From DONOTREPLY at icculus.org Tue Mar 15 06:58:08 2005 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 15 Mar 2005 06:58:08 -0500 Subject: r101 - trunk/tools/lvl_tools Message-ID: <20050315115808.22325.qmail@icculus.org> Author: jonas Date: 2005-03-15 06:58:08 -0500 (Tue, 15 Mar 2005) New Revision: 101 Modified: trunk/tools/lvl_tools/lvlextract.c Log: use xpm output for the moment as default as it's much faster... Modified: trunk/tools/lvl_tools/lvlextract.c =================================================================== --- trunk/tools/lvl_tools/lvlextract.c 2005-03-14 23:44:55 UTC (rev 100) +++ trunk/tools/lvl_tools/lvlextract.c 2005-03-15 11:58:08 UTC (rev 101) @@ -395,7 +395,7 @@ if (!strncmp(off_ptr,entry_id,4)) { counter++; /* write_pgm, write_png, write_xpm, write_png_xpm */ - last_ptr=write_png_xpm(off_ptr,counter); + last_ptr=write_xpm(off_ptr,counter); } else { last_ptr=off_ptr+1; } From DONOTREPLY at icculus.org Tue Mar 15 08:40:58 2005 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 15 Mar 2005 08:40:58 -0500 Subject: r102 - trunk/tools/lvl_tools Message-ID: <20050315134058.30009.qmail@icculus.org> Author: jonas Date: 2005-03-15 08:40:58 -0500 (Tue, 15 Mar 2005) New Revision: 102 Modified: trunk/tools/lvl_tools/lvlextract.c Log: more ANSI like, write out unknown content as %08d.bin, where d is the number of the corresponding image file, following the unknown content. Modified: trunk/tools/lvl_tools/lvlextract.c =================================================================== --- trunk/tools/lvl_tools/lvlextract.c 2005-03-15 11:58:08 UTC (rev 101) +++ trunk/tools/lvl_tools/lvlextract.c 2005-03-15 13:40:58 UTC (rev 102) @@ -322,43 +322,50 @@ int main(int argc, char *argv[]) { - int fd_in; -/* FILE* append_file; */ - char buf[16]; + FILE* lvl_file; + FILE* unknown_file; + char buf[100]; char *data; + /* + * Temporary variable to indicate the last offset to start searching from: + * Either after (1+) an invalid "T" or after the image of a valid "TRPS" + */ char *last_ptr; + /* Either index position (start) or the last known position after an image */ + char *save_ptr; + /* Iterates through all offsets at a "T" */ char *off_ptr; struct stat sb; int data_size; int counter=0; int unknown=0; - char entry_id[]="TRPS"; + const char entry_id[]="TRPS"; if (argc < 2) { printf("Usage: %s input.lvl [destination]\n", argv[0]); exit(1); } - fd_in = open(argv[1], O_RDONLY); + lvl_file = fopen(argv[1],"r"); - if (fd_in < 0) { - perror("error opening file"); + if (lvl_file == NULL) { + perror("Error opening file"); exit(1); } - read(fd_in, buf, 12); + fread(buf,1,12,lvl_file); if ((buf[0] != 'D') && (buf[1] != 'A') && (buf[2] != 'T') && (buf[3] != 'A')) { printf("Invalid file\n"); - close(fd_in); + fclose(lvl_file); exit(1); } if (argc > 2) { mkdir(argv[2], 0777); chdir(argv[2]); - printf("directory: %s\n", argv[2]); + printf("Directory: %s\n", argv[2]); } else { /* copy the filename */ if (strrchr(argv[1], '/')) strncpy(buf, strrchr(argv[1], '/')+1, 16); @@ -373,29 +380,38 @@ mkdir(buf, 0777); chdir(buf); - printf("directory: %s\n", buf); + printf("Directory: %s\n", buf); } /* get file size */ - fstat(fd_in, &sb); + fstat(fileno(lvl_file), &sb); data_size = sb.st_size; - /* File for unknown content */ -/* append_file = fopen("unknown.bin", "a"); */ - /* map the entire file into process memory space */ - data = mmap(NULL, data_size, PROT_READ, MAP_PRIVATE, fd_in, 0); + data = mmap(NULL, data_size, PROT_READ, MAP_PRIVATE, fileno(lvl_file), 0); last_ptr=data; + save_ptr=data; while (off_ptr=memchr(last_ptr,'T',(data_size-(last_ptr-data)))) { -/* - if (!strncmp(off_ptr,entry_id,4)) fprintf(append_file,"****************"); - fwrite(last_ptr,1,(off_ptr-last_ptr),append_file); -*/ unknown+=(off_ptr-last_ptr); if (!strncmp(off_ptr,entry_id,4)) { counter++; - /* write_pgm, write_png, write_xpm, write_png_xpm */ + /* + * Write unknown content (up to this image position (off_ptr)) to a file. + * If the file size would be 0, skip it. + */ + if ((off_ptr-save_ptr > 0)) { + snprintf(buf, 100, "%08d.bin", counter); + unknown_file = fopen(buf, "wb"); + fwrite(save_ptr,1,(off_ptr-save_ptr),unknown_file); + fclose(unknown_file); + } + + /* + * Write the image file: write_pgm, write_png, write_xpm or write_png_xpm + * and update the pointers + */ last_ptr=write_xpm(off_ptr,counter); + save_ptr=last_ptr; } else { last_ptr=off_ptr+1; } @@ -404,8 +420,7 @@ printf("Contains %d extracted images, unknown content: %d bytes\n",counter,unknown); munmap(data, data_size); - close(fd_in); -/* fclose(append_file); */ + fclose(lvl_file); return 0; } From DONOTREPLY at icculus.org Mon Mar 14 18:44:55 2005 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 14 Mar 2005 18:44:55 -0500 Subject: r100 - in trunk/src: . objects Message-ID: <20050314234455.7611.qmail@icculus.org> Author: jonas Date: 2005-03-14 18:44:55 -0500 (Mon, 14 Mar 2005) New Revision: 100 Added: trunk/src/SDL_rotozoom.cpp trunk/src/SDL_rotozoom.h Modified: trunk/src/Makefile trunk/src/imgcache.cpp trunk/src/imgcache.h trunk/src/objects/Makefile Log: Support preceeding image scaling, using the rotozoomer (from SDL_gfx) from A. Schiffler. Syntax: When loading a new image into cache, one can add an aditional parameter double scale_factor to specify the scaling factor. Modified: trunk/src/Makefile =================================================================== --- trunk/src/Makefile 2005-03-14 15:51:04 UTC (rev 99) +++ trunk/src/Makefile 2005-03-14 23:44:55 UTC (rev 100) @@ -1,7 +1,7 @@ CXX = g++ CXX_FLAGS = -W -Wall -ansi -pedantic CXX_DEBUG = -g #-fno-inline -CXX_OPT = -O2 -march=pentium4 -ffast-math +CXX_OPT = #-O2 -march=pentium4 -ffast-math CXX_GAME = -DSDL_MIXER -DSDL_IMAGE -DALPHA -I ./ SDL = `sdl-config --cflags` SDL_LINK = `sdl-config --libs` -lSDL_mixer -lSDL_image -ldl -rdynamic @@ -9,7 +9,7 @@ OBJS = common.o gfxeng.o input.o font.o lost_penguins.o scenario.o\ objects_common.o sfxeng.o players_common.o monsters_common.o\ characters_common.o objectpools.o weapons.o events.o imgcache.o\ - sndcache.o physics.o animation.o menu.o + sndcache.o physics.o animation.o menu.o SDL_rotozoom.o PLUGS = objects.a BIN = ../lost_penguins Added: trunk/src/SDL_rotozoom.cpp =================================================================== --- trunk/src/SDL_rotozoom.cpp 2005-03-14 15:51:04 UTC (rev 99) +++ trunk/src/SDL_rotozoom.cpp 2005-03-14 23:44:55 UTC (rev 100) @@ -0,0 +1,945 @@ +/* + * SDL_rotozoom.c - rotozoomer for 32bit or 8bit surfaces + * + * LGPL (c) A. Schiffler + */ + +#include +#include +#include +#include +#include "SDL_rotozoom.h" + +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) + +/* + * 32bit Zoomer with optional anti-aliasing by bilinear interpolation. + * + * Zoomes 32bit RGBA/ABGR 'src' surface to 'dst' surface. + */ + +int zoomSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int flipx, int flipy, int smooth) { + int x, y, sx, sy, *sax, *say, *csax, *csay, csx, csy, ex, ey, t1, t2, sstep; + tColorRGBA *c00, *c01, *c10, *c11; + tColorRGBA *sp, *csp, *dp; + int dgap; + + /* + * Variable setup + */ + if (smooth) { + /* + * For interpolation: assume source dimension is one pixel + */ + /* + * smaller to avoid overflow on right and bottom edge. + */ + sx = (int) (65536.0 * (float) (src->w - 1) / (float) dst->w); + sy = (int) (65536.0 * (float) (src->h - 1) / (float) dst->h); + } else { + sx = (int) (65536.0 * (float) src->w / (float) dst->w); + sy = (int) (65536.0 * (float) src->h / (float) dst->h); + } + + /* + * Allocate memory for row increments + */ + if ((sax = (int *) malloc((dst->w + 1) * sizeof(Uint32))) == NULL) { + return (-1); + } + if ((say = (int *) malloc((dst->h + 1) * sizeof(Uint32))) == NULL) { + free(sax); + return (-1); + } + + /* + * Precalculate row increments + */ + sp = csp = (tColorRGBA *) src->pixels; + dp = (tColorRGBA *) dst->pixels; + + if (flipx) csp += (src->w-1); + if (flipy) csp = (tColorRGBA*)( (Uint8*)csp + src->pitch*(src->h-1) ); + + csx = 0; + csax = sax; + for (x = 0; x <= dst->w; x++) { + *csax = csx; + csax++; + csx &= 0xffff; + csx += sx; + } + csy = 0; + csay = say; + for (y = 0; y <= dst->h; y++) { + *csay = csy; + csay++; + csy &= 0xffff; + csy += sy; + } + + dgap = dst->pitch - dst->w * 4; + + /* + * Switch between interpolating and non-interpolating code + */ + if (smooth) { + + /* + * Interpolating Zoom + */ + + /* + * Scan destination + */ + csay = say; + for (y = 0; y < dst->h; y++) { + /* + * Setup color source pointers + */ + c00 = csp; + c01 = csp; + c01++; + c10 = (tColorRGBA *) ((Uint8 *) csp + src->pitch); + c11 = c10; + c11++; + csax = sax; + for (x = 0; x < dst->w; x++) { + + /* + * Interpolate colors + */ + ex = (*csax & 0xffff); + ey = (*csay & 0xffff); + t1 = ((((c01->r - c00->r) * ex) >> 16) + c00->r) & 0xff; + t2 = ((((c11->r - c10->r) * ex) >> 16) + c10->r) & 0xff; + dp->r = (((t2 - t1) * ey) >> 16) + t1; + t1 = ((((c01->g - c00->g) * ex) >> 16) + c00->g) & 0xff; + t2 = ((((c11->g - c10->g) * ex) >> 16) + c10->g) & 0xff; + dp->g = (((t2 - t1) * ey) >> 16) + t1; + t1 = ((((c01->b - c00->b) * ex) >> 16) + c00->b) & 0xff; + t2 = ((((c11->b - c10->b) * ex) >> 16) + c10->b) & 0xff; + dp->b = (((t2 - t1) * ey) >> 16) + t1; + t1 = ((((c01->a - c00->a) * ex) >> 16) + c00->a) & 0xff; + t2 = ((((c11->a - c10->a) * ex) >> 16) + c10->a) & 0xff; + dp->a = (((t2 - t1) * ey) >> 16) + t1; + + /* + * Advance source pointers + */ + csax++; + sstep = (*csax >> 16); + c00 += sstep; + c01 += sstep; + c10 += sstep; + c11 += sstep; + /* + * Advance destination pointer + */ + dp++; + } + /* + * Advance source pointer + */ + csay++; + csp = (tColorRGBA *) ((Uint8 *) csp + (*csay >> 16) * src->pitch); + /* + * Advance destination pointers + */ + dp = (tColorRGBA *) ((Uint8 *) dp + dgap); + } + + } else { + + /* + * Non-Interpolating Zoom + */ + + csay = say; + for (y = 0; y < dst->h; y++) { + sp = csp; + csax = sax; + for (x = 0; x < dst->w; x++) { + /* + * Draw + */ + *dp = *sp; + /* + * Advance source pointers + */ + csax++; + sstep = (*csax >> 16); + if (flipx) sstep = -sstep; + sp += sstep; + /* + * Advance destination pointer + */ + dp++; + } + /* + * Advance source pointer + */ + csay++; + sstep = (*csay >> 16) * src->pitch; + if (flipy) sstep = -sstep; + csp = (tColorRGBA *) ((Uint8 *) csp + sstep); + + /* + * Advance destination pointers + */ + dp = (tColorRGBA *) ((Uint8 *) dp + dgap); + } + + } + + /* + * Remove temp arrays + */ + free(sax); + free(say); + + return (0); +} + +/* + * 8bit Zoomer without smoothing. + * + * Zoomes 8bit palette/Y 'src' surface to 'dst' surface. + */ + +int zoomSurfaceY(SDL_Surface * src, SDL_Surface * dst, int flipx, int flipy) { + Uint32 sx, sy, *sax, *say, *csax, *csay, csx, csy; + int x,y; + Uint8 *sp, *dp, *csp; + int dgap; + + /* + * Variable setup + */ + sx = (Uint32) (65536.0 * (float) src->w / (float) dst->w); + sy = (Uint32) (65536.0 * (float) src->h / (float) dst->h); + + /* + * Allocate memory for row increments + */ + if ((sax = (Uint32 *) malloc(dst->w * sizeof(Uint32))) == NULL) { + return (-1); + } + if ((say = (Uint32 *) malloc(dst->h * sizeof(Uint32))) == NULL) { + if (sax != NULL) { + free(sax); + } + return (-1); + } + + /* + * Precalculate row increments + */ + csx = 0; + csax = sax; + for (x = 0; x < dst->w; x++) { + csx += sx; + *csax = (csx >> 16); + csx &= 0xffff; + csax++; + } + csy = 0; + csay = say; + for (y = 0; y < dst->h; y++) { + csy += sy; + *csay = (csy >> 16); + csy &= 0xffff; + csay++; + } + + csx = 0; + csax = sax; + for (x = 0; x < dst->w; x++) { + csx += (*csax); + csax++; + } + csy = 0; + csay = say; + for (y = 0; y < dst->h; y++) { + csy += (*csay); + csay++; + } + + /* + * Pointer setup + */ + sp = csp = (Uint8 *) src->pixels; + dp = (Uint8 *) dst->pixels; + dgap = dst->pitch - dst->w; + + /* + * Draw + */ + csay = say; + for (y = 0; y < dst->h; y++) { + csax = sax; + sp = csp; + for (x = 0; x < dst->w; x++) { + /* + * Draw + */ + *dp = *sp; + /* + * Advance source pointers + */ + sp += (*csax); + csax++; + /* + * Advance destination pointer + */ + dp++; + } + /* + * Advance source pointer (for row) + */ + csp += ((*csay) * src->pitch); + csay++; + /* + * Advance destination pointers + */ + dp += dgap; + } + + /* + * Remove temp arrays + */ + free(sax); + free(say); + + return (0); +} + +/* + * 32bit Rotozoomer with optional anti-aliasing by bilinear interpolation. + * + * Rotates and zoomes 32bit RGBA/ABGR 'src' surface to 'dst' surface. + * + */ + +void transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int flipx, int flipy, int smooth) { + int x, y, t1, t2, dx, dy, xd, yd, sdx, sdy, ax, ay, ex, ey, sw, sh; + tColorRGBA c00, c01, c10, c11; + tColorRGBA *pc, *sp; + int gap; + + /* + * Variable setup + */ + xd = ((src->w - dst->w) << 15); + yd = ((src->h - dst->h) << 15); + ax = (cx << 16) - (icos * cx); + ay = (cy << 16) - (isin * cx); + sw = src->w - 1; + sh = src->h - 1; + pc = (tColorRGBA*)dst->pixels; + gap = dst->pitch - dst->w * 4; + + /* + * Switch between interpolating and non-interpolating code + */ + if (smooth) { + for (y = 0; y < dst->h; y++) { + dy = cy - y; + sdx = (ax + (isin * dy)) + xd; + sdy = (ay - (icos * dy)) + yd; + for (x = 0; x < dst->w; x++) { + dx = (sdx >> 16); + dy = (sdy >> 16); + if ((dx >= -1) && (dy >= -1) && (dx < src->w) && (dy < src->h)) { + if ((dx >= 0) && (dy >= 0) && (dx < sw) && (dy < sh)) { + sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy); + sp += dx; + c00 = *sp; + sp += 1; + c01 = *sp; + sp = (tColorRGBA *) ((Uint8 *) sp + src->pitch); + sp -= 1; + c10 = *sp; + sp += 1; + c11 = *sp; + } else if ((dx == sw) && (dy == sh)) { + sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy); + sp += dx; + c00 = *sp; + c01 = *sp; + c10 = *sp; + c11 = *sp; + } else if ((dx == -1) && (dy == -1)) { + sp = (tColorRGBA *) (src->pixels); + c00 = *sp; + c01 = *sp; + c10 = *sp; + c11 = *sp; + } else if ((dx == -1) && (dy == sh)) { + sp = (tColorRGBA *) (src->pixels); + sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy); + c00 = *sp; + c01 = *sp; + c10 = *sp; + c11 = *sp; + } else if ((dx == sw) && (dy == -1)) { + sp = (tColorRGBA *) (src->pixels); + sp += dx; + c00 = *sp; + c01 = *sp; + c10 = *sp; + c11 = *sp; + } else if (dx == -1) { + sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy); + c00 = *sp; + c01 = *sp; + c10 = *sp; + sp = (tColorRGBA *) ((Uint8 *) sp + src->pitch); + c11 = *sp; + } else if (dy == -1) { + sp = (tColorRGBA *) (src->pixels); + sp += dx; + c00 = *sp; + c01 = *sp; + c10 = *sp; + sp += 1; + c11 = *sp; + } else if (dx == sw) { + sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy); + sp += dx; + c00 = *sp; + c01 = *sp; + sp = (tColorRGBA *) ((Uint8 *) sp + src->pitch); + c10 = *sp; + c11 = *sp; + } else if (dy == sh) { + sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy); + sp += dx; + c00 = *sp; + sp += 1; + c01 = *sp; + c10 = *sp; + c11 = *sp; + } + /* + * Interpolate colors + */ + ex = (sdx & 0xffff); + ey = (sdy & 0xffff); + t1 = ((((c01.r - c00.r) * ex) >> 16) + c00.r) & 0xff; + t2 = ((((c11.r - c10.r) * ex) >> 16) + c10.r) & 0xff; + pc->r = (((t2 - t1) * ey) >> 16) + t1; + t1 = ((((c01.g - c00.g) * ex) >> 16) + c00.g) & 0xff; + t2 = ((((c11.g - c10.g) * ex) >> 16) + c10.g) & 0xff; + pc->g = (((t2 - t1) * ey) >> 16) + t1; + t1 = ((((c01.b - c00.b) * ex) >> 16) + c00.b) & 0xff; + t2 = ((((c11.b - c10.b) * ex) >> 16) + c10.b) & 0xff; + pc->b = (((t2 - t1) * ey) >> 16) + t1; + t1 = ((((c01.a - c00.a) * ex) >> 16) + c00.a) & 0xff; + t2 = ((((c11.a - c10.a) * ex) >> 16) + c10.a) & 0xff; + pc->a = (((t2 - t1) * ey) >> 16) + t1; + } + sdx += icos; + sdy += isin; + pc++; + } + pc = (tColorRGBA *) ((Uint8 *) pc + gap); + } + } else { + for (y = 0; y < dst->h; y++) { + dy = cy - y; + sdx = (ax + (isin * dy)) + xd; + sdy = (ay - (icos * dy)) + yd; + for (x = 0; x < dst->w; x++) { + dx = (short) (sdx >> 16); + dy = (short) (sdy >> 16); + if (flipx) dx = (src->w-1)-dx; + if (flipy) dy = (src->h-1)-dy; + if ((dx >= 0) && (dy >= 0) && (dx < src->w) && (dy < src->h)) { + sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy); + sp += dx; + *pc = *sp; + } + sdx += icos; + sdy += isin; + pc++; + } + pc = (tColorRGBA *) ((Uint8 *) pc + gap); + } + } +} + +/* + * 8bit Rotozoomer without smoothing + * + * Rotates and zoomes 8bit palette/Y 'src' surface to 'dst' surface. + */ + +void transformSurfaceY(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos) { + int x, y, dx, dy, xd, yd, sdx, sdy, ax, ay, sw, sh; + tColorY *pc, *sp; + int gap; + + /* + * Variable setup + */ + xd = ((src->w - dst->w) << 15); + yd = ((src->h - dst->h) << 15); + ax = (cx << 16) - (icos * cx); + ay = (cy << 16) - (isin * cx); + sw = src->w - 1; + sh = src->h - 1; + pc = (tColorY*)dst->pixels; + gap = dst->pitch - dst->w; + /* + * Clear surface to colorkey + */ + memset(pc, (unsigned char) (src->format->colorkey & 0xff), dst->pitch * dst->h); + /* + * Iterate through destination surface + */ + for (y = 0; y < dst->h; y++) { + dy = cy - y; + sdx = (ax + (isin * dy)) + xd; + sdy = (ay - (icos * dy)) + yd; + for (x = 0; x < dst->w; x++) { + dx = (short) (sdx >> 16); + dy = (short) (sdy >> 16); + if ((dx >= 0) && (dy >= 0) && (dx < src->w) && (dy < src->h)) { + sp = (tColorY *) (src->pixels); + sp += (src->pitch * dy + dx); + *pc = *sp; + } + sdx += icos; + sdy += isin; + pc++; + } + pc += gap; + } +} + +/* + * rotozoomSurface() + * + * Rotates and zoomes a 32bit or 8bit 'src' surface to newly created 'dst' surface. + * 'angle' is the rotation in degrees. 'zoom' a scaling factor. If 'smooth' is 1 + * then the destination 32bit surface is anti-aliased. If the surface is not 8bit + * or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly. + */ + +#define VALUE_LIMIT 0.001 + + +/* Local rotozoom-size function with trig result return */ + +void rotozoomSurfaceSizeTrig(int width, int height, double angle, double zoomx, double zoomy, int *dstwidth, int *dstheight, double *canglezoom, double *sanglezoom) { + double x, y, cx, cy, sx, sy; + double radangle; + int dstwidthhalf, dstheighthalf; + + /* + * Determine destination width and height by rotating a centered source box + */ + radangle = angle * (M_PI / 180.0); + *sanglezoom = sin(radangle); + *canglezoom = cos(radangle); + *sanglezoom *= zoomx; + *canglezoom *= zoomx; + x = width / 2; + y = height / 2; + cx = *canglezoom * x; + cy = *canglezoom * y; + sx = *sanglezoom * x; + sy = *sanglezoom * y; + dstwidthhalf = MAX((int) + ceil(MAX(MAX(MAX(fabs(cx + sy), fabs(cx - sy)), fabs(-cx + sy)), fabs(-cx - sy))), 1); + dstheighthalf = MAX((int) + ceil(MAX(MAX(MAX(fabs(sx + cy), fabs(sx - cy)), fabs(-sx + cy)), fabs(-sx - cy))), 1); + *dstwidth = 2 * dstwidthhalf; + *dstheight = 2 * dstheighthalf; +} + + +/* Publically available rotozoom-size function */ + +void rotozoomSurfaceSizeXY(int width, int height, double angle, double zoomx, double zoomy, int *dstwidth, int *dstheight) { + double dummy_sanglezoom, dummy_canglezoom; + + rotozoomSurfaceSizeTrig(width, height, angle, zoomx, zoomy, dstwidth, dstheight, &dummy_sanglezoom, &dummy_canglezoom); +} + +/* Publically available rotozoom-size function */ + +void rotozoomSurfaceSize(int width, int height, double angle, double zoom, int *dstwidth, int *dstheight) { + double dummy_sanglezoom, dummy_canglezoom; + + rotozoomSurfaceSizeTrig(width, height, angle, zoom, zoom, dstwidth, dstheight, &dummy_sanglezoom, &dummy_canglezoom); +} + +/* Publically available rotozoom function */ + +SDL_Surface *rotozoomSurface(SDL_Surface * src, double angle, double zoom, int smooth) { + return rotozoomSurfaceXY(src, angle, zoom, zoom, smooth); +} + +/* Publically available rotozoom function */ + +SDL_Surface *rotozoomSurfaceXY(SDL_Surface * src, double angle, double zoomx, double zoomy, int smooth) { + SDL_Surface *rz_src; + SDL_Surface *rz_dst; + double zoominv; + double sanglezoom, canglezoom, sanglezoominv, canglezoominv; + int dstwidthhalf, dstwidth, dstheighthalf, dstheight; + int is32bit; + int i, src_converted; + int flipx,flipy; + + /* + * Sanity check + */ + if (src == NULL) + return (NULL); + + /* + * Determine if source surface is 32bit or 8bit + */ + is32bit = (src->format->BitsPerPixel == 32); + if ((is32bit) || (src->format->BitsPerPixel == 8)) { + /* + * Use source surface 'as is' + */ + rz_src = src; + src_converted = 0; + } else { + /* + * New source surface is 32bit with a defined RGBA ordering + */ + rz_src = + SDL_CreateRGBSurface(SDL_SWSURFACE, src->w, src->h, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000); + SDL_BlitSurface(src, NULL, rz_src, NULL); + src_converted = 1; + is32bit = 1; + } + + /* + * Sanity check zoom factor + */ + flipx = (zoomx<0); + if (flipx) zoomx=-zoomx; + flipy = (zoomy<0); + if (flipy) zoomy=-zoomy; + if (zoomx < VALUE_LIMIT) zoomx = VALUE_LIMIT; + if (zoomy < VALUE_LIMIT) zoomy = VALUE_LIMIT; + zoominv = 65536.0 / (zoomx * zoomx); + + /* + * Check if we have a rotozoom or just a zoom + */ + if (fabs(angle) > VALUE_LIMIT) { + + /* + * Angle!=0: full rotozoom + */ + /* + * ----------------------- + */ + + /* Determine target size */ + rotozoomSurfaceSizeTrig(rz_src->w, rz_src->h, angle, zoomx, zoomy, &dstwidth, &dstheight, &canglezoom, &sanglezoom); + + /* + * Calculate target factors from sin/cos and zoom + */ + sanglezoominv = sanglezoom; + canglezoominv = canglezoom; + sanglezoominv *= zoominv; + canglezoominv *= zoominv; + + /* Calculate half size */ + dstwidthhalf = dstwidth / 2; + dstheighthalf = dstheight / 2; + + /* + * Alloc space to completely contain the rotated surface + */ + rz_dst = NULL; + if (is32bit) { + /* + * Target surface is 32bit with source RGBA/ABGR ordering + */ + rz_dst = + SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 32, + rz_src->format->Rmask, rz_src->format->Gmask, + rz_src->format->Bmask, rz_src->format->Amask); + } else { + /* + * Target surface is 8bit + */ + rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 8, 0, 0, 0, 0); + } + + /* + * Lock source surface + */ + SDL_LockSurface(rz_src); + /* + * Check which kind of surface we have + */ + if (is32bit) { + /* + * Call the 32bit transformation routine to do the rotation (using alpha) + */ + transformSurfaceRGBA(rz_src, rz_dst, dstwidthhalf, dstheighthalf, + (int) (sanglezoominv), (int) (canglezoominv), + flipx, flipy, + smooth); + /* + * Turn on source-alpha support + */ + SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255); + } else { + /* + * Copy palette and colorkey info + */ + for (i = 0; i < rz_src->format->palette->ncolors; i++) { + rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i]; + } + rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors; + /* + * Call the 8bit transformation routine to do the rotation + */ + transformSurfaceY(rz_src, rz_dst, dstwidthhalf, dstheighthalf, + (int) (sanglezoominv), (int) (canglezoominv)); + SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, rz_src->format->colorkey); + } + /* + * Unlock source surface + */ + SDL_UnlockSurface(rz_src); + + } else { + + /* + * Angle=0: Just a zoom + */ + /* + * -------------------- + */ + + /* + * Calculate target size + */ + zoomSurfaceSize(rz_src->w, rz_src->h, zoomx, zoomy, &dstwidth, &dstheight); + + /* + * Alloc space to completely contain the zoomed surface + */ + rz_dst = NULL; + if (is32bit) { + /* + * Target surface is 32bit with source RGBA/ABGR ordering + */ + rz_dst = + SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 32, + rz_src->format->Rmask, rz_src->format->Gmask, + rz_src->format->Bmask, rz_src->format->Amask); + } else { + /* + * Target surface is 8bit + */ + rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 8, 0, 0, 0, 0); + } + + /* + * Lock source surface + */ + SDL_LockSurface(rz_src); + /* + * Check which kind of surface we have + */ + if (is32bit) { + /* + * Call the 32bit transformation routine to do the zooming (using alpha) + */ + zoomSurfaceRGBA(rz_src, rz_dst, flipx, flipy, smooth); + /* + * Turn on source-alpha support + */ + SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255); + } else { + /* + * Copy palette and colorkey info + */ + for (i = 0; i < rz_src->format->palette->ncolors; i++) { + rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i]; + } + rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors; + /* + * Call the 8bit transformation routine to do the zooming + */ + zoomSurfaceY(rz_src, rz_dst, flipx, flipy); + SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, rz_src->format->colorkey); + } + /* + * Unlock source surface + */ + SDL_UnlockSurface(rz_src); + } + + /* + * Cleanup temp surface + */ + if (src_converted) { + SDL_FreeSurface(rz_src); + } + + /* + * Return destination surface + */ + return (rz_dst); +} + +/* + * zoomSurface() + * + * Zoomes a 32bit or 8bit 'src' surface to newly created 'dst' surface. + * 'zoomx' and 'zoomy' are scaling factors for width and height. If 'smooth' is 1 + * then the destination 32bit surface is anti-aliased. If the surface is not 8bit + * or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly. + */ + +#define VALUE_LIMIT 0.001 + +void zoomSurfaceSize(int width, int height, double zoomx, double zoomy, int *dstwidth, int *dstheight) { + /* + * Sanity check zoom factors + */ + if (zoomx < VALUE_LIMIT) { + zoomx = VALUE_LIMIT; + } + if (zoomy < VALUE_LIMIT) { + zoomy = VALUE_LIMIT; + } + + /* + * Calculate target size + */ + *dstwidth = (int) ((double) width * zoomx); + *dstheight = (int) ((double) height * zoomy); + if (*dstwidth < 1) { + *dstwidth = 1; + } + if (*dstheight < 1) { + *dstheight = 1; + } +} + +SDL_Surface *zoomSurface(SDL_Surface * src, double zoomx, double zoomy, int smooth) { + SDL_Surface *rz_src; + SDL_Surface *rz_dst; + int dstwidth, dstheight; + int is32bit; + int i, src_converted; + int flipx, flipy; + + /* + * Sanity check + */ + if (src == NULL) + return (NULL); + + /* + * Determine if source surface is 32bit or 8bit + */ + is32bit = (src->format->BitsPerPixel == 32); + if ((is32bit) || (src->format->BitsPerPixel == 8)) { + /* + * Use source surface 'as is' + */ + rz_src = src; + src_converted = 0; + } else { + /* + * New source surface is 32bit with a defined RGBA ordering + */ + rz_src = + SDL_CreateRGBSurface(SDL_SWSURFACE, src->w, src->h, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000); + SDL_BlitSurface(src, NULL, rz_src, NULL); + src_converted = 1; + is32bit = 1; + } + + flipx = (zoomx<0); + if (flipx) zoomx = -zoomx; + flipy = (zoomy<0); + if (flipy) zoomy = -zoomy; + + /* Get size if target */ + zoomSurfaceSize(rz_src->w, rz_src->h, zoomx, zoomy, &dstwidth, &dstheight); + + /* + * Alloc space to completely contain the zoomed surface + */ + rz_dst = NULL; + if (is32bit) { + /* + * Target surface is 32bit with source RGBA/ABGR ordering + */ + rz_dst = + SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 32, + rz_src->format->Rmask, rz_src->format->Gmask, + rz_src->format->Bmask, rz_src->format->Amask); + } else { + /* + * Target surface is 8bit + */ + rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 8, 0, 0, 0, 0); + } + + /* + * Lock source surface + */ + SDL_LockSurface(rz_src); + /* + * Check which kind of surface we have + */ + if (is32bit) { + /* + * Call the 32bit transformation routine to do the zooming (using alpha) + */ + zoomSurfaceRGBA(rz_src, rz_dst, flipx, flipy, smooth); + /* + * Turn on source-alpha support + */ + SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255); + } else { + /* + * Copy palette and colorkey info + */ + for (i = 0; i < rz_src->format->palette->ncolors; i++) { + rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i]; + } + rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors; + /* + * Call the 8bit transformation routine to do the zooming + */ + zoomSurfaceY(rz_src, rz_dst, flipx, flipy); + SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, rz_src->format->colorkey); + } + /* + * Unlock source surface + */ + SDL_UnlockSurface(rz_src); + + /* + * Cleanup temp surface + */ + if (src_converted) { + SDL_FreeSurface(rz_src); + } + + /* + * Return destination surface + */ + return (rz_dst); +} Added: trunk/src/SDL_rotozoom.h =================================================================== --- trunk/src/SDL_rotozoom.h 2005-03-14 15:51:04 UTC (rev 99) +++ trunk/src/SDL_rotozoom.h 2005-03-14 23:44:55 UTC (rev 100) @@ -0,0 +1,62 @@ +/* + * SDL_rotozoom - rotozoomer + * + * LGPL (c) A. Schiffler + * + */ + +#ifndef _SDL_rotozoom_h +#define _SDL_rotozoom_h + +#ifndef M_PI +#define M_PI 3.141592654 +#endif + +#define SMOOTHING_OFF 0 +#define SMOOTHING_ON 1 + +typedef struct tColorRGBA { + Uint8 r; + Uint8 g; + Uint8 b; + Uint8 a; +} tColorRGBA; + +typedef struct tColorY { + Uint8 y; +} tColorY; + + +/* + * rotozoomSurface() + * + * Rotates and zoomes a 32bit or 8bit 'src' surface to newly created 'dst' surface. + * 'angle' is the rotation in degrees. 'zoom' a scaling factor. If 'smooth' is 1 + * then the destination 32bit surface is anti-aliased. If the surface is not 8bit + * or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly. + */ + +SDL_Surface *rotozoomSurface(SDL_Surface * src, double angle, double zoom, int smooth); +SDL_Surface *rotozoomSurfaceXY (SDL_Surface * src, double angle, double zoomx, double zoomy, int smooth); + +/* Returns the size of the target surface for a rotozoomSurface() call */ + +void rotozoomSurfaceSize(int width, int height, double angle, double zoom, int *dstwidth, int *dstheight); +void rotozoomSurfaceSizeXY(int width, int height, double angle, double zoomx, double zoomy, int *dstwidth, int *dstheight); + +/* + * zoomSurface() + * + * Zoomes a 32bit or 8bit 'src' surface to newly created 'dst' surface. + * 'zoomx' and 'zoomy' are scaling factors for width and height. If 'smooth' is 1 + * then the destination 32bit surface is anti-aliased. If the surface is not 8bit + * or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly. + */ + +SDL_Surface *zoomSurface(SDL_Surface * src, double zoomx, double zoomy, int smooth); + +/* Returns the size of the target surface for a zoomSurface() call */ + +void zoomSurfaceSize(int width, int height, double zoomx, double zoomy, int *dstwidth, int *dstheight); + +#endif Modified: trunk/src/imgcache.cpp =================================================================== --- trunk/src/imgcache.cpp 2005-03-14 15:51:04 UTC (rev 99) +++ trunk/src/imgcache.cpp 2005-03-14 23:44:55 UTC (rev 100) @@ -1,4 +1,5 @@ #include "common.h" +#include "SDL_rotozoom.h" #include "imgcache.h" @@ -6,23 +7,29 @@ not_found="no_file.bmp"; } ImageCache::~ImageCache() { - map::iterator imgit=imgcache.begin(); + map, SDL_Surface*>::iterator imgit=imgcache.begin(); while (imgit != imgcache.end()) { SDL_FreeSurface((*imgit).second); imgcache.erase(imgit++); } } -SDL_Surface* ImageCache::loadImage(string imagename) { +//TODO: maybe replace double scale_factor by string scale_format or sthg like that +SDL_Surface* ImageCache::loadImage(string imagename, double scale_factor) { //default is not_found - if (imagename=="") imagename=not_found; - map::iterator imgit=imgcache.find(imagename); + if (imagename=="") { + imagename=not_found; + scale_factor=1; + } + + map, SDL_Surface*>::iterator imgit=imgcache.find(make_pair(imagename,scale_factor)); - //load new image + // Image is not yet cached if (imgit==imgcache.end()) { string loadfile=config.datadir+imagename; SDL_Surface* tmpimg=NULL; SDL_Surface* returnimg=NULL; + // Loading #ifdef SDL_IMAGE if ((tmpimg=IMG_Load(loadfile.c_str())) == NULL) { #else @@ -36,23 +43,45 @@ } else { return loadImage(not_found); } + // Preprocessing } else { + // About ColorKeys: I'm not sure anymore what is necessary and what not, as some stuff is now + // also done in SDL_rotozoom.cpp, at least it seems to work this way... + // Image's colorkey have to be set before (if unset) as the SCALING changes the color values + #ifdef ALPHA + if (!(tmpimg->flags & (SDL_SRCCOLORKEY|SDL_SRCALPHA))) { + #else + if (!(tmpimg->flags & (SDL_SRCCOLORKEY))) { + #endif + SDL_SetColorKey(tmpimg, SDL_SRCCOLORKEY|SDL_RLEACCEL, SDL_MapRGB(tmpimg->format,255,0,255)); + } + // SCALING + if (scale_factor!=1) tmpimg=scaleImage(tmpimg,scale_factor); + // Image's colorkey if (tmpimg->flags & SDL_SRCCOLORKEY) { SDL_SetColorKey(tmpimg, SDL_SRCCOLORKEY|SDL_RLEACCEL, tmpimg->format->colorkey); returnimg=SDL_DisplayFormat(tmpimg); #ifdef ALPHA + // Alpha } else if (tmpimg->flags & SDL_SRCALPHA) { SDL_SetAlpha(tmpimg, SDL_SRCALPHA|SDL_RLEACCEL, tmpimg->format->alpha); returnimg=SDL_DisplayFormatAlpha(tmpimg); #endif + // Our own colorkey (0xff00ff) } else { SDL_SetColorKey(tmpimg, SDL_SRCCOLORKEY|SDL_RLEACCEL, SDL_MapRGB(tmpimg->format,255,0,255)); returnimg=SDL_DisplayFormat(tmpimg); } SDL_FreeSurface(tmpimg); } - imgcache.insert(make_pair(imagename,returnimg)); + imgcache.insert(make_pair(make_pair(imagename,scale_factor),returnimg)); return returnimg; - //already there + // Return the existing Image in cache... } else return (*imgit).second; } + +inline SDL_Surface* ImageCache::scaleImage(SDL_Surface* original_image, double scale_factor) { + SDL_Surface* scaled_image=zoomSurface(original_image, scale_factor, scale_factor, 1); + SDL_FreeSurface(original_image); + return scaled_image; +} Modified: trunk/src/imgcache.h =================================================================== --- trunk/src/imgcache.h 2005-03-14 15:51:04 UTC (rev 99) +++ trunk/src/imgcache.h 2005-03-14 23:44:55 UTC (rev 100) @@ -13,10 +13,12 @@ /// Loads an image if it isn't already contained in the pool /// according to it's image name. If the image is not found /// it tries to load a fallback image (not_found). - SDL_Surface* loadImage(string imagename=""); + SDL_Surface* loadImage(string imagename="", double scale_factor=1); private: - std::map imgcache; + std::map,SDL_Surface*> imgcache; string not_found; + private: + inline SDL_Surface* scaleImage(SDL_Surface* original_image, double scale_factor); }; #endif Modified: trunk/src/objects/Makefile =================================================================== --- trunk/src/objects/Makefile 2005-03-14 15:51:04 UTC (rev 99) +++ trunk/src/objects/Makefile 2005-03-14 23:44:55 UTC (rev 100) @@ -1,7 +1,7 @@ CXX = g++ CXX_FLAGS = -W -Wall -ansi -pedantic CXX_DEBUG = -g #-fno-inline -CXX_OPT = -O2 -march=pentium4 -ffast-math +CXX_OPT = #-O2 -march=pentium4 -ffast-math CXX_GAME = -DSDL_MIXER -DSDL_IMAGE -DALPHA -I ../ SDL = `sdl-config --cflags` SDL_LINK = `sdl-config --libs` -lSDL_mixer -lSDL_image -ldl -rdynamic From DONOTREPLY at icculus.org Mon Mar 14 10:49:57 2005 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 14 Mar 2005 10:49:57 -0500 Subject: r98 - in trunk/tools: . lvl_tools Message-ID: <20050314154957.4310.qmail@icculus.org> Author: jonas Date: 2005-03-14 10:49:56 -0500 (Mon, 14 Mar 2005) New Revision: 98 Added: trunk/tools/lvl_tools/ trunk/tools/lvl_tools/Makefile trunk/tools/lvl_tools/lvlextract.c trunk/tools/lvl_tools/lvlextract.h trunk/tools/lvl_tools/pgm_out.c trunk/tools/lvl_tools/png_out.c trunk/tools/lvl_tools/png_xpm_out.c trunk/tools/lvl_tools/xpm_out.c Modified: trunk/tools/Makefile Log: Added a tool (lvlextract) to extract images from Lost Vikings 2 .LVL files. It's still work in progress and doesn't work as expected yet, but you can extract images. Syntax: lvlextract file.lvl [target dir] The .LVL files contain (almost) all sprite images of the game. But at the moment we can just extract images (no names, no arrangements, no game info, etc). Here a summary about the (simple) format: An image header starts at the ascii start signature "TRPS" (4 byte) Then follows (it seems at least) the width as Uint32 LE number (32 byte) Afterwards the height as a Uint32 LE number (32 byte) Then the raw image data follows in form of 8 bit alligned indexed image data. I was able to approximately get/extract the palette beeing used. At the moment the image is extracted like this: write the image as .xpm using our palette. Convert the image using system("convert image.xpm image.png")... The direct png output (libpng) doesn't work yet (segfault?)... Modified: trunk/tools/Makefile =================================================================== --- trunk/tools/Makefile 2005-02-24 11:55:38 UTC (rev 97) +++ trunk/tools/Makefile 2005-03-14 15:49:56 UTC (rev 98) @@ -7,17 +7,23 @@ SDL_LINK = `sdl-config --libs` -lSDL_mixer -lSDL_image OBJS = slvextract.o -BIN = ../slvextract +BIN = slvextract - +default: + $(MAKE) -C lvl_tools + $(MAKE) $(BIN) + $(BIN): $(OBJS) - $(CXX) $(OBJS) $(SDL_LINK) -o $(BIN) + $(CXX) $(OBJS) $(SDL_LINK) -o $(BIN) %.o: %.cpp - $(CXX) $(CXX_FLAGS) $(CXX_DEBUG) $(CXX_GAME) $(SDL) -c $< -o $@ + $(CXX) $(CXX_FLAGS) $(CXX_DEBUG) $(CXX_GAME) $(SDL) -c $< -o $@ clean: - rm -f *.o + rm -f *.o + rm -f $(BIN) + +$(MAKE) -C lvl_tools clean distclean: clean - rm -f *~ + rm -f *~ + +$(MAKE) -C lvl_tools distclean Added: trunk/tools/lvl_tools/Makefile =================================================================== --- trunk/tools/lvl_tools/Makefile 2005-02-24 11:55:38 UTC (rev 97) +++ trunk/tools/lvl_tools/Makefile 2005-03-14 15:49:56 UTC (rev 98) @@ -0,0 +1,23 @@ +CXX = gcc +CXX_FLAGS = -W -Wall -ansi -pedantic +CXX_DEBUG = -g #-fno-inline +CXX_OPT = -O2 -march=pentium4 -ffast-math +CXX_TOOL = -lpng + +OBJS = png_out.o xpm_out.o pgm_out.o png_xpm_out.o lvlextract.o +BIN = ../lvlextract + +default: $(BIN) + +$(BIN): $(OBJS) + $(CXX) $(CXX_TOOL) $(OBJS) -o $(BIN) + +%.o: %.c + $(CXX) $(CXX_FLAGS) $(CXX_DEBUG) -c $< -o $@ + +clean: + rm -f $(BIN) + rm -f *.o *.a + +distclean: clean + rm -f *~ Added: trunk/tools/lvl_tools/lvlextract.c =================================================================== --- trunk/tools/lvl_tools/lvlextract.c 2005-02-24 11:55:38 UTC (rev 97) +++ trunk/tools/lvl_tools/lvlextract.c 2005-03-14 15:49:56 UTC (rev 98) @@ -0,0 +1,412 @@ +/* + * (C) 2004 Jonas Jermann + * + * License: GPL + */ + +#include +#include +#include +#include +#include +#include +#include "lvlextract.h" + +/* RGB(A) palette */ +unsigned short lvl_palette[256][3]= { +/* (One of) the first two RGB values is the background + * (colorkey) color... in lost_penguins it's set to + * 0xff00ff + */ +/* + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, +*/ + 0xff, 0x00, 0xff, + 0xff, 0x00, 0xff, + + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, + 0x08, 0x04, 0x00, + 0x00, 0x04, 0x10, + 0x08, 0x10, 0x00, + 0x08, 0x10, 0x10, + 0x18, 0x10, 0x00, + 0x18, 0x14, 0x10, + 0x00, 0x08, 0x29, + 0x00, 0x0c, 0x39, + 0x10, 0x14, 0x20, + 0x18, 0x18, 0x20, + 0x08, 0x20, 0x08, + 0x08, 0x24, 0x29, + 0x18, 0x28, 0x39, + 0x29, 0x10, 0x08, + 0x20, 0x24, 0x00, + 0x20, 0x24, 0x10, + 0x31, 0x24, 0x00, + 0x31, 0x24, 0x00, + 0x31, 0x34, 0x00, + 0x31, 0x34, 0x10, + 0x20, 0x20, 0x20, + 0x29, 0x24, 0x20, + 0x20, 0x34, 0x29, + 0x31, 0x30, 0x29, + 0x31, 0x30, 0x39, + 0x00, 0x0c, 0x4a, + 0x62, 0x65, 0x08, + 0x73, 0x6d, 0x52, + 0x73, 0x00, 0xb4, + 0x94, 0x38, 0x20, + 0xa4, 0x65, 0x39, + 0x31, 0x34, 0x4a, + 0x29, 0x34, 0x62, + 0x08, 0x44, 0x10, + 0x00, 0x65, 0x00, + 0x29, 0x59, 0x39, + 0x31, 0x7d, 0x39, + 0x29, 0x48, 0x6a, + 0x4a, 0x0c, 0x08, + 0x41, 0x2c, 0x00, + 0x41, 0x28, 0x10, + 0x52, 0x2c, 0x10, + 0x52, 0x3c, 0x10, + 0x4a, 0x38, 0x29, + 0x41, 0x3c, 0x39, + 0x62, 0x1c, 0x08, + 0x73, 0x08, 0x08, + 0x62, 0x3c, 0x10, + 0x7b, 0x20, 0x08, + 0x73, 0x34, 0x10, + 0x41, 0x3c, 0x4a, + 0x41, 0x40, 0x00, + 0x41, 0x40, 0x10, + 0x4a, 0x55, 0x00, + 0x52, 0x40, 0x00, + 0x52, 0x55, 0x08, + 0x52, 0x55, 0x18, + 0x52, 0x44, 0x39, + 0x5a, 0x59, 0x39, + 0x62, 0x44, 0x00, + 0x62, 0x55, 0x00, + 0x62, 0x55, 0x18, + 0x73, 0x44, 0x10, + 0x73, 0x59, 0x00, + 0x73, 0x59, 0x10, + 0x62, 0x40, 0x20, + 0x62, 0x44, 0x39, + 0x73, 0x40, 0x20, + 0x7b, 0x44, 0x20, + 0x7b, 0x55, 0x20, + 0x7b, 0x59, 0x31, + 0x62, 0x65, 0x08, + 0x62, 0x65, 0x18, + 0x62, 0x75, 0x18, + 0x7b, 0x6d, 0x08, + 0x73, 0x6d, 0x18, + 0x7b, 0x7d, 0x08, + 0x7b, 0x7d, 0x18, + 0x7b, 0x6d, 0x29, + 0x7b, 0x7d, 0x29, + 0x4a, 0x48, 0x52, + 0x52, 0x50, 0x52, + 0x4a, 0x4c, 0x6a, + 0x4a, 0x4c, 0x7b, + 0x5a, 0x59, 0x62, + 0x4a, 0x71, 0x5a, + 0x6a, 0x55, 0x52, + 0x73, 0x6d, 0x52, + 0x62, 0x65, 0x62, + 0x62, 0x6d, 0x7b, + 0x73, 0x71, 0x6a, + 0x7b, 0x79, 0x7b, + 0x08, 0x10, 0x94, + 0x00, 0x04, 0xac, + 0x10, 0x1c, 0xa4, + 0x18, 0x20, 0xbd, + 0x20, 0x30, 0x83, + 0x00, 0x04, 0xf6, + 0x29, 0x30, 0xc5, + 0x29, 0x4c, 0x83, + 0x20, 0x40, 0xa4, + 0x20, 0x55, 0xc5, + 0x20, 0x4c, 0xee, + 0x73, 0x00, 0xb4, + 0x4a, 0x4c, 0xac, + 0x4a, 0x71, 0x83, + 0x52, 0x6d, 0xac, + 0x4a, 0x48, 0xcd, + 0x52, 0x4c, 0xee, + 0x5a, 0x6d, 0xe6, + 0x00, 0x99, 0x00, + 0x10, 0xea, 0x08, + 0x4a, 0x85, 0x39, + 0x4a, 0xa5, 0xac, + 0x7b, 0x85, 0xa4, + 0x5a, 0xba, 0xee, + 0x6a, 0x89, 0xee, + 0x94, 0x08, 0x08, + 0x94, 0x2c, 0x08, + 0x94, 0x38, 0x20, + 0xac, 0x0c, 0x08, + 0xb4, 0x30, 0x10, + 0xb4, 0x34, 0x31, + 0x94, 0x50, 0x10, + 0x8b, 0x4c, 0x20, + 0x8b, 0x5d, 0x20, + 0x8b, 0x5d, 0x31, + 0x8b, 0x69, 0x00, + 0x9c, 0x69, 0x08, + 0x94, 0x7d, 0x00, + 0x94, 0x79, 0x39, + 0xac, 0x55, 0x00, + 0xa4, 0x59, 0x20, + 0xa4, 0x5d, 0x31, + 0xbd, 0x50, 0x20, + 0xa4, 0x65, 0x39, + 0xa4, 0x7d, 0x20, + 0xac, 0x75, 0x39, + 0xbd, 0x65, 0x29, + 0xbd, 0x6d, 0x39, + 0x8b, 0x61, 0x4a, + 0x9c, 0x79, 0x5a, + 0xd5, 0x08, 0x08, + 0xd5, 0x30, 0x20, + 0xf6, 0x08, 0x08, + 0xf6, 0x28, 0x20, + 0xf6, 0x38, 0x39, + 0xc5, 0x59, 0x39, + 0xc5, 0x79, 0x29, + 0xc5, 0x7d, 0x39, + 0xde, 0x7d, 0x31, + 0xe6, 0x59, 0x29, + 0xe6, 0x59, 0x52, + 0xff, 0x59, 0x52, + 0xb4, 0x24, 0xbd, + 0x8b, 0x81, 0x10, + 0x94, 0x95, 0x00, + 0x8b, 0x81, 0x20, + 0x9c, 0x99, 0x20, + 0xa4, 0x81, 0x00, + 0xa4, 0x81, 0x10, + 0xac, 0x9d, 0x00, + 0xbd, 0x81, 0x08, + 0xac, 0x99, 0x20, + 0xb4, 0xae, 0x18, + 0xa4, 0xaa, 0x20, + 0xb4, 0xae, 0x29, + 0xbd, 0xb6, 0x39, + 0x94, 0x81, 0x73, + 0xa4, 0x99, 0x41, + 0xbd, 0x99, 0x5a, + 0xb4, 0x8d, 0x73, + 0xbd, 0xaa, 0x73, + 0xc5, 0x9d, 0x00, + 0xcd, 0x99, 0x20, + 0xcd, 0xb6, 0x00, + 0xc5, 0xb6, 0x29, + 0xd5, 0xba, 0x20, + 0xde, 0xba, 0x39, + 0xff, 0x99, 0x00, + 0xe6, 0xae, 0x00, + 0xc5, 0x81, 0x4a, + 0xc5, 0x95, 0x41, + 0xd5, 0x99, 0x41, + 0xd5, 0x99, 0x52, + 0xde, 0x85, 0x73, + 0xd5, 0xaa, 0x5a, + 0xd5, 0xb2, 0x6a, + 0xd5, 0xb6, 0x7b, + 0xe6, 0x81, 0x52, + 0xf6, 0x85, 0x73, + 0xee, 0xa5, 0x5a, + 0xf6, 0xb2, 0x73, + 0xd5, 0xce, 0x00, + 0xd5, 0xca, 0x31, + 0xd5, 0xd2, 0x20, + 0xde, 0xda, 0x39, + 0xf6, 0xd2, 0x00, + 0xff, 0xf2, 0x00, + 0xee, 0xee, 0x20, + 0xf6, 0xf2, 0x39, + 0xd5, 0xca, 0x41, + 0xde, 0xda, 0x4a, + 0xee, 0xde, 0x52, + 0xf6, 0xde, 0x73, + 0xee, 0xe2, 0x41, + 0xf6, 0xf2, 0x52, + 0x8b, 0x89, 0x83, + 0x94, 0x95, 0x9c, + 0x8b, 0x99, 0xb4, + 0xb4, 0xa5, 0x94, + 0xa4, 0xa5, 0xac, + 0xb4, 0xb2, 0xb4, + 0xbe, 0xbd, 0xbe, + 0x94, 0x91, 0xf6, + 0xac, 0xb6, 0xd5, + 0xac, 0xb2, 0xff, + 0xbd, 0xd2, 0xee, + 0xd5, 0xb6, 0x94, + 0xcd, 0xba, 0xb4, + 0xf6, 0x99, 0x94, + 0xf6, 0xba, 0x9c, + 0xde, 0xca, 0x8b, + 0xde, 0xce, 0xa4, + 0xde, 0xd2, 0xb4, + 0xff, 0xde, 0x94, + 0xf6, 0xda, 0xbd, + 0xff, 0xfa, 0xbd, + 0xcd, 0xca, 0xcd, + 0xde, 0xda, 0xcd, + 0xde, 0xda, 0xde, + 0xd5, 0xf6, 0xff, + 0xe6, 0xe2, 0xee, + 0xf6, 0xf2, 0xe6, + 0xff, 0xfa, 0xff, + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, +}; + +/* unused */ +unsigned int lvl_palette2[256]= { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x08040000, 0x00041000, 0x08100000, 0x08101000, + 0x18100000, 0x18141000, 0x00082900, 0x000c3900, 0x10142000, 0x18182000, 0x08200800, 0x08242900, 0x18283900, 0x29100800, 0x20240000, 0x20241000, 0x31240000, 0x31240000, 0x31340000, 0x31341000, + 0x20202000, 0x29242000, 0x20342900, 0x31302900, 0x31303900, 0x000c4a00, 0x62650800, 0x736d5200, 0x7300b400, 0x94382000, 0xa4653900, 0x31344a00, 0x29346200, 0x08441000, 0x00650000, 0x29593900, + 0x317d3900, 0x29486a00, 0x4a0c0800, 0x412c0000, 0x41281000, 0x522c1000, 0x523c1000, 0x4a382900, 0x413c3900, 0x621c0800, 0x73080800, 0x623c1000, 0x7b200800, 0x73341000, 0x413c4a00, 0x41400000, + 0x41401000, 0x4a550000, 0x52400000, 0x52550800, 0x52551800, 0x52443900, 0x5a593900, 0x62440000, 0x62550000, 0x62551800, 0x73441000, 0x73590000, 0x73591000, 0x62402000, 0x62443900, 0x73402000, + 0x7b442000, 0x7b552000, 0x7b593100, 0x62650800, 0x62651800, 0x62751800, 0x7b6d0800, 0x736d1800, 0x7b7d0800, 0x7b7d1800, 0x7b6d2900, 0x7b7d2900, 0x4a485200, 0x52505200, 0x4a4c6a00, 0x4a4c7b00, + 0x5a596200, 0x4a715a00, 0x6a555200, 0x736d5200, 0x62656200, 0x626d7b00, 0x73716a00, 0x7b797b00, 0x08109400, 0x0004ac00, 0x101ca400, 0x1820bd00, 0x20308300, 0x0004f600, 0x2930c500, 0x294c8300, + 0x2040a400, 0x2055c500, 0x204cee00, 0x7300b400, 0x4a4cac00, 0x4a718300, 0x526dac00, 0x4a48cd00, 0x524cee00, 0x5a6de600, 0x00990000, 0x10ea0800, 0x4a853900, 0x4aa5ac00, 0x7b85a400, 0x5abaee00, + 0x6a89ee00, 0x94080800, 0x942c0800, 0x94382000, 0xac0c0800, 0xb4301000, 0xb4343100, 0x94501000, 0x8b4c2000, 0x8b5d2000, 0x8b5d3100, 0x8b690000, 0x9c690800, 0x947d0000, 0x94793900, 0xac550000, + 0xa4592000, 0xa45d3100, 0xbd502000, 0xa4653900, 0xa47d2000, 0xac753900, 0xbd652900, 0xbd6d3900, 0x8b614a00, 0x9c795a00, 0xd5080800, 0xd5302000, 0xf6080800, 0xf6282000, 0xf6383900, 0xc5593900, + 0xc5792900, 0xc57d3900, 0xde7d3100, 0xe6592900, 0xe6595200, 0xff595200, 0xb424bd00, 0x8b811000, 0x94950000, 0x8b812000, 0x9c992000, 0xa4810000, 0xa4811000, 0xac9d0000, 0xbd810800, 0xac992000, + 0xb4ae1800, 0xa4aa2000, 0xb4ae2900, 0xbdb63900, 0x94817300, 0xa4994100, 0xbd995a00, 0xb48d7300, 0xbdaa7300, 0xc59d0000, 0xcd992000, 0xcdb60000, 0xc5b62900, 0xd5ba2000, 0xdeba3900, 0xff990000, + 0xe6ae0000, 0xc5814a00, 0xc5954100, 0xd5994100, 0xd5995200, 0xde857300, 0xd5aa5a00, 0xd5b26a00, 0xd5b67b00, 0xe6815200, 0xf6857300, 0xeea55a00, 0xf6b27300, 0xd5ce0000, 0xd5ca3100, 0xd5d22000, + 0xdeda3900, 0xf6d20000, 0xfff20000, 0xeeee2000, 0xf6f23900, 0xd5ca4100, 0xdeda4a00, 0xeede5200, 0xf6de7300, 0xeee24100, 0xf6f25200, 0x8b898300, 0x94959c00, 0x8b99b400, 0xb4a59400, 0xa4a5ac00, + 0xb4b2b400, 0xbebdbe00, 0x9491f600, 0xacb6d500, 0xacb2ff00, 0xbdd2ee00, 0xd5b69400, 0xcdbab400, 0xf6999400, 0xf6ba9c00, 0xdeca8b00, 0xdecea400, 0xded2b400, 0xffde9400, 0xf6dabd00, 0xfffabd00, + 0xcdcacd00, 0xdedacd00, 0xdedade00, 0xd5f6ff00, 0xe6e2ee00, 0xf6f2e600, 0xfffaff00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 +}; + +char* xpm_map[256] = { + " ", ". ", "+ ", "@ ", "# ", "$ ", "% ", "& ", "* ", "= ", "- ", "; ", "> ", ", ", "' ", ") ", + "! ", "~ ", "{ ", "] ", "^ ", "/ ", "( ", "_ ", ": ", "< ", "[ ", "} ", "| ", "1 ", "2 ", "3 ", + "4 ", "5 ", "6 ", "7 ", "8 ", "9 ", "0 ", "a ", "b ", "c ", "d ", "e ", "f ", "g ", "h ", "i ", + "j ", "k ", "l ", "m ", "n ", "o ", "p ", "q ", "r ", "s ", "t ", "u ", "v ", "w ", "x ", "y ", + "z ", "A ", "B ", "C ", "D ", "E ", "F ", "G ", "H ", "I ", "J ", "K ", "L ", "M ", "N ", "O ", + "P ", "Q ", "R ", "S ", "T ", "U ", "V ", "W ", "X ", "Y ", "Z ", "` ", " .", "..", "+.", "@.", + "#.", "$.", "%.", "&.", "*.", "=.", "-.", ";.", ">.", ",.", "\'.", ").", "!.", "~.", "{.", "].", + "^.", "/.", "(.", "_.", ":.", "<.", "[.", "}.", "|.", "1.", "2.", "3.", "4.", "5.", "6.", "7.", + "8.", "9.", "0.", "a.", "b.", "c.", "d.", "e.", "f.", "g.", "h.", "i.", "j.", "k.", "l.", "m.", + "n.", "o.", "p.", "q.", "r.", "s.", "t.", "u.", "v.", "w.", "x.", "y.", "z.", "A.", "B.", "C.", + "D.", "E.", "F.", "G.", "H.", "I.", "J.", "K.", "L.", "M.", "N.", "O.", "P.", "Q.", "R.", "S.", + "T.", "U.", "V.", "W.", "X.", "Y.", "Z.", "`.", " +", ".+", "++", "@+", "#+", "$+", "%+", "&+", + "*+", "=+", "-+", ";+", ">+", ",+", "'+", ")+", "!+", "~+", "{+", "]+", "^+", "/+", "(+", "_+", + ":+", "<+", "[+", "}+", "|+", "1+", "2+", "3+", "4+", "5+", "6+", "7+", "8+", "9+", "0+", "a+", + "b+", "c+", "d+", "e+", "f+", "g+", "h+", "i+", "j+", "k+", "l+", "m+", "n+", "o+", "p+", "q+", + "r+", "s+", "t+", "u+", "v+", "w+", "x+", "y+", "z+", "A+", "B+", "C+", "D+", "E+", "F+", "G+" +}; + + +int main(int argc, char *argv[]) { + int fd_in; +/* FILE* append_file; */ + char buf[16]; + char *data; + char *last_ptr; + char *off_ptr; + struct stat sb; + int data_size; + int counter=0; + int unknown=0; + char entry_id[]="TRPS"; + + if (argc < 2) { + printf("Usage: %s input.lvl [destination]\n", argv[0]); + exit(1); + } + + fd_in = open(argv[1], O_RDONLY); + + if (fd_in < 0) { + perror("error opening file"); + exit(1); + } + + read(fd_in, buf, 12); + + if ((buf[0] != 'D') && (buf[1] != 'A') && + (buf[2] != 'T') && (buf[3] != 'A')) { + printf("Invalid file\n"); + close(fd_in); + exit(1); + } + + if (argc > 2) { + mkdir(argv[2], 0777); + chdir(argv[2]); + printf("directory: %s\n", argv[2]); + } else { + /* copy the filename */ + if (strrchr(argv[1], '/')) strncpy(buf, strrchr(argv[1], '/')+1, 16); + else strncpy(buf, argv[1], 16); + + /* truncate filename at . */ + if (strrchr(buf, '.')) { + char *loc = strrchr(buf, '.'); + *loc = 0; + } + + mkdir(buf, 0777); + chdir(buf); + + printf("directory: %s\n", buf); + } + + /* get file size */ + fstat(fd_in, &sb); + data_size = sb.st_size; + + /* File for unknown content */ +/* append_file = fopen("unknown.bin", "a"); */ + + /* map the entire file into process memory space */ + data = mmap(NULL, data_size, PROT_READ, MAP_PRIVATE, fd_in, 0); + last_ptr=data; + while (off_ptr=memchr(last_ptr,'T',(data_size-(last_ptr-data)))) { +/* + if (!strncmp(off_ptr,entry_id,4)) fprintf(append_file,"****************"); + fwrite(last_ptr,1,(off_ptr-last_ptr),append_file); +*/ + unknown+=(off_ptr-last_ptr); + if (!strncmp(off_ptr,entry_id,4)) { + counter++; + /* write_pgm, write_png, write_xpm, write_png_xpm */ + last_ptr=write_png_xpm(off_ptr,counter); + } else { + last_ptr=off_ptr+1; + } + } + + printf("Contains %d extracted images, unknown content: %d bytes\n",counter,unknown); + + munmap(data, data_size); + close(fd_in); +/* fclose(append_file); */ + + return 0; +} + Added: trunk/tools/lvl_tools/lvlextract.h =================================================================== --- trunk/tools/lvl_tools/lvlextract.h 2005-02-24 11:55:38 UTC (rev 97) +++ trunk/tools/lvl_tools/lvlextract.h 2005-03-14 15:49:56 UTC (rev 98) @@ -0,0 +1,8 @@ +#ifndef _LVLEXTRACT_H +#define _LVLEXTRACT_H 1 + +extern unsigned short lvl_palette[256][3]; +extern unsigned int lvl_palette2[256]; +extern char* xpm_map[256]; + +#endif Added: trunk/tools/lvl_tools/pgm_out.c =================================================================== --- trunk/tools/lvl_tools/pgm_out.c 2005-02-24 11:55:38 UTC (rev 97) +++ trunk/tools/lvl_tools/pgm_out.c 2005-03-14 15:49:56 UTC (rev 98) @@ -0,0 +1,39 @@ +/* + * Copyright 2005 by Jonas Jermann + * + */ + +#include +#include +#include +#include +#include +#include +#include "lvlextract.h" + +char* write_pgm(char* ptr, int counter) { + int size; + FILE *out_file; + char pbm_header[50]; + char filename[50]; + int *width, *height; + + /* get size */ + width=(int *)(ptr+4); + height=(int *)(ptr+8); + size=(*width)*(*height); + /* global data offset */ + ptr+=12; + /* pbm header */ + sprintf(pbm_header,"P5\n%d %d\n255\n",*width,*height); + sprintf(filename,"test_%010d.pgm",counter); + + out_file = fopen(filename,"wb"); + fprintf(out_file,"P5\n%d %d\n255\n",*width,*height); + fclose(out_file); + out_file = fopen(filename,"a"); + fwrite(ptr,1,size,out_file); + fclose(out_file); + + return ptr+size; +} Added: trunk/tools/lvl_tools/png_out.c =================================================================== --- trunk/tools/lvl_tools/png_out.c 2005-02-24 11:55:38 UTC (rev 97) +++ trunk/tools/lvl_tools/png_out.c 2005-03-14 15:49:56 UTC (rev 98) @@ -0,0 +1,137 @@ +/* + * Copyright 2005 by Jonas Jermann + * + * NOT WORKING!! + * Uses libpng (which uses zlib), so see according licenses. + * Based on vo_png.c from Felix Buenemann + * + */ + +#include +#include +#include +#include +#include +#include "lvlextract.h" + +int z_compression = Z_NO_COMPRESSION; + +struct pngdata { + FILE * fp; + png_structp png_ptr; + png_infop info_ptr; + enum {OK,ERROR} status; +}; + +/* TODO: read palette information */ +struct pngdata create_png(char * fname, int image_width, int image_height) { + struct pngdata png; + png_color palette[256]; +/* png_colorp palette; */ + + int k; + + png.png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + png.info_ptr = png_create_info_struct(png.png_ptr); + + if (!png.png_ptr) { + png.status = ERROR; + return png; + } + + if (!png.info_ptr) { + png_destroy_write_struct(&png.png_ptr, (png_infopp)NULL); + png.status = ERROR; + return png; + } + + if (setjmp(png.png_ptr->jmpbuf)) { + png_destroy_write_struct(&png.png_ptr, &png.info_ptr); + fclose(png.fp); + png.status = ERROR; + return png; + } + + png.fp = fopen (fname, "wb"); + if (png.fp == NULL) { + printf("\nPNG Error opening %s for writing!\n", strerror(errno)); + png.status = ERROR; + return png; + } + + png_init_io(png.png_ptr, png.fp); + + /* set the zlib compression level */ + png_set_compression_level(png.png_ptr, z_compression); + + png_set_IHDR(png.png_ptr, png.info_ptr, image_width, image_height, + 8, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + +/* palette = (png_colorp)png_malloc(png.png_ptr, 256 * png_sizeof (png_color)); */ + + for (k=0; k<256; k++) { + palette[k].red = lvl_palette[k][0]; + palette[k].green = lvl_palette[k][1]; + palette[k].blue = lvl_palette[k][2]; +/* + palette[k].red = (png_byte)lvl_palette2[k]; + palette[k].green = (png_byte)((png_bytep)lvl_palette2[k]+8); + palette[k].blue = (png_byte)((png_bytep)lvl_palette2[k]+16); +*/ + } + + png_set_PLTE(png.png_ptr, png.info_ptr, palette, 256); + png_write_info(png.png_ptr, png.info_ptr); + + png.status = OK; + return png; +} + +static int destroy_png(struct pngdata png) { + png_write_end(png.png_ptr, png.info_ptr); + + png_destroy_write_struct(&png.png_ptr, &png.info_ptr); + + fclose (png.fp); + + return 0; +} + +char* write_png(char* ptr, int counter){ + int size; + int *width, *height; + char buf[100]; + int k; + struct pngdata png; + + /* get size */ + width=(int *)(ptr+4); + height=(int *)(ptr+8); + size=(*width)*(*height); + /* global data offset */ + ptr+=12; + png_bytep row_pointers[(*height)]; + + snprintf(buf, 100, "%08d.png", counter); + + png = create_png(buf, *width, *height); + + if(png.status){ + printf("PNG Error in create_png\n"); + exit(2); + } + + for ( k = 0; k < *height; k++ ) + row_pointers[k] = (png_bytep)(ptr+k*(*width)); + +printf("trying to write image...\n---------\n"); + + png_write_image(png.png_ptr, row_pointers); +printf("\n----------\n"); + destroy_png(png); +printf("DONE.\n"); + + return ptr+size; +} + Added: trunk/tools/lvl_tools/png_xpm_out.c =================================================================== --- trunk/tools/lvl_tools/png_xpm_out.c 2005-02-24 11:55:38 UTC (rev 97) +++ trunk/tools/lvl_tools/png_xpm_out.c 2005-03-14 15:49:56 UTC (rev 98) @@ -0,0 +1,60 @@ +/* + * Copyright 2005 by Jonas Jermann + * + * Uses libpng (which uses zlib), so see according licenses. + * Based on vo_png.c from Felix Buenemann + * + */ + +#include +#include +#include +#include "lvlextract.h" + +char* write_png_xpm(char* ptr, int counter){ + int size; + int *width, *height; + char buf[100]; + char buf2[200]; + int k,l; + FILE *out_file; + + /* get size */ + width=(int *)(ptr+4); + height=(int *)(ptr+8); + size=(*width)*(*height); + /* global data offset */ + ptr+=12; + snprintf(buf, 100, "%08d", counter); + snprintf(buf2, 200, "%s.xpm", buf); + + /* open file */ + out_file = fopen(buf2,"wb"); + + /* write xpm header */ + fprintf(out_file,"/* XPM */\nstatic char * %s[] = {\n\"%d %d 256 2\",\n",buf2,*width,*height); + for (k=0; k<256; k++) { + fprintf(out_file,"\"%s\tc #%02x%02x%02x\",\n",xpm_map[k],lvl_palette[k][0],lvl_palette[k][1],lvl_palette[k][2]); + } + + /* reopen file for appending */ + fclose(out_file); + out_file=fopen(buf2,"a"); +/* out_file=freopen(buf2,"a",out_file); */ + + /* data */ + for (k=0; k<(*height); k++) { + fprintf(out_file,"\""); + for (l=0; l<(*width); l++) { + fprintf(out_file,"%s",xpm_map[(unsigned char)(*(ptr+k*(*width)+l))]); + } + if (k==((*height)-1)) fprintf(out_file,"\"};\n"); + else fprintf(out_file,"\",\n"); + } + + fclose(out_file); + snprintf(buf2, 200, "convert %s.xpm %s.png && rm %s.xpm",buf,buf,buf); + if (system(buf2)==-1) printf("png conversion failed, probably Imagemagick (convert) isn't installed...\n"); + + return ptr+size; +} Added: trunk/tools/lvl_tools/xpm_out.c =================================================================== --- trunk/tools/lvl_tools/xpm_out.c 2005-02-24 11:55:38 UTC (rev 97) +++ trunk/tools/lvl_tools/xpm_out.c 2005-03-14 15:49:56 UTC (rev 98) @@ -0,0 +1,56 @@ +/* + * Copyright 2005 by Jonas Jermann + * + * Uses libpng (which uses zlib), so see according licenses. + * Based on vo_png.c from Felix Buenemann + * + */ + +#include +#include +#include +#include "lvlextract.h" + +char* write_xpm(char* ptr, int counter){ + int size; + int *width, *height; + char buf[100]; + int k,l; + FILE *out_file; + + /* get size */ + width=(int *)(ptr+4); + height=(int *)(ptr+8); + size=(*width)*(*height); + /* global data offset */ + ptr+=12; + snprintf(buf, 100, "%08d.xpm", counter); + + /* open file */ + out_file = fopen(buf,"wb"); + + /* write xpm header */ + fprintf(out_file,"/* XPM */\nstatic char * %s[] = {\n\"%d %d 256 2\",\n",buf,*width,*height); + for (k=0; k<256; k++) { + fprintf(out_file,"\"%s\tc #%02x%02x%02x\",\n",xpm_map[k],lvl_palette[k][0],lvl_palette[k][1],lvl_palette[k][2]); + } + + /* reopen file for appending */ + fclose(out_file); + out_file=fopen(buf,"a"); +/* out_file=freopen(buf,"a",out_file); */ + + /* data */ + for (k=0; k<(*height); k++) { + fprintf(out_file,"\""); + for (l=0; l<(*width); l++) { + fprintf(out_file,"%s",xpm_map[(unsigned char)(*(ptr+k*(*width)+l))]); + } + if (k==((*height)-1)) fprintf(out_file,"\"};\n"); + else fprintf(out_file,"\",\n"); + } + + fclose(out_file); + + return ptr+size; +} From DONOTREPLY at icculus.org Mon Mar 14 10:51:04 2005 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 14 Mar 2005 10:51:04 -0500 Subject: r99 - in trunk: . src src/objects Message-ID: <20050314155104.4432.qmail@icculus.org> Author: jonas Date: 2005-03-14 10:51:04 -0500 (Mon, 14 Mar 2005) New Revision: 99 Modified: trunk/TODO trunk/lost_penguins.conf trunk/src/Makefile trunk/src/menu.h trunk/src/objects/Makefile Log: added optimazation gcc parameters, default bpp set to 16, small doc changes Modified: trunk/TODO =================================================================== --- trunk/TODO 2005-03-14 15:49:56 UTC (rev 98) +++ trunk/TODO 2005-03-14 15:51:04 UTC (rev 99) @@ -8,6 +8,7 @@ ==== o General: + o (BIG) move drawing to the objects/menus/etc (create a draw() function)! o pointers => references where possible o Describe everything using Doxygen styles, move the documentation from *.cpp to the headers... @@ -25,6 +26,10 @@ character down or better: an elevator should push the characters up o In case of the elevator, the players are somehow "bound" to the elevator (ie. it's not like: the elevator moves, the character falls, but they move together) + Solution: The elevators move function checks all objects it would + hit, if they are pushable (not dense) they are moved first if + possible. If it's not possible, do sthg else (stop the elevator and hit the + object/whatever)... o the collision detection and the move/fall code is all a big mess o Animations/Events: Modified: trunk/lost_penguins.conf =================================================================== --- trunk/lost_penguins.conf 2005-03-14 15:49:56 UTC (rev 98) +++ trunk/lost_penguins.conf 2005-03-14 15:51:04 UTC (rev 99) @@ -4,4 +4,4 @@ full 0 width 1024 height 768 -bpp 32 \ No newline at end of file +bpp 16 Modified: trunk/src/Makefile =================================================================== --- trunk/src/Makefile 2005-03-14 15:49:56 UTC (rev 98) +++ trunk/src/Makefile 2005-03-14 15:51:04 UTC (rev 99) @@ -14,7 +14,7 @@ BIN = ../lost_penguins -all: +default: +$(MAKE) depend +$(MAKE) -C objects +$(MAKE) $(BIN) @@ -23,7 +23,7 @@ $(CXX) $(OBJS) $(PLUGS) $(SDL_LINK) -o $(BIN) %.o: %.cpp - $(CXX) $(CXX_FLAGS) $(CXX_DEBUG) $(CXX_GAME) $(SDL) -c $< -o $@ + $(CXX) $(CXX_FLAGS) $(CXX_DEBUG) $(CXX_GAME) $(CXX_OPT) $(SDL) -c $< -o $@ $(PLUGS): +$(MAKE) -C objects Modified: trunk/src/menu.h =================================================================== --- trunk/src/menu.h 2005-03-14 15:49:56 UTC (rev 98) +++ trunk/src/menu.h 2005-03-14 15:51:04 UTC (rev 99) @@ -7,8 +7,6 @@ virtual function act(), overload it in the child classes. Only the base class is needed to draw the menu in gfxeng. The background depends from where the menu is called. - - \todo Create the actual menus (StartMenu, etc)... */ class Menu { friend class GraphicsEngine; Modified: trunk/src/objects/Makefile =================================================================== --- trunk/src/objects/Makefile 2005-03-14 15:49:56 UTC (rev 98) +++ trunk/src/objects/Makefile 2005-03-14 15:51:04 UTC (rev 99) @@ -13,13 +13,13 @@ PLUGS = ../objects.a -all: +default: +$(MAKE) depend +$(MAKE) $(OBJS) +$(MAKE) $(PLUGS) %.o: %.cpp - $(CXX) $(CXX_FLAGS) $(CXX_DEBUG) $(CXX_GAME) $(SDL) -c $< -o $@ + $(CXX) $(CXX_FLAGS) $(CXX_DEBUG) $(CXX_GAME) $(CXX_OPT) $(SDL) -c $< -o $@ $(PLUGS): $(OBJS) $(AR) r $(PLUGS) $(OBJS) From DONOTREPLY at icculus.org Thu Mar 17 18:39:59 2005 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 17 Mar 2005 18:39:59 -0500 Subject: r103 - trunk/tools/lvl_tools Message-ID: <20050317233959.30678.qmail@icculus.org> Author: jonas Date: 2005-03-17 18:39:59 -0500 (Thu, 17 Mar 2005) New Revision: 103 Added: trunk/tools/lvl_tools/lvl2magick.c Modified: trunk/tools/lvl_tools/Makefile Log: lvl2magick uses ImageMagick (libmagick-dev) to parse .lvl files, read all images and write them as one big image. At the moment the image is just one row which will result in illegal images (for most programs), if the row size is too big. Additionally it creates a text file with a description about the image offsets, the format is: Number of images x_offset y_offset width height ... The output format can be specified in the source file (see char* type). Modified: trunk/tools/lvl_tools/Makefile =================================================================== --- trunk/tools/lvl_tools/Makefile 2005-03-15 13:40:58 UTC (rev 102) +++ trunk/tools/lvl_tools/Makefile 2005-03-17 23:39:59 UTC (rev 103) @@ -1,19 +1,27 @@ -CXX = gcc -CXX_FLAGS = -W -Wall -ansi -pedantic -CXX_DEBUG = -g #-fno-inline -CXX_OPT = -O2 -march=pentium4 -ffast-math -CXX_TOOL = -lpng +CC = gcc +CC_FLAGS = -ansi -pedantic -W -Wall +CC_DEBUG = -g #-fno-inline +CC_OPT = -O2 -march=pentium4 -ffast-math +CC_TOOL = -lpng +CC_MAGICK = `Magick-config --ldflags --libs` -OBJS = png_out.o xpm_out.o pgm_out.o png_xpm_out.o lvlextract.o -BIN = ../lvlextract +OBJS = png_out.o xpm_out.o pgm_out.o png_xpm_out.o lvlextract.o +OBJS_MAGICK = lvl2magick.o +BIN = ../lvlextract +BIN_MAGICK = ../lvl2magick -default: $(BIN) +default: $(BIN_MAGICK) +all: $(BIN) $(BIN_MAGICK) + $(BIN): $(OBJS) - $(CXX) $(CXX_TOOL) $(OBJS) -o $(BIN) + $(CC) $(CC_TOOL) $(OBJS) -o $(BIN) +$(BIN_MAGICK): $(OBJS_MAGICK) + $(CC) $(CC_MAGICK) $(OBJS_MAGICK) -o $(BIN_MAGICK) + %.o: %.c - $(CXX) $(CXX_FLAGS) $(CXX_DEBUG) -c $< -o $@ + $(CC) $(CC_FLAGS) $(CC_DEBUG) -c $< -o $@ clean: rm -f $(BIN) Added: trunk/tools/lvl_tools/lvl2magick.c =================================================================== --- trunk/tools/lvl_tools/lvl2magick.c 2005-03-15 13:40:58 UTC (rev 102) +++ trunk/tools/lvl_tools/lvl2magick.c 2005-03-17 23:39:59 UTC (rev 103) @@ -0,0 +1,333 @@ +/* + * (C) 2004 Jonas Jermann + * + * License: GPL + */ + +#include +#include +#include +#include +#include +#include +#include + +enum { + red=0, + green=1, + blue=2 +}; + +enum { + img_x=0, + img_y=1, + img_w=2, + img_h=3 +}; + +/* RGB palette */ +unsigned short lvl_palette[256][3]= { + /* (One of) the first two RGB values is the background + * (colorkey) color... (colorkey used: 0xff00ff + * (before: 0x00, 0x00, 0x00) + */ + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x04, 0x00, 0x00, 0x04, 0x10, 0x08, 0x10, 0x00, 0x08, 0x10, 0x10, + 0x18, 0x10, 0x00, 0x18, 0x14, 0x10, 0x00, 0x08, 0x29, 0x00, 0x0c, 0x39, + 0x10, 0x14, 0x20, 0x18, 0x18, 0x20, 0x08, 0x20, 0x08, 0x08, 0x24, 0x29, + 0x18, 0x28, 0x39, 0x29, 0x10, 0x08, 0x20, 0x24, 0x00, 0x20, 0x24, 0x10, + 0x31, 0x24, 0x00, 0x31, 0x24, 0x00, 0x31, 0x34, 0x00, 0x31, 0x34, 0x10, + 0x20, 0x20, 0x20, 0x29, 0x24, 0x20, 0x20, 0x34, 0x29, 0x31, 0x30, 0x29, + 0x31, 0x30, 0x39, 0x00, 0x0c, 0x4a, 0x62, 0x65, 0x08, 0x73, 0x6d, 0x52, + 0x73, 0x00, 0xb4, 0x94, 0x38, 0x20, 0xa4, 0x65, 0x39, 0x31, 0x34, 0x4a, + 0x29, 0x34, 0x62, 0x08, 0x44, 0x10, 0x00, 0x65, 0x00, 0x29, 0x59, 0x39, + 0x31, 0x7d, 0x39, 0x29, 0x48, 0x6a, 0x4a, 0x0c, 0x08, 0x41, 0x2c, 0x00, + 0x41, 0x28, 0x10, 0x52, 0x2c, 0x10, 0x52, 0x3c, 0x10, 0x4a, 0x38, 0x29, + 0x41, 0x3c, 0x39, 0x62, 0x1c, 0x08, 0x73, 0x08, 0x08, 0x62, 0x3c, 0x10, + 0x7b, 0x20, 0x08, 0x73, 0x34, 0x10, 0x41, 0x3c, 0x4a, 0x41, 0x40, 0x00, + 0x41, 0x40, 0x10, 0x4a, 0x55, 0x00, 0x52, 0x40, 0x00, 0x52, 0x55, 0x08, + 0x52, 0x55, 0x18, 0x52, 0x44, 0x39, 0x5a, 0x59, 0x39, 0x62, 0x44, 0x00, + 0x62, 0x55, 0x00, 0x62, 0x55, 0x18, 0x73, 0x44, 0x10, 0x73, 0x59, 0x00, + 0x73, 0x59, 0x10, 0x62, 0x40, 0x20, 0x62, 0x44, 0x39, 0x73, 0x40, 0x20, + 0x7b, 0x44, 0x20, 0x7b, 0x55, 0x20, 0x7b, 0x59, 0x31, 0x62, 0x65, 0x08, + 0x62, 0x65, 0x18, 0x62, 0x75, 0x18, 0x7b, 0x6d, 0x08, 0x73, 0x6d, 0x18, + 0x7b, 0x7d, 0x08, 0x7b, 0x7d, 0x18, 0x7b, 0x6d, 0x29, 0x7b, 0x7d, 0x29, + 0x4a, 0x48, 0x52, 0x52, 0x50, 0x52, 0x4a, 0x4c, 0x6a, 0x4a, 0x4c, 0x7b, + 0x5a, 0x59, 0x62, 0x4a, 0x71, 0x5a, 0x6a, 0x55, 0x52, 0x73, 0x6d, 0x52, + 0x62, 0x65, 0x62, 0x62, 0x6d, 0x7b, 0x73, 0x71, 0x6a, 0x7b, 0x79, 0x7b, + 0x08, 0x10, 0x94, 0x00, 0x04, 0xac, 0x10, 0x1c, 0xa4, 0x18, 0x20, 0xbd, + 0x20, 0x30, 0x83, 0x00, 0x04, 0xf6, 0x29, 0x30, 0xc5, 0x29, 0x4c, 0x83, + 0x20, 0x40, 0xa4, 0x20, 0x55, 0xc5, 0x20, 0x4c, 0xee, 0x73, 0x00, 0xb4, + 0x4a, 0x4c, 0xac, 0x4a, 0x71, 0x83, 0x52, 0x6d, 0xac, 0x4a, 0x48, 0xcd, + 0x52, 0x4c, 0xee, 0x5a, 0x6d, 0xe6, 0x00, 0x99, 0x00, 0x10, 0xea, 0x08, + 0x4a, 0x85, 0x39, 0x4a, 0xa5, 0xac, 0x7b, 0x85, 0xa4, 0x5a, 0xba, 0xee, + 0x6a, 0x89, 0xee, 0x94, 0x08, 0x08, 0x94, 0x2c, 0x08, 0x94, 0x38, 0x20, + 0xac, 0x0c, 0x08, 0xb4, 0x30, 0x10, 0xb4, 0x34, 0x31, 0x94, 0x50, 0x10, + 0x8b, 0x4c, 0x20, 0x8b, 0x5d, 0x20, 0x8b, 0x5d, 0x31, 0x8b, 0x69, 0x00, + 0x9c, 0x69, 0x08, 0x94, 0x7d, 0x00, 0x94, 0x79, 0x39, 0xac, 0x55, 0x00, + 0xa4, 0x59, 0x20, 0xa4, 0x5d, 0x31, 0xbd, 0x50, 0x20, 0xa4, 0x65, 0x39, + 0xa4, 0x7d, 0x20, 0xac, 0x75, 0x39, 0xbd, 0x65, 0x29, 0xbd, 0x6d, 0x39, + 0x8b, 0x61, 0x4a, 0x9c, 0x79, 0x5a, 0xd5, 0x08, 0x08, 0xd5, 0x30, 0x20, + 0xf6, 0x08, 0x08, 0xf6, 0x28, 0x20, 0xf6, 0x38, 0x39, 0xc5, 0x59, 0x39, + 0xc5, 0x79, 0x29, 0xc5, 0x7d, 0x39, 0xde, 0x7d, 0x31, 0xe6, 0x59, 0x29, + 0xe6, 0x59, 0x52, 0xff, 0x59, 0x52, 0xb4, 0x24, 0xbd, 0x8b, 0x81, 0x10, + 0x94, 0x95, 0x00, 0x8b, 0x81, 0x20, 0x9c, 0x99, 0x20, 0xa4, 0x81, 0x00, + 0xa4, 0x81, 0x10, 0xac, 0x9d, 0x00, 0xbd, 0x81, 0x08, 0xac, 0x99, 0x20, + 0xb4, 0xae, 0x18, 0xa4, 0xaa, 0x20, 0xb4, 0xae, 0x29, 0xbd, 0xb6, 0x39, + 0x94, 0x81, 0x73, 0xa4, 0x99, 0x41, 0xbd, 0x99, 0x5a, 0xb4, 0x8d, 0x73, + 0xbd, 0xaa, 0x73, 0xc5, 0x9d, 0x00, 0xcd, 0x99, 0x20, 0xcd, 0xb6, 0x00, + 0xc5, 0xb6, 0x29, 0xd5, 0xba, 0x20, 0xde, 0xba, 0x39, 0xff, 0x99, 0x00, + 0xe6, 0xae, 0x00, 0xc5, 0x81, 0x4a, 0xc5, 0x95, 0x41, 0xd5, 0x99, 0x41, + 0xd5, 0x99, 0x52, 0xde, 0x85, 0x73, 0xd5, 0xaa, 0x5a, 0xd5, 0xb2, 0x6a, + 0xd5, 0xb6, 0x7b, 0xe6, 0x81, 0x52, 0xf6, 0x85, 0x73, 0xee, 0xa5, 0x5a, + 0xf6, 0xb2, 0x73, 0xd5, 0xce, 0x00, 0xd5, 0xca, 0x31, 0xd5, 0xd2, 0x20, + 0xde, 0xda, 0x39, 0xf6, 0xd2, 0x00, 0xff, 0xf2, 0x00, 0xee, 0xee, 0x20, + 0xf6, 0xf2, 0x39, 0xd5, 0xca, 0x41, 0xde, 0xda, 0x4a, 0xee, 0xde, 0x52, + 0xf6, 0xde, 0x73, 0xee, 0xe2, 0x41, 0xf6, 0xf2, 0x52, 0x8b, 0x89, 0x83, + 0x94, 0x95, 0x9c, 0x8b, 0x99, 0xb4, 0xb4, 0xa5, 0x94, 0xa4, 0xa5, 0xac, + 0xb4, 0xb2, 0xb4, 0xbe, 0xbd, 0xbe, 0x94, 0x91, 0xf6, 0xac, 0xb6, 0xd5, + 0xac, 0xb2, 0xff, 0xbd, 0xd2, 0xee, 0xd5, 0xb6, 0x94, 0xcd, 0xba, 0xb4, + 0xf6, 0x99, 0x94, 0xf6, 0xba, 0x9c, 0xde, 0xca, 0x8b, 0xde, 0xce, 0xa4, + 0xde, 0xd2, 0xb4, 0xff, 0xde, 0x94, 0xf6, 0xda, 0xbd, 0xff, 0xfa, 0xbd, + 0xcd, 0xca, 0xcd, 0xde, 0xda, 0xcd, 0xde, 0xda, 0xde, 0xd5, 0xf6, 0xff, + 0xe6, 0xe2, 0xee, 0xf6, 0xf2, 0xe6, 0xff, 0xfa, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + + +/* + * Create an ImageMagick image of size width x height + * + * image_info is an initialized ImageMagick ImageInfo* ptr + * ptr is the pointer to the image data offset + */ +Image* write_magick(unsigned char* ptr, ImageInfo* image_info, unsigned int width, unsigned int height) { + Image* image; + unsigned int y; + register unsigned int x; + register PixelPacket *q,t; + register unsigned char *p; + + image=AllocateImage(image_info); + image->columns=width; + image->rows=height; + t=image->matte_color; + t.red=MaxRGB; + t.green=0; + t.blue=MaxRGB; + image->matte_color=t; + + p=ptr; + for (y=0; y < image->rows; y++) { + q=SetImagePixels(image,0,y,image->columns,1); + if (q == (PixelPacket *) NULL) break; + for (x=0; x < image->columns; x++) { + q->red=MaxRGB*(lvl_palette[*p][red])/255; + q->green=MaxRGB*(lvl_palette[*p][green])/255; + q->blue=MaxRGB*(lvl_palette[*p][blue])/255; + p++; + q++; + } + if (!SyncImagePixels(image)) break; + } + return image; +} + + +int main(int argc, char *argv[]) { + FILE *lvl_file, *unknown_file, *append_file; + char dirname[16], buf[100]; + + /* Initial start pointer to the beginning of the file */ + unsigned char *data; + /* Temporary variable to indicate the last offset to start searching from: + * Either after (1+) an invalid "T" or after the image of a valid "TRPS" */ + unsigned char *last_ptr; + /* Either index position (start) or the last known position after an image */ + unsigned char *save_ptr; + /* Iterates through all offsets at a "T" */ + unsigned char *off_ptr; + + /* temporary variables */ + struct stat sb; + unsigned int i=0; + unsigned int width,height; + + const char entry_id[]="TRPS"; + char type[]="png"; + int debug=0; + unsigned int data_size; + unsigned int num_entries; + unsigned int unknown=0; + + unsigned int x_off=0; + Image* image_list=NULL; + ImageInfo *image_info=NULL; + MontageInfo montage_info; + ExceptionInfo exception; + Image *big_image, *tmp_img; + register PixelPacket colorkey; + + /* -------------------------------------------------------------------- */ + + if (argc < 2) { + printf("Usage: %s input.lvl [destination]\n", argv[0]); + return 1; + } + + lvl_file = fopen(argv[1],"r"); + + if (lvl_file == NULL) { + perror("Error opening file"); + return 1; + } + + fread(buf,1,12,lvl_file); + + if ((buf[0] != 'D') && (buf[1] != 'A') && + (buf[2] != 'T') && (buf[3] != 'A')) { + printf("Invalid file\n"); + fclose(lvl_file); + return 1; + } + + /* get file size */ + fstat(fileno(lvl_file), &sb); + data_size = sb.st_size; + + /* Get directory name and create directory */ + if (argc > 2) { + strncpy(dirname, argv[1], 16); + } else { + /* copy the filename */ + if (strrchr(argv[1], '/')) strncpy(dirname, strrchr(argv[1], '/')+1, 16); + else strncpy(dirname, argv[1], 16); + + /* truncate filename at . */ + if (strrchr(dirname, '.')) { + char *loc = strrchr(dirname, '.'); + *loc = 0; + } + } + mkdir(dirname, 0777); + chdir(dirname); + printf("Directory: %s\n", dirname); + + /* Create file for image informations */ + snprintf(buf,16,"%s.txt",dirname); + append_file = fopen(buf,"w"); + append_file = freopen(buf,"a",append_file); + + /* ImageMagick stuff */ + image_list=NewImageList(); + image_info=CloneImageInfo((ImageInfo *) NULL); + image_info->colorspace = RGBColorspace; + colorkey.red=MaxRGB; + colorkey.green=0; + colorkey.blue=MaxRGB; + colorkey.opacity=0; + + /* Map the entire file into process memory space */ + data = mmap(NULL, data_size, PROT_READ, MAP_PRIVATE, fileno(lvl_file), 0); + + /* Iterate through all image data offsets to get the number of entries and the + * size of the unknown chunk */ + num_entries=0; + last_ptr=data; + save_ptr=data; + while (off_ptr=(unsigned char*)memchr(last_ptr,'T',(data_size-(last_ptr-data)))) { + unknown+=(off_ptr-last_ptr); + if (!strncmp((char*)off_ptr,entry_id,4)) { + num_entries++; + width=*((unsigned int *)(off_ptr+4)); + height=*((unsigned int *)(off_ptr+8)); + last_ptr=off_ptr+12+width*height; + save_ptr=last_ptr; + } else { + last_ptr=off_ptr+1; + } + } + + unsigned short geometry[num_entries][4]; + + /* Iterate through all image data offsets */ + i=0; + last_ptr=data; + save_ptr=data; + while (off_ptr=(unsigned char*)memchr(last_ptr,'T',(data_size-(last_ptr-data)))) { + unknown+=(off_ptr-last_ptr); + if (!strncmp((char*)off_ptr,entry_id,4)) { + i++; + /* + * Write unknown content (up to this image position (off_ptr)) to a file. + * If the file size would be 0, skip it. + */ + if (debug && (off_ptr-save_ptr > 0)) { + snprintf(buf, 100, "%08d.bin", i); + unknown_file = fopen(buf, "wb"); + fwrite(save_ptr,1,(off_ptr-save_ptr),unknown_file); + fclose(unknown_file); + } + + /* --== Parse header ==-- */ + width=*((unsigned int *)(off_ptr+4)); + height=*((unsigned int *)(off_ptr+8)); + geometry[i-1][img_x]=x_off; + geometry[i-1][img_y]=0; + geometry[i-1][img_w]=width; + geometry[i-1][img_h]=height; + x_off+=width; + + /* update last_ptr, get the image and append it to the list */ + tmp_img=write_magick(off_ptr+12,image_info,width,height); + snprintf(buf,100,"%08d.%s",i,type); + strcpy(tmp_img->filename,buf); + AppendImageToList(&image_list,tmp_img); + + /* update pointers */ + last_ptr=off_ptr+12+width*height; + save_ptr=last_ptr; + } else { + last_ptr=off_ptr+1; + } + } + + /* Montage the image and save it */ + GetMontageInfo(image_info,&montage_info); + GetExceptionInfo(&exception); + montage_info.tile="3000x1"; + montage_info.geometry="+0+0"; + montage_info.background_color=colorkey; + montage_info.matte_color=colorkey; + montage_info.gravity=NorthWestGravity; + + big_image=MontageImages(image_list,&montage_info,&exception); + big_image->matte_color=colorkey; + + snprintf(buf, 100, "%s.%s",dirname,type); + strcpy(big_image->filename,buf); + WriteImage(image_info,big_image); + DestroyImage(big_image); + + fprintf(append_file,"%d\n",num_entries); + for (i=0; i Author: jonas Date: 2005-03-18 07:52:51 -0500 (Fri, 18 Mar 2005) New Revision: 104 Modified: trunk/tools/lvl_tools/lvl2magick.c Log: misc. improvements Modified: trunk/tools/lvl_tools/lvl2magick.c =================================================================== --- trunk/tools/lvl_tools/lvl2magick.c 2005-03-17 23:39:59 UTC (rev 103) +++ trunk/tools/lvl_tools/lvl2magick.c 2005-03-18 12:52:51 UTC (rev 104) @@ -1,6 +1,8 @@ /* * (C) 2004 Jonas Jermann * + * Extract Images from .lvl files using ImageMagick api + * * License: GPL */ @@ -25,81 +27,233 @@ img_h=3 }; +enum { + errno_ok=0, + errno_quit=1, + errno_parse=2, + errno_open=3, + errno_invalid=4, + errno_misc=5 +}; + +struct config_s { + /* create unknown.bin chunk files if != 0 */ + int debug; + /* input lvl file */ + char lvl_file[20]; + /* input data file */ + char data_file[20]; + /* output geometry file */ + char geom_file[20]; + /* base name (used for output directory and output file names) */ + char basename[20]; + /* image format */ + char format[5]; + /* colorkey */ + PixelPacket colorkey; + /* background color */ + PixelPacket bg; +} config; + /* RGB palette */ -unsigned short lvl_palette[256][3]= { - /* (One of) the first two RGB values is the background - * (colorkey) color... (colorkey used: 0xff00ff - * (before: 0x00, 0x00, 0x00) - */ - 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, +unsigned char lvl_palette[256][3] = { + /* The first two RGB values represent the colorkey (changed accordingly later) */ + { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, }, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x04, 0x00, 0x00, 0x04, 0x10, 0x08, 0x10, 0x00, 0x08, 0x10, 0x10, - 0x18, 0x10, 0x00, 0x18, 0x14, 0x10, 0x00, 0x08, 0x29, 0x00, 0x0c, 0x39, - 0x10, 0x14, 0x20, 0x18, 0x18, 0x20, 0x08, 0x20, 0x08, 0x08, 0x24, 0x29, - 0x18, 0x28, 0x39, 0x29, 0x10, 0x08, 0x20, 0x24, 0x00, 0x20, 0x24, 0x10, - 0x31, 0x24, 0x00, 0x31, 0x24, 0x00, 0x31, 0x34, 0x00, 0x31, 0x34, 0x10, - 0x20, 0x20, 0x20, 0x29, 0x24, 0x20, 0x20, 0x34, 0x29, 0x31, 0x30, 0x29, - 0x31, 0x30, 0x39, 0x00, 0x0c, 0x4a, 0x62, 0x65, 0x08, 0x73, 0x6d, 0x52, - 0x73, 0x00, 0xb4, 0x94, 0x38, 0x20, 0xa4, 0x65, 0x39, 0x31, 0x34, 0x4a, - 0x29, 0x34, 0x62, 0x08, 0x44, 0x10, 0x00, 0x65, 0x00, 0x29, 0x59, 0x39, - 0x31, 0x7d, 0x39, 0x29, 0x48, 0x6a, 0x4a, 0x0c, 0x08, 0x41, 0x2c, 0x00, - 0x41, 0x28, 0x10, 0x52, 0x2c, 0x10, 0x52, 0x3c, 0x10, 0x4a, 0x38, 0x29, - 0x41, 0x3c, 0x39, 0x62, 0x1c, 0x08, 0x73, 0x08, 0x08, 0x62, 0x3c, 0x10, - 0x7b, 0x20, 0x08, 0x73, 0x34, 0x10, 0x41, 0x3c, 0x4a, 0x41, 0x40, 0x00, - 0x41, 0x40, 0x10, 0x4a, 0x55, 0x00, 0x52, 0x40, 0x00, 0x52, 0x55, 0x08, - 0x52, 0x55, 0x18, 0x52, 0x44, 0x39, 0x5a, 0x59, 0x39, 0x62, 0x44, 0x00, - 0x62, 0x55, 0x00, 0x62, 0x55, 0x18, 0x73, 0x44, 0x10, 0x73, 0x59, 0x00, - 0x73, 0x59, 0x10, 0x62, 0x40, 0x20, 0x62, 0x44, 0x39, 0x73, 0x40, 0x20, - 0x7b, 0x44, 0x20, 0x7b, 0x55, 0x20, 0x7b, 0x59, 0x31, 0x62, 0x65, 0x08, - 0x62, 0x65, 0x18, 0x62, 0x75, 0x18, 0x7b, 0x6d, 0x08, 0x73, 0x6d, 0x18, - 0x7b, 0x7d, 0x08, 0x7b, 0x7d, 0x18, 0x7b, 0x6d, 0x29, 0x7b, 0x7d, 0x29, - 0x4a, 0x48, 0x52, 0x52, 0x50, 0x52, 0x4a, 0x4c, 0x6a, 0x4a, 0x4c, 0x7b, - 0x5a, 0x59, 0x62, 0x4a, 0x71, 0x5a, 0x6a, 0x55, 0x52, 0x73, 0x6d, 0x52, - 0x62, 0x65, 0x62, 0x62, 0x6d, 0x7b, 0x73, 0x71, 0x6a, 0x7b, 0x79, 0x7b, - 0x08, 0x10, 0x94, 0x00, 0x04, 0xac, 0x10, 0x1c, 0xa4, 0x18, 0x20, 0xbd, - 0x20, 0x30, 0x83, 0x00, 0x04, 0xf6, 0x29, 0x30, 0xc5, 0x29, 0x4c, 0x83, - 0x20, 0x40, 0xa4, 0x20, 0x55, 0xc5, 0x20, 0x4c, 0xee, 0x73, 0x00, 0xb4, - 0x4a, 0x4c, 0xac, 0x4a, 0x71, 0x83, 0x52, 0x6d, 0xac, 0x4a, 0x48, 0xcd, - 0x52, 0x4c, 0xee, 0x5a, 0x6d, 0xe6, 0x00, 0x99, 0x00, 0x10, 0xea, 0x08, - 0x4a, 0x85, 0x39, 0x4a, 0xa5, 0xac, 0x7b, 0x85, 0xa4, 0x5a, 0xba, 0xee, - 0x6a, 0x89, 0xee, 0x94, 0x08, 0x08, 0x94, 0x2c, 0x08, 0x94, 0x38, 0x20, - 0xac, 0x0c, 0x08, 0xb4, 0x30, 0x10, 0xb4, 0x34, 0x31, 0x94, 0x50, 0x10, - 0x8b, 0x4c, 0x20, 0x8b, 0x5d, 0x20, 0x8b, 0x5d, 0x31, 0x8b, 0x69, 0x00, - 0x9c, 0x69, 0x08, 0x94, 0x7d, 0x00, 0x94, 0x79, 0x39, 0xac, 0x55, 0x00, - 0xa4, 0x59, 0x20, 0xa4, 0x5d, 0x31, 0xbd, 0x50, 0x20, 0xa4, 0x65, 0x39, - 0xa4, 0x7d, 0x20, 0xac, 0x75, 0x39, 0xbd, 0x65, 0x29, 0xbd, 0x6d, 0x39, - 0x8b, 0x61, 0x4a, 0x9c, 0x79, 0x5a, 0xd5, 0x08, 0x08, 0xd5, 0x30, 0x20, - 0xf6, 0x08, 0x08, 0xf6, 0x28, 0x20, 0xf6, 0x38, 0x39, 0xc5, 0x59, 0x39, - 0xc5, 0x79, 0x29, 0xc5, 0x7d, 0x39, 0xde, 0x7d, 0x31, 0xe6, 0x59, 0x29, - 0xe6, 0x59, 0x52, 0xff, 0x59, 0x52, 0xb4, 0x24, 0xbd, 0x8b, 0x81, 0x10, - 0x94, 0x95, 0x00, 0x8b, 0x81, 0x20, 0x9c, 0x99, 0x20, 0xa4, 0x81, 0x00, - 0xa4, 0x81, 0x10, 0xac, 0x9d, 0x00, 0xbd, 0x81, 0x08, 0xac, 0x99, 0x20, - 0xb4, 0xae, 0x18, 0xa4, 0xaa, 0x20, 0xb4, 0xae, 0x29, 0xbd, 0xb6, 0x39, - 0x94, 0x81, 0x73, 0xa4, 0x99, 0x41, 0xbd, 0x99, 0x5a, 0xb4, 0x8d, 0x73, - 0xbd, 0xaa, 0x73, 0xc5, 0x9d, 0x00, 0xcd, 0x99, 0x20, 0xcd, 0xb6, 0x00, - 0xc5, 0xb6, 0x29, 0xd5, 0xba, 0x20, 0xde, 0xba, 0x39, 0xff, 0x99, 0x00, - 0xe6, 0xae, 0x00, 0xc5, 0x81, 0x4a, 0xc5, 0x95, 0x41, 0xd5, 0x99, 0x41, - 0xd5, 0x99, 0x52, 0xde, 0x85, 0x73, 0xd5, 0xaa, 0x5a, 0xd5, 0xb2, 0x6a, - 0xd5, 0xb6, 0x7b, 0xe6, 0x81, 0x52, 0xf6, 0x85, 0x73, 0xee, 0xa5, 0x5a, - 0xf6, 0xb2, 0x73, 0xd5, 0xce, 0x00, 0xd5, 0xca, 0x31, 0xd5, 0xd2, 0x20, - 0xde, 0xda, 0x39, 0xf6, 0xd2, 0x00, 0xff, 0xf2, 0x00, 0xee, 0xee, 0x20, - 0xf6, 0xf2, 0x39, 0xd5, 0xca, 0x41, 0xde, 0xda, 0x4a, 0xee, 0xde, 0x52, - 0xf6, 0xde, 0x73, 0xee, 0xe2, 0x41, 0xf6, 0xf2, 0x52, 0x8b, 0x89, 0x83, - 0x94, 0x95, 0x9c, 0x8b, 0x99, 0xb4, 0xb4, 0xa5, 0x94, 0xa4, 0xa5, 0xac, - 0xb4, 0xb2, 0xb4, 0xbe, 0xbd, 0xbe, 0x94, 0x91, 0xf6, 0xac, 0xb6, 0xd5, - 0xac, 0xb2, 0xff, 0xbd, 0xd2, 0xee, 0xd5, 0xb6, 0x94, 0xcd, 0xba, 0xb4, - 0xf6, 0x99, 0x94, 0xf6, 0xba, 0x9c, 0xde, 0xca, 0x8b, 0xde, 0xce, 0xa4, - 0xde, 0xd2, 0xb4, 0xff, 0xde, 0x94, 0xf6, 0xda, 0xbd, 0xff, 0xfa, 0xbd, - 0xcd, 0xca, 0xcd, 0xde, 0xda, 0xcd, 0xde, 0xda, 0xde, 0xd5, 0xf6, 0xff, - 0xe6, 0xe2, 0xee, 0xf6, 0xf2, 0xe6, 0xff, 0xfa, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00 }, + { 0x08, 0x04, 0x00 }, { 0x00, 0x04, 0x10 }, { 0x08, 0x10, 0x00 }, { 0x08, 0x10, 0x10 }, + { 0x18, 0x10, 0x00 }, { 0x18, 0x14, 0x10 }, { 0x00, 0x08, 0x29 }, { 0x00, 0x0c, 0x39 }, + { 0x10, 0x14, 0x20 }, { 0x18, 0x18, 0x20 }, { 0x08, 0x20, 0x08 }, { 0x08, 0x24, 0x29 }, + { 0x18, 0x28, 0x39 }, { 0x29, 0x10, 0x08 }, { 0x20, 0x24, 0x00 }, { 0x20, 0x24, 0x10 }, + { 0x31, 0x24, 0x00 }, { 0x31, 0x24, 0x00 }, { 0x31, 0x34, 0x00 }, { 0x31, 0x34, 0x10 }, + { 0x20, 0x20, 0x20 }, { 0x29, 0x24, 0x20 }, { 0x20, 0x34, 0x29 }, { 0x31, 0x30, 0x29 }, + { 0x31, 0x30, 0x39 }, { 0x00, 0x0c, 0x4a }, { 0x62, 0x65, 0x08 }, { 0x73, 0x6d, 0x52 }, + { 0x73, 0x00, 0xb4 }, { 0x94, 0x38, 0x20 }, { 0xa4, 0x65, 0x39 }, { 0x31, 0x34, 0x4a }, + { 0x29, 0x34, 0x62 }, { 0x08, 0x44, 0x10 }, { 0x00, 0x65, 0x00 }, { 0x29, 0x59, 0x39 }, + { 0x31, 0x7d, 0x39 }, { 0x29, 0x48, 0x6a }, { 0x4a, 0x0c, 0x08 }, { 0x41, 0x2c, 0x00 }, + { 0x41, 0x28, 0x10 }, { 0x52, 0x2c, 0x10 }, { 0x52, 0x3c, 0x10 }, { 0x4a, 0x38, 0x29 }, + { 0x41, 0x3c, 0x39 }, { 0x62, 0x1c, 0x08 }, { 0x73, 0x08, 0x08 }, { 0x62, 0x3c, 0x10 }, + { 0x7b, 0x20, 0x08 }, { 0x73, 0x34, 0x10 }, { 0x41, 0x3c, 0x4a }, { 0x41, 0x40, 0x00 }, + { 0x41, 0x40, 0x10 }, { 0x4a, 0x55, 0x00 }, { 0x52, 0x40, 0x00 }, { 0x52, 0x55, 0x08 }, + { 0x52, 0x55, 0x18 }, { 0x52, 0x44, 0x39 }, { 0x5a, 0x59, 0x39 }, { 0x62, 0x44, 0x00 }, + { 0x62, 0x55, 0x00 }, { 0x62, 0x55, 0x18 }, { 0x73, 0x44, 0x10 }, { 0x73, 0x59, 0x00 }, + { 0x73, 0x59, 0x10 }, { 0x62, 0x40, 0x20 }, { 0x62, 0x44, 0x39 }, { 0x73, 0x40, 0x20 }, + { 0x7b, 0x44, 0x20 }, { 0x7b, 0x55, 0x20 }, { 0x7b, 0x59, 0x31 }, { 0x62, 0x65, 0x08 }, + { 0x62, 0x65, 0x18 }, { 0x62, 0x75, 0x18 }, { 0x7b, 0x6d, 0x08 }, { 0x73, 0x6d, 0x18 }, + { 0x7b, 0x7d, 0x08 }, { 0x7b, 0x7d, 0x18 }, { 0x7b, 0x6d, 0x29 }, { 0x7b, 0x7d, 0x29 }, + { 0x4a, 0x48, 0x52 }, { 0x52, 0x50, 0x52 }, { 0x4a, 0x4c, 0x6a }, { 0x4a, 0x4c, 0x7b }, + { 0x5a, 0x59, 0x62 }, { 0x4a, 0x71, 0x5a }, { 0x6a, 0x55, 0x52 }, { 0x73, 0x6d, 0x52 }, + { 0x62, 0x65, 0x62 }, { 0x62, 0x6d, 0x7b }, { 0x73, 0x71, 0x6a }, { 0x7b, 0x79, 0x7b }, + { 0x08, 0x10, 0x94 }, { 0x00, 0x04, 0xac }, { 0x10, 0x1c, 0xa4 }, { 0x18, 0x20, 0xbd }, + { 0x20, 0x30, 0x83 }, { 0x00, 0x04, 0xf6 }, { 0x29, 0x30, 0xc5 }, { 0x29, 0x4c, 0x83 }, + { 0x20, 0x40, 0xa4 }, { 0x20, 0x55, 0xc5 }, { 0x20, 0x4c, 0xee }, { 0x73, 0x00, 0xb4 }, + { 0x4a, 0x4c, 0xac }, { 0x4a, 0x71, 0x83 }, { 0x52, 0x6d, 0xac }, { 0x4a, 0x48, 0xcd }, + { 0x52, 0x4c, 0xee }, { 0x5a, 0x6d, 0xe6 }, { 0x00, 0x99, 0x00 }, { 0x10, 0xea, 0x08 }, + { 0x4a, 0x85, 0x39 }, { 0x4a, 0xa5, 0xac }, { 0x7b, 0x85, 0xa4 }, { 0x5a, 0xba, 0xee }, + /* check below */ + { 0x6a, 0x89, 0xee }, { 0x94, 0x08, 0x08 }, { 0x94, 0x2c, 0x08 }, { 0x94, 0x38, 0x20 }, + { 0xac, 0x0c, 0x08 }, { 0xb4, 0x30, 0x10 }, { 0xb4, 0x34, 0x31 }, { 0x94, 0x50, 0x10 }, + { 0x8b, 0x4c, 0x20 }, { 0x8b, 0x5d, 0x20 }, { 0x8b, 0x5d, 0x31 }, { 0x8b, 0x69, 0x00 }, + { 0x9c, 0x69, 0x08 }, { 0x94, 0x7d, 0x00 }, { 0x94, 0x79, 0x39 }, { 0xac, 0x55, 0x00 }, + { 0xa4, 0x59, 0x20 }, { 0xa4, 0x5d, 0x31 }, { 0xbd, 0x50, 0x20 }, { 0xa4, 0x65, 0x39 }, + { 0xa4, 0x7d, 0x20 }, { 0xac, 0x75, 0x39 }, { 0xbd, 0x65, 0x29 }, { 0xbd, 0x6d, 0x39 }, + { 0x8b, 0x61, 0x4a }, { 0x9c, 0x79, 0x5a }, { 0xd5, 0x08, 0x08 }, { 0xd5, 0x30, 0x20 }, + { 0xf6, 0x08, 0x08 }, { 0xf6, 0x28, 0x20 }, { 0xf6, 0x38, 0x39 }, { 0xc5, 0x59, 0x39 }, + { 0xc5, 0x79, 0x29 }, { 0xc5, 0x7d, 0x39 }, { 0xde, 0x7d, 0x31 }, { 0xe6, 0x59, 0x29 }, + { 0xe6, 0x59, 0x52 }, { 0xff, 0x59, 0x52 }, { 0xb4, 0x24, 0xbd }, { 0x8b, 0x81, 0x10 }, + { 0x94, 0x95, 0x00 }, { 0x8b, 0x81, 0x20 }, { 0x9c, 0x99, 0x20 }, { 0xa4, 0x81, 0x00 }, + { 0xa4, 0x81, 0x10 }, { 0xac, 0x9d, 0x00 }, { 0xbd, 0x81, 0x08 }, { 0xac, 0x99, 0x20 }, + { 0xb4, 0xae, 0x18 }, { 0xa4, 0xaa, 0x20 }, { 0xb4, 0xae, 0x29 }, { 0xbd, 0xb6, 0x39 }, + { 0x94, 0x81, 0x73 }, { 0xa4, 0x99, 0x41 }, { 0xbd, 0x99, 0x5a }, { 0xb4, 0x8d, 0x73 }, + { 0xbd, 0xaa, 0x73 }, { 0xc5, 0x9d, 0x00 }, { 0xcd, 0x99, 0x20 }, { 0xcd, 0xb6, 0x00 }, + { 0xc5, 0xb6, 0x29 }, { 0xd5, 0xba, 0x20 }, { 0xde, 0xba, 0x39 }, { 0xff, 0x99, 0x00 }, + { 0xe6, 0xae, 0x00 }, { 0xc5, 0x81, 0x4a }, { 0xc5, 0x95, 0x41 }, { 0xd5, 0x99, 0x41 }, + { 0xd5, 0x99, 0x52 }, { 0xde, 0x85, 0x73 }, { 0xd5, 0xaa, 0x5a }, { 0xd5, 0xb2, 0x6a }, + { 0xd5, 0xb6, 0x7b }, { 0xe6, 0x81, 0x52 }, { 0xf6, 0x85, 0x73 }, { 0xee, 0xa5, 0x5a }, + { 0xf6, 0xb2, 0x73 }, { 0xd5, 0xce, 0x00 }, { 0xd5, 0xca, 0x31 }, { 0xd5, 0xd2, 0x20 }, + { 0xde, 0xda, 0x39 }, { 0xf6, 0xd2, 0x00 }, { 0xff, 0xf2, 0x00 }, { 0xee, 0xee, 0x20 }, + { 0xf6, 0xf2, 0x39 }, { 0xd5, 0xca, 0x41 }, { 0xde, 0xda, 0x4a }, { 0xee, 0xde, 0x52 }, + { 0xf6, 0xde, 0x73 }, { 0xee, 0xe2, 0x41 }, { 0xf6, 0xf2, 0x52 }, { 0x8b, 0x89, 0x83 }, + { 0x94, 0x95, 0x9c }, { 0x8b, 0x99, 0xb4 }, { 0xb4, 0xa5, 0x94 }, { 0xa4, 0xa5, 0xac }, + { 0xb4, 0xb2, 0xb4 }, { 0xbe, 0xbd, 0xbe }, { 0x94, 0x91, 0xf6 }, { 0xac, 0xb6, 0xd5 }, + { 0xac, 0xb2, 0xff }, { 0xbd, 0xd2, 0xee }, { 0xd5, 0xb6, 0x94 }, { 0xcd, 0xba, 0xb4 }, + { 0xf6, 0x99, 0x94 }, { 0xf6, 0xba, 0x9c }, { 0xde, 0xca, 0x8b }, { 0xde, 0xce, 0xa4 }, + { 0xde, 0xd2, 0xb4 }, { 0xff, 0xde, 0x94 }, { 0xf6, 0xda, 0xbd }, { 0xff, 0xfa, 0xbd }, + { 0xcd, 0xca, 0xcd }, { 0xde, 0xda, 0xcd }, { 0xde, 0xda, 0xde }, { 0xd5, 0xf6, 0xff }, + { 0xe6, 0xe2, 0xee }, { 0xf6, 0xf2, 0xe6 }, { 0xff, 0xfa, 0xff }, { 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00 } }; +void usage() { + printf("Usage: lvl2magick [options] file.lvl\n"); + printf("Extracts images from file.lvl.\n"); + printf("\n"); + printf("Options:\n"); + printf(" -h, --help Print this help message\n"); + printf(" -debug Create additional files if n>0 (default: 0)\n"); + printf(" -colorkey \"#rrggbb\" Use the specified color for the colorkey. The numbers\n"); + printf(" rr, gg, bb are hex values from 0 to ff. (default: #ff00ff)\n"); + printf(" -bg \"#rrggbb\" Use the specified color for the background (default: colorkey)\n"); + printf(" -dir, -o Name of the output directory (default: file)\n"); + printf(" -format Name of the output image format (default: png)\n"); + printf(" -data_file Data filename for file.lvl (default: file.dat)\n"); +} + +int parse(int argc, char* argv[]) { + int i; + char buf[20]; + + /* default settings */ + strncpy(config.lvl_file,"",16); + strncpy(config.data_file,"",16); + strncpy(config.basename,"",16); + strncpy(config.format,"png",4); + config.debug=0; + config.colorkey.red=MaxRGB; + config.colorkey.green=0; + config.colorkey.blue=MaxRGB; + config.colorkey.opacity=0; + config.bg.red=config.colorkey.red; + config.bg.green=config.colorkey.green; + config.bg.blue=config.colorkey.blue; + config.bg.opacity=config.colorkey.opacity; + + /* parse cmdline */ + for (i=1; icolumns=width; image->rows=height; - t=image->matte_color; - t.red=MaxRGB; - t.green=0; - t.blue=MaxRGB; - image->matte_color=t; + image->matte_color=config.colorkey; p=ptr; for (y=0; y < image->rows; y++) { @@ -140,9 +290,17 @@ int main(int argc, char *argv[]) { - FILE *lvl_file, *unknown_file, *append_file; - char dirname[16], buf[100]; + /* ImageMagick stuff */ + Image* image_list=NULL; + ImageInfo *image_info=NULL; + MontageInfo montage_info; + ExceptionInfo exception; + Image *big_image, *tmp_img; + const char entry_id[]="TRPS"; + unsigned int data_size, num_entries, unknown=0; + FILE *lvl_file, *data_file, *unknown_file, *geom_file; + /* Initial start pointer to the beginning of the file */ unsigned char *data; /* Temporary variable to indicate the last offset to start searching from: @@ -154,37 +312,25 @@ unsigned char *off_ptr; /* temporary variables */ + char buf[20]; struct stat sb; - unsigned int i=0; - unsigned int width,height; + unsigned int i,width,height,x_off=0; - const char entry_id[]="TRPS"; - char type[]="png"; - int debug=0; - unsigned int data_size; - unsigned int num_entries; - unsigned int unknown=0; + /* -------------------------------------------------------------------- */ - unsigned int x_off=0; - Image* image_list=NULL; - ImageInfo *image_info=NULL; - MontageInfo montage_info; - ExceptionInfo exception; - Image *big_image, *tmp_img; - register PixelPacket colorkey; + /* parse command line options and set config */ + i=parse(argc,argv); - /* -------------------------------------------------------------------- */ + if (i==errno_quit) return errno_ok; + else if (i==errno_parse) return errno_parse; + else if (i!=errno_ok) return i; - if (argc < 2) { - printf("Usage: %s input.lvl [destination]\n", argv[0]); - return 1; - } - - lvl_file = fopen(argv[1],"r"); + /* Check lvl_file */ + lvl_file = fopen(config.lvl_file,"r"); if (lvl_file == NULL) { - perror("Error opening file"); - return 1; + printf("Error opening file\n"); + return errno_open; } fread(buf,1,12,lvl_file); @@ -193,44 +339,32 @@ (buf[2] != 'T') && (buf[3] != 'A')) { printf("Invalid file\n"); fclose(lvl_file); - return 1; + return errno_invalid; } /* get file size */ fstat(fileno(lvl_file), &sb); data_size = sb.st_size; - /* Get directory name and create directory */ - if (argc > 2) { - strncpy(dirname, argv[1], 16); - } else { - /* copy the filename */ - if (strrchr(argv[1], '/')) strncpy(dirname, strrchr(argv[1], '/')+1, 16); - else strncpy(dirname, argv[1], 16); + /* Check data_file */ + data_file = fopen(config.data_file,"r"); - /* truncate filename at . */ - if (strrchr(dirname, '.')) { - char *loc = strrchr(dirname, '.'); - *loc = 0; - } - } - mkdir(dirname, 0777); - chdir(dirname); - printf("Directory: %s\n", dirname); + if (data_file == NULL) printf("No data file %s found!\n",config.data_file); + /* Change to the base directory */ + mkdir(config.basename, 0777); + chdir(config.basename); + printf("Directory: %s\n", config.basename); + /* Create file for image informations */ - snprintf(buf,16,"%s.txt",dirname); - append_file = fopen(buf,"w"); - append_file = freopen(buf,"a",append_file); + snprintf(buf,16,"%s.txt",config.basename); + geom_file = fopen(buf,"w"); + geom_file = freopen(buf,"a",geom_file); /* ImageMagick stuff */ image_list=NewImageList(); image_info=CloneImageInfo((ImageInfo *) NULL); image_info->colorspace = RGBColorspace; - colorkey.red=MaxRGB; - colorkey.green=0; - colorkey.blue=MaxRGB; - colorkey.opacity=0; /* Map the entire file into process memory space */ data = mmap(NULL, data_size, PROT_READ, MAP_PRIVATE, fileno(lvl_file), 0); @@ -267,8 +401,8 @@ * Write unknown content (up to this image position (off_ptr)) to a file. * If the file size would be 0, skip it. */ - if (debug && (off_ptr-save_ptr > 0)) { - snprintf(buf, 100, "%08d.bin", i); + if (config.debug && (off_ptr-save_ptr > 0)) { + snprintf(buf, 16, "%08d.bin", i); unknown_file = fopen(buf, "wb"); fwrite(save_ptr,1,(off_ptr-save_ptr),unknown_file); fclose(unknown_file); @@ -285,7 +419,7 @@ /* update last_ptr, get the image and append it to the list */ tmp_img=write_magick(off_ptr+12,image_info,width,height); - snprintf(buf,100,"%08d.%s",i,type); + snprintf(buf,16,"%08d.%s",i,config.format); strcpy(tmp_img->filename,buf); AppendImageToList(&image_list,tmp_img); @@ -302,32 +436,40 @@ GetExceptionInfo(&exception); montage_info.tile="3000x1"; montage_info.geometry="+0+0"; - montage_info.background_color=colorkey; - montage_info.matte_color=colorkey; + montage_info.background_color=config.bg; + montage_info.matte_color=config.colorkey; montage_info.gravity=NorthWestGravity; big_image=MontageImages(image_list,&montage_info,&exception); - big_image->matte_color=colorkey; + big_image->matte_color=config.colorkey; - snprintf(buf, 100, "%s.%s",dirname,type); + snprintf(buf, 16, "%s.%s",config.basename,config.format); strcpy(big_image->filename,buf); WriteImage(image_info,big_image); DestroyImage(big_image); - fprintf(append_file,"%d\n",num_entries); + /* Create geom_file */ + fprintf(geom_file,"%d\n",num_entries); for (i=0; i Author: jonas Date: 2005-03-19 12:04:32 -0500 (Sat, 19 Mar 2005) New Revision: 105 Modified: trunk/tools/Makefile trunk/tools/lvl_tools/Makefile trunk/tools/lvl_tools/lvl2magick.c Log: Almost finnished the lvl2magick tool. It now uses an image data file (if present) to separate animations. Lot's of fixes and/or improvements. Additionaly: Removed compiler warnings (splint +weak +posixlib has even 0 warnings). Modified: trunk/tools/Makefile =================================================================== --- trunk/tools/Makefile 2005-03-18 12:52:51 UTC (rev 104) +++ trunk/tools/Makefile 2005-03-19 17:04:32 UTC (rev 105) @@ -1,5 +1,5 @@ CXX = g++ -CXX_FLAGS = -W -Wall -ansi -pedantic +CXX_FLAGS = -W -Wall -pedantic CXX_DEBUG = -g #-fno-inline CXX_OPT = -O2 -march=pentium4 -ffast-math CXX_GAME = -DSDL_MIXER -DSDL_IMAGE -DALPHA Modified: trunk/tools/lvl_tools/Makefile =================================================================== --- trunk/tools/lvl_tools/Makefile 2005-03-18 12:52:51 UTC (rev 104) +++ trunk/tools/lvl_tools/Makefile 2005-03-19 17:04:32 UTC (rev 105) @@ -1,5 +1,5 @@ CC = gcc -CC_FLAGS = -ansi -pedantic -W -Wall +CC_FLAGS = -pedantic -W -Wall CC_DEBUG = -g #-fno-inline CC_OPT = -O2 -march=pentium4 -ffast-math CC_TOOL = -lpng Modified: trunk/tools/lvl_tools/lvl2magick.c =================================================================== --- trunk/tools/lvl_tools/lvl2magick.c 2005-03-18 12:52:51 UTC (rev 104) +++ trunk/tools/lvl_tools/lvl2magick.c 2005-03-19 17:04:32 UTC (rev 105) @@ -8,12 +8,15 @@ #include #include +#include #include -#include #include #include +#include #include +#define EXIT(a) { errno=(a); goto end; } + enum { red=0, green=1, @@ -21,24 +24,34 @@ }; enum { - img_x=0, - img_y=1, - img_w=2, - img_h=3 -}; - -enum { errno_ok=0, errno_quit=1, errno_parse=2, errno_open=3, errno_invalid=4, - errno_misc=5 + errno_alloc=5, + errno_misc=6 }; -struct config_s { +typedef struct { + unsigned int x; + unsigned int y; + unsigned int w; + unsigned int h; +} Rectangle; + +typedef struct { + unsigned int start_num; + unsigned int size; + char name[32]; + Rectangle* geometry; +} LVLAnim; + +typedef struct { /* create unknown.bin chunk files if != 0 */ int debug; + /* Write the individial animations */ + int write; /* input lvl file */ char lvl_file[20]; /* input data file */ @@ -53,8 +66,11 @@ PixelPacket colorkey; /* background color */ PixelPacket bg; -} config; +} Config; +Config config; +int errno=errno_ok; + /* RGB palette */ unsigned char lvl_palette[256][3] = { /* The first two RGB values represent the colorkey (changed accordingly later) */ @@ -130,17 +146,22 @@ void usage() { printf("Usage: lvl2magick [options] file.lvl\n"); - printf("Extracts images from file.lvl.\n"); - printf("\n"); + printf("Extracts images from file.lvl.\n\n\n"); printf("Options:\n"); - printf(" -h, --help Print this help message\n"); - printf(" -debug Create additional files if n>0 (default: 0)\n"); - printf(" -colorkey \"#rrggbb\" Use the specified color for the colorkey. The numbers\n"); - printf(" rr, gg, bb are hex values from 0 to ff. (default: #ff00ff)\n"); - printf(" -bg \"#rrggbb\" Use the specified color for the background (default: colorkey)\n"); - printf(" -dir, -o Name of the output directory (default: file)\n"); - printf(" -format Name of the output image format (default: png)\n"); - printf(" -data_file Data filename for file.lvl (default: file.dat)\n"); + printf(" -h, --help Print this help message\n\n"); + printf(" -debug Create additional debug files (default: off)\n\n"); + printf(" -write <0-7> n=0: Just create the geometry data (no images)\n"); + printf(" n=1: Create one big image with all animations in it\n"); + printf(" n=2: Create one image for each animation\n"); + printf(" n=4: Create one image for each frame\n"); + printf(" Values can be added to achieve the desired combination\n"); + printf(" (default: 3)\n\n"); + printf(" -colorkey \"#rrggbb\" Use the specified color for the colorkey. The numbers\n"); + printf(" rr, gg, bb are hex values from 0 to ff. (default: #ff00ff)\n\n"); + printf(" -bg \"#rrggbb\" Use the specified color for the background (default: colorkey)\n\n"); + printf(" -dir, -o Name of the output directory (default: file)\n\n"); + printf(" -format Name of the output image format (default: png)\n\n"); + printf(" -data_file Data filename for file.lvl (default: file.dat)\n\n"); } int parse(int argc, char* argv[]) { @@ -153,6 +174,7 @@ strncpy(config.basename,"",16); strncpy(config.format,"png",4); config.debug=0; + config.write=3; config.colorkey.red=MaxRGB; config.colorkey.green=0; config.colorkey.blue=MaxRGB; @@ -169,18 +191,24 @@ usage(); return errno_quit; } else if (strcmp(argv[i],"-debug")==0) { + config.debug=1; + } else if (strcmp(argv[i],"-write")==0) { i++; if (strncmp(argv[i],"-",1)==0) { usage(); return errno_parse; } - config.debug=atoi(argv[i]); + config.write=atoi(argv[i]); + if (config.write>7 || config.write<0) { + usage(); + return errno_parse; + } } else if (strcmp(argv[i],"-colorkey")==0) { i++; if (!strncmp(argv[i],"#",1)==0) { usage(); return errno_parse; } strcpy(buf,argv[i]+1); buf[2]=0; - config.colorkey.red=MaxRGB*strtol(buf,NULL,16)/255; + config.colorkey.red=(Quantum)(MaxRGB*strtol(buf,NULL,16)/255); strcpy(buf,argv[i]+3); buf[2]=0; - config.colorkey.green=MaxRGB*strtol(buf,NULL,16)/255; + config.colorkey.green=(Quantum)(MaxRGB*strtol(buf,NULL,16)/255); strcpy(buf,argv[i]+5); buf[2]=0; - config.colorkey.blue=MaxRGB*strtol(buf,NULL,16)/255; + config.colorkey.blue=(Quantum)(MaxRGB*strtol(buf,NULL,16)/255); config.bg.blue=config.colorkey.blue; config.bg.red=config.colorkey.red; config.bg.green=config.colorkey.green; @@ -188,11 +216,11 @@ i++; if (strncmp(argv[i],"#",1)==0) { strcpy(buf,argv[i]+1); buf[2]=0; - config.bg.red=MaxRGB*strtol(buf,NULL,16)/255; + config.bg.red=(Quantum)(MaxRGB*strtol(buf,NULL,16)/255); strcpy(buf,argv[i]+3); buf[2]=0; - config.bg.green=MaxRGB*strtol(buf,NULL,16)/255; + config.bg.green=(Quantum)(MaxRGB*strtol(buf,NULL,16)/255); strcpy(buf,argv[i]+5); buf[2]=0; - config.bg.blue=MaxRGB*strtol(buf,NULL,16)/255; + config.bg.blue=(Quantum)(MaxRGB*strtol(buf,NULL,16)/255); config.bg.opacity=0; } else { usage(); @@ -239,31 +267,117 @@ } } if (strcmp(config.data_file,"")==0) { - sprintf(config.data_file,"%s.dat",config.basename); + snprintf(config.data_file,16,"%s.dat",config.basename); } - sprintf(config.geom_file,"%s.txt",config.basename); + snprintf(config.geom_file,16,"%s.txt",config.basename); /* set colorkey in palette */ - lvl_palette[0][red] = config.colorkey.red*255/MaxRGB; - lvl_palette[0][green] = config.colorkey.green*255/MaxRGB; - lvl_palette[0][blue] = config.colorkey.blue*255/MaxRGB; - lvl_palette[1][red] = config.colorkey.red*255/MaxRGB; - lvl_palette[1][green] = config.colorkey.green*255/MaxRGB; - lvl_palette[1][blue] = config.colorkey.blue*255/MaxRGB; + lvl_palette[0][red] = (unsigned char)(config.colorkey.red*255/MaxRGB); + lvl_palette[0][green] = (unsigned char)(config.colorkey.green*255/MaxRGB); + lvl_palette[0][blue] = (unsigned char)(config.colorkey.blue*255/MaxRGB); + lvl_palette[1][red] = (unsigned char)(config.colorkey.red*255/MaxRGB); + lvl_palette[1][green] = (unsigned char)(config.colorkey.green*255/MaxRGB); + lvl_palette[1][blue] = (unsigned char)(config.colorkey.blue*255/MaxRGB); return errno_ok; } +void freeLVLAnimList(LVLAnim* lvlanims,unsigned int size) { + unsigned int i; + for (i=0; i< size; i++) { + if (lvlanims[i].geometry!=NULL) free(lvlanims[i].geometry); + } + free(lvlanims); +} + +/* Parses the specified data file and stores the result (array of LVLAnim) in + * lvlanims. The return value is the size of the array (number of animations). + * Usage: anim_size=parseDataFile("image.dat",&lvlanims); + * + * Data file Format: + * + * ----------------- + * LVLDATA + * + * start_offset size name + * ... + * + * ----------------- + * + * start_offset is the image index off all images in the file + * size is the number of frames of the animation + * name is the unique name of the animation + * + */ +unsigned int parseDataFile(char* data_file_name, LVLAnim** lvlanims) { + const char data_id[]="LVLDATA"; + unsigned int start_num, size, data_size=0; + char name[32], line[80]; + int match=0; + unsigned int i=0; + + FILE* data_file = fopen(data_file_name,"r"); + *lvlanims=NULL; + + if (data_file == NULL) { + printf("Data file %s not found!\n",data_file_name); + return 0; + } + + if (!fgets(line,80,data_file) || strncmp(line,data_id,7)) { + printf("Data file %s is invalid!!\n",data_file_name); + fclose(data_file); + return 0; + } + + /* get the number of entries */ + while (fgets(line,80,data_file)) { + match=sscanf(line, "%u %u %s\n", &start_num, &size, name); + if (match==3) data_size++; + } + if (data_size==0) { + printf("Data file %s is invalid (no entries)!\n",data_file_name); + fclose(data_file); + return 0; + } + /* rewind to the beginning */ + rewind(data_file); + (void)fgets(line,80,data_file); + + /* allocate memory */ + if ((*lvlanims=(LVLAnim*)malloc(data_size*sizeof(LVLAnim))) == NULL) { + printf("Memory allocation of LVLAnim* failed! Couldn't read data file %s!\n", data_file_name); + *lvlanims=NULL; + return 0; + } + + i=0; + while (fgets(line,80,data_file)) { + match=sscanf(line, "%u %u %s\n", &start_num, &size, name); + if (match!=3) continue; + (*lvlanims)[i].start_num=start_num; + (*lvlanims)[i].size=size; + strncpy((*lvlanims)[i].name,name,32); + + (*lvlanims)[i].geometry=NULL; + i++; + } + + fclose(data_file); + return data_size; +} + + /* * Create an ImageMagick image of size width x height * * image_info is an initialized ImageMagick ImageInfo* ptr * ptr is the pointer to the image data offset */ -Image* write_magick(unsigned char* ptr, ImageInfo* image_info, unsigned int width, unsigned int height) { +Image* getFrame(unsigned char* ptr, ImageInfo* image_info, unsigned int width, unsigned int height) { Image* image; - unsigned int y; - register unsigned int x; + unsigned long int y; + register unsigned long int x; register PixelPacket *q; register unsigned char *p; @@ -274,12 +388,12 @@ p=ptr; for (y=0; y < image->rows; y++) { - q=SetImagePixels(image,0,y,image->columns,1); + q=SetImagePixels(image,0,(long int)y,image->columns,1); if (q == (PixelPacket *) NULL) break; for (x=0; x < image->columns; x++) { - q->red=MaxRGB*(lvl_palette[*p][red])/255; - q->green=MaxRGB*(lvl_palette[*p][green])/255; - q->blue=MaxRGB*(lvl_palette[*p][blue])/255; + q->red=(Quantum)(MaxRGB*(lvl_palette[*p][red])/255); + q->green=(Quantum)(MaxRGB*(lvl_palette[*p][green])/255); + q->blue=(Quantum)(MaxRGB*(lvl_palette[*p][blue])/255); p++; q++; } @@ -288,21 +402,28 @@ return image; } - int main(int argc, char *argv[]) { /* ImageMagick stuff */ - Image* image_list=NULL; + Image *image_list=NULL, *anim_list=NULL; ImageInfo *image_info=NULL; - MontageInfo montage_info; + MontageInfo montage_info, montage_anim_info; ExceptionInfo exception; - Image *big_image, *tmp_img; + Image *big_image=NULL, *anim_image=NULL, *tmp_image=NULL; + /* temporary variables */ + char buf[20]; + struct stat sb; + unsigned int i,j,width,height,x_off=0,y_off=0,maxh=0; + int d_exception=0; + const char entry_id[]="TRPS"; - unsigned int data_size, num_entries, unknown=0; - FILE *lvl_file, *data_file, *unknown_file, *geom_file; + unsigned int data_size=0, tot_entries=0, num_entries=0, unknown=0; + FILE *lvl_file=NULL, *unknown_file=NULL, *geom_file=NULL; + LVLAnim* lvlanims=NULL; + unsigned int lvlanim_size=0; /* Initial start pointer to the beginning of the file */ - unsigned char *data; + unsigned char *data=NULL; /* Temporary variable to indicate the last offset to start searching from: * Either after (1+) an invalid "T" or after the image of a valid "TRPS" */ unsigned char *last_ptr; @@ -311,46 +432,47 @@ /* Iterates through all offsets at a "T" */ unsigned char *off_ptr; - /* temporary variables */ - char buf[20]; - struct stat sb; - unsigned int i,width,height,x_off=0; + const unsigned int img_off_size_step=32; + unsigned int img_off_size=0; + unsigned char **img_offsets=NULL; + unsigned char **tmp=NULL; /* -------------------------------------------------------------------- */ /* parse command line options and set config */ - i=parse(argc,argv); + errno=parse(argc,argv); - if (i==errno_quit) return errno_ok; - else if (i==errno_parse) return errno_parse; - else if (i!=errno_ok) return i; + if (errno==errno_quit) + EXIT(errno_ok) + else if (errno==errno_parse) + EXIT(errno_parse) + else if (errno!=errno_ok) + EXIT(errno) /* Check lvl_file */ lvl_file = fopen(config.lvl_file,"r"); if (lvl_file == NULL) { printf("Error opening file\n"); - return errno_open; + EXIT(errno_open) } - fread(buf,1,12,lvl_file); + (void)fread(buf,1,12,lvl_file); if ((buf[0] != 'D') && (buf[1] != 'A') && (buf[2] != 'T') && (buf[3] != 'A')) { printf("Invalid file\n"); fclose(lvl_file); - return errno_invalid; + EXIT(errno_invalid) } /* get file size */ fstat(fileno(lvl_file), &sb); - data_size = sb.st_size; + data_size = (unsigned int)(sb.st_size); /* Check data_file */ - data_file = fopen(config.data_file,"r"); + lvlanim_size=parseDataFile(config.data_file, &lvlanims); - if (data_file == NULL) printf("No data file %s found!\n",config.data_file); - /* Change to the base directory */ mkdir(config.basename, 0777); chdir(config.basename); @@ -361,69 +483,44 @@ geom_file = fopen(buf,"w"); geom_file = freopen(buf,"a",geom_file); - /* ImageMagick stuff */ - image_list=NewImageList(); - image_info=CloneImageInfo((ImageInfo *) NULL); - image_info->colorspace = RGBColorspace; - /* Map the entire file into process memory space */ - data = mmap(NULL, data_size, PROT_READ, MAP_PRIVATE, fileno(lvl_file), 0); + if ((data = mmap(NULL, data_size, PROT_READ, MAP_PRIVATE, fileno(lvl_file), 0)) == MAP_FAILED) { + printf("ERROR: Unable to mmap the file content!\n"); + EXIT(errno_alloc) + } /* Iterate through all image data offsets to get the number of entries and the * size of the unknown chunk */ - num_entries=0; + tot_entries=0; last_ptr=data; save_ptr=data; - while (off_ptr=(unsigned char*)memchr(last_ptr,'T',(data_size-(last_ptr-data)))) { + while (!((off_ptr=(unsigned char*)memchr(last_ptr,'T',(data_size-(last_ptr-data)))) == NULL)) { unknown+=(off_ptr-last_ptr); if (!strncmp((char*)off_ptr,entry_id,4)) { - num_entries++; - width=*((unsigned int *)(off_ptr+4)); - height=*((unsigned int *)(off_ptr+8)); - last_ptr=off_ptr+12+width*height; - save_ptr=last_ptr; - } else { - last_ptr=off_ptr+1; - } - } - - unsigned short geometry[num_entries][4]; - - /* Iterate through all image data offsets */ - i=0; - last_ptr=data; - save_ptr=data; - while (off_ptr=(unsigned char*)memchr(last_ptr,'T',(data_size-(last_ptr-data)))) { - unknown+=(off_ptr-last_ptr); - if (!strncmp((char*)off_ptr,entry_id,4)) { - i++; + /* Create an image offset table */ + if (img_off_size<=tot_entries) { + if ((tmp = realloc(img_offsets, sizeof(unsigned char*) * (img_off_size += img_off_size_step))) == NULL) { + printf("ERROR: Realloc failed (img_offsets)!\n"); + free(img_offsets); + EXIT(errno_alloc) + } + img_offsets = tmp; + } + img_offsets[tot_entries]=off_ptr; + tot_entries++; /* * Write unknown content (up to this image position (off_ptr)) to a file. * If the file size would be 0, skip it. */ if (config.debug && (off_ptr-save_ptr > 0)) { - snprintf(buf, 16, "%08d.bin", i); + snprintf(buf, 16, "%08u.bin", unknown); unknown_file = fopen(buf, "wb"); - fwrite(save_ptr,1,(off_ptr-save_ptr),unknown_file); + (void)fwrite(save_ptr,1,(size_t)(off_ptr-save_ptr),unknown_file); fclose(unknown_file); } - - /* --== Parse header ==-- */ + /* skip the image */ width=*((unsigned int *)(off_ptr+4)); height=*((unsigned int *)(off_ptr+8)); - geometry[i-1][img_x]=x_off; - geometry[i-1][img_y]=0; - geometry[i-1][img_w]=width; - geometry[i-1][img_h]=height; - x_off+=width; - - /* update last_ptr, get the image and append it to the list */ - tmp_img=write_magick(off_ptr+12,image_info,width,height); - snprintf(buf,16,"%08d.%s",i,config.format); - strcpy(tmp_img->filename,buf); - AppendImageToList(&image_list,tmp_img); - - /* update pointers */ last_ptr=off_ptr+12+width*height; save_ptr=last_ptr; } else { @@ -431,45 +528,159 @@ } } - /* Montage the image and save it */ - GetMontageInfo(image_info,&montage_info); - GetExceptionInfo(&exception); - montage_info.tile="3000x1"; - montage_info.geometry="+0+0"; - montage_info.background_color=config.bg; - montage_info.matte_color=config.colorkey; - montage_info.gravity=NorthWestGravity; + if (lvlanims==NULL) { + if ( (lvlanims=(LVLAnim*)malloc(sizeof(LVLAnim))) == NULL) { + printf("Memory allocation of LVLAnim* failed!\n"); + lvlanims=NULL; + EXIT(errno_alloc) + } else { + lvlanims->start_num=0; + lvlanims->size=tot_entries; + strncpy(lvlanims->name,config.basename,32); + lvlanims->geometry=NULL; + } + lvlanim_size=1; + } + if (lvlanim_size<=1) config.write&=~2; - big_image=MontageImages(image_list,&montage_info,&exception); - big_image->matte_color=config.colorkey; + /* ImageMagick: global stuff */ + if (config.write!=0) { + image_info=CloneImageInfo((ImageInfo *) NULL); + image_info->colorspace = RGBColorspace; + image_list=NewImageList(); + GetExceptionInfo(&exception); + d_exception=1; + GetMontageInfo(image_info,&montage_info); + montage_info.tile="1x3000"; + montage_info.geometry="+0+0"; + montage_info.background_color=config.bg; + montage_info.matte_color=config.colorkey; + montage_info.gravity=NorthWestGravity; + GetMontageInfo(image_info,&montage_anim_info); + montage_anim_info.tile="3000x1"; + montage_anim_info.geometry="+0+0"; + montage_anim_info.background_color=config.bg; + montage_anim_info.matte_color=config.colorkey; + montage_anim_info.gravity=NorthWestGravity; + } + y_off=0; - snprintf(buf, 16, "%s.%s",config.basename,config.format); - strcpy(big_image->filename,buf); - WriteImage(image_info,big_image); - DestroyImage(big_image); + /* Main loop: Process each animation */ + for (i=0; i=tot_entries) { + printf("Illegal animation data file (image number %u does not exist)!\n",j); + break; + } + /* --== Parse header ==-- */ + width=*((unsigned int *)(img_offsets[j]+4)); + height=*((unsigned int *)(img_offsets[j]+8)); + if (height>maxh) maxh=height; + + lvlanims[i].geometry[j-lvlanims[i].start_num].x=x_off; + lvlanims[i].geometry[j-lvlanims[i].start_num].y=y_off; + lvlanims[i].geometry[j-lvlanims[i].start_num].w=width; + lvlanims[i].geometry[j-lvlanims[i].start_num].h=height; + + if (width*height>0) num_entries++; + + /* get the frame and append it to the animation image list */ + if (config.write!=0) { + tmp_image=getFrame(img_offsets[j]+12,image_info,width,height); + if (config.write&4) { + snprintf(buf, 32, "%s_%04u.%s",lvlanims[i].name,(j-lvlanims[i].start_num)+1,config.format); + strcpy(tmp_image->filename,buf); + (void)WriteImage(image_info,tmp_image); + } + AppendImageToList(&anim_list,tmp_image); + } + + x_off+=width; + } + + /* Montage the image and append it to the big image list */ + if (config.write!=0) { + if (anim_list!=(Image *) ((void *)0)) { + anim_image=MontageImages(anim_list,&montage_anim_info,&exception); + anim_image->matte_color=config.colorkey; + + DestroyImageList(anim_list); + anim_list=NULL; + if (config.write&2) { + snprintf(buf, 32, "%s.%s",lvlanims[i].name,config.format); + strcpy(anim_image->filename,buf); + (void)WriteImage(image_info,anim_image); + } + AppendImageToList(&image_list,anim_image); + } else { + printf("Empty animation: %s!\n",lvlanims[i].name); + } + } + y_off+=maxh; } + /* Create a big image (montage) using the big image list */ + if (config.write!=0) { + big_image=MontageImages(image_list,&montage_info,&exception); + big_image->matte_color=config.colorkey; + DestroyImageList(image_list); + image_list=NULL; + + if (config.write&1) { + snprintf(buf, 16, "%s.%s",config.basename,config.format); + strcpy(big_image->filename,buf); + (void)WriteImage(image_info,big_image); + } + DestroyImage(big_image); + big_image=NULL; + } + + /* Create the geometry file */ + fprintf(geom_file,"LVLGEOM\n"); + fprintf(geom_file,"Size %u %u\n\n",lvlanim_size,num_entries); + for (i=0; i Author: jonas Date: 2005-03-19 16:32:42 -0500 (Sat, 19 Mar 2005) New Revision: 106 Modified: trunk/tools/lvl_tools/lvl2magick.c Log: further improvements Modified: trunk/tools/lvl_tools/lvl2magick.c =================================================================== --- trunk/tools/lvl_tools/lvl2magick.c 2005-03-19 17:04:32 UTC (rev 105) +++ trunk/tools/lvl_tools/lvl2magick.c 2005-03-19 21:32:42 UTC (rev 106) @@ -43,7 +43,7 @@ typedef struct { unsigned int start_num; unsigned int size; - char name[32]; + char name[50]; Rectangle* geometry; } LVLAnim; @@ -285,7 +285,7 @@ void freeLVLAnimList(LVLAnim* lvlanims,unsigned int size) { unsigned int i; for (i=0; i< size; i++) { - if (lvlanims[i].geometry!=NULL) free(lvlanims[i].geometry); + free(lvlanims[i].geometry); } free(lvlanims); } @@ -312,7 +312,7 @@ unsigned int parseDataFile(char* data_file_name, LVLAnim** lvlanims) { const char data_id[]="LVLDATA"; unsigned int start_num, size, data_size=0; - char name[32], line[80]; + char name[50], line[80]; int match=0; unsigned int i=0; @@ -351,13 +351,15 @@ return 0; } + /* parse the file */ i=0; while (fgets(line,80,data_file)) { + /* TODO: ignore lines starting with: # */ match=sscanf(line, "%u %u %s\n", &start_num, &size, name); if (match!=3) continue; (*lvlanims)[i].start_num=start_num; (*lvlanims)[i].size=size; - strncpy((*lvlanims)[i].name,name,32); + strncpy((*lvlanims)[i].name,name,50); (*lvlanims)[i].geometry=NULL; i++; @@ -463,6 +465,7 @@ (buf[2] != 'T') && (buf[3] != 'A')) { printf("Invalid file\n"); fclose(lvl_file); + lvl_file=NULL; EXIT(errno_invalid) } @@ -470,19 +473,6 @@ fstat(fileno(lvl_file), &sb); data_size = (unsigned int)(sb.st_size); - /* Check data_file */ - lvlanim_size=parseDataFile(config.data_file, &lvlanims); - - /* Change to the base directory */ - mkdir(config.basename, 0777); - chdir(config.basename); - printf("Directory: %s\n", config.basename); - - /* Create file for image informations */ - snprintf(buf,16,"%s.txt",config.basename); - geom_file = fopen(buf,"w"); - geom_file = freopen(buf,"a",geom_file); - /* Map the entire file into process memory space */ if ((data = mmap(NULL, data_size, PROT_READ, MAP_PRIVATE, fileno(lvl_file), 0)) == MAP_FAILED) { printf("ERROR: Unable to mmap the file content!\n"); @@ -528,6 +518,9 @@ } } + /* Check data_file */ + lvlanim_size=parseDataFile(config.data_file, &lvlanims); + if (lvlanims==NULL) { if ( (lvlanims=(LVLAnim*)malloc(sizeof(LVLAnim))) == NULL) { printf("Memory allocation of LVLAnim* failed!\n"); @@ -536,13 +529,18 @@ } else { lvlanims->start_num=0; lvlanims->size=tot_entries; - strncpy(lvlanims->name,config.basename,32); + strncpy(lvlanims->name,config.basename,50); lvlanims->geometry=NULL; } lvlanim_size=1; } if (lvlanim_size<=1) config.write&=~2; + /* Change to the base directory */ + mkdir(config.basename, 0777); + chdir(config.basename); + printf("Directory: %s\n", config.basename); + /* ImageMagick: global stuff */ if (config.write!=0) { image_info=CloneImageInfo((ImageInfo *) NULL); @@ -596,7 +594,7 @@ if (config.write!=0) { tmp_image=getFrame(img_offsets[j]+12,image_info,width,height); if (config.write&4) { - snprintf(buf, 32, "%s_%04u.%s",lvlanims[i].name,(j-lvlanims[i].start_num)+1,config.format); + snprintf(buf, 80, "%s_%04u.%s",lvlanims[i].name,(j-lvlanims[i].start_num)+1,config.format); strcpy(tmp_image->filename,buf); (void)WriteImage(image_info,tmp_image); } @@ -615,7 +613,7 @@ DestroyImageList(anim_list); anim_list=NULL; if (config.write&2) { - snprintf(buf, 32, "%s.%s",lvlanims[i].name,config.format); + snprintf(buf, 80, "%s.%s",lvlanims[i].name,config.format); strcpy(anim_image->filename,buf); (void)WriteImage(image_info,anim_image); } @@ -644,6 +642,10 @@ } /* Create the geometry file */ + snprintf(buf,16,"%s.txt",config.basename); + geom_file = fopen(buf,"w"); + geom_file = freopen(buf,"a",geom_file); + fprintf(geom_file,"LVLGEOM\n"); fprintf(geom_file,"Size %u %u\n\n",lvlanim_size,num_entries); for (i=0; i Author: jonas Date: 2005-03-19 17:16:09 -0500 (Sat, 19 Mar 2005) New Revision: 107 Added: trunk/tools/lvl2magick.c Modified: trunk/tools/Makefile trunk/tools/slvextract.c Log: reorganized the directory structure... Modified: trunk/tools/Makefile =================================================================== --- trunk/tools/Makefile 2005-03-19 21:32:42 UTC (rev 106) +++ trunk/tools/Makefile 2005-03-19 22:16:09 UTC (rev 107) @@ -1,29 +1,31 @@ -CXX = g++ -CXX_FLAGS = -W -Wall -pedantic -CXX_DEBUG = -g #-fno-inline -CXX_OPT = -O2 -march=pentium4 -ffast-math -CXX_GAME = -DSDL_MIXER -DSDL_IMAGE -DALPHA -SDL = `sdl-config --cflags` -SDL_LINK = `sdl-config --libs` -lSDL_mixer -lSDL_image +CC = gcc +CC_FLAGS = -pedantic -W -Wall +CC_DEBUG = -g #-fno-inline +CC_OPT = -O2 -march=pentium4 -ffast-math +CC_LVL = `Magick-config --ldflags --libs` -OBJS = slvextract.o -BIN = slvextract +SLV = lvlextract +SLV_OBJS = slvextract.o +LVL = lvl2magick +LVL_OBJS = lvl2magick.o -default: - $(MAKE) -C lvl_tools - $(MAKE) $(BIN) - -$(BIN): $(OBJS) - $(CXX) $(OBJS) $(SDL_LINK) -o $(BIN) +default: $(SLV) $(LVL) -%.o: %.cpp - $(CXX) $(CXX_FLAGS) $(CXX_DEBUG) $(CXX_GAME) $(SDL) -c $< -o $@ +all: $(SLV) $(LVL) +$(SLV): $(SLV_OBJS) + $(CC) $(SLV_OBJS) -o $(SLV) + +$(LVL): $(LVL_OBJS) + $(CC) $(CC_LVL) $(LVL_OBJS) -o $(LVL) + +%.o: %.c + $(CC) $(CC_FLAGS) $(CC_DEBUG) $(CC_OPT) -c $< -o $@ + clean: - rm -f *.o - rm -f $(BIN) - +$(MAKE) -C lvl_tools clean + rm -f $(SLV) + rm -f $(LVL) + rm -f *.o *.a distclean: clean rm -f *~ - +$(MAKE) -C lvl_tools distclean Copied: trunk/tools/lvl2magick.c (from rev 106, trunk/tools/lvl_tools/lvl2magick.c) Modified: trunk/tools/slvextract.c =================================================================== --- trunk/tools/slvextract.c 2005-03-19 21:32:42 UTC (rev 106) +++ trunk/tools/slvextract.c 2005-03-19 22:16:09 UTC (rev 107) @@ -5,16 +5,19 @@ */ #include +#include +#include +#include +#include #include #include -void put_wav_header(int fd, int samp, int bits, int chans, int size) -{ +void put_wav_header(int fd, int samp, int bit, int chans, int size) { int bps = chans*samp; char buf[44] = { 'R','I','F','F', 0,0,0,0, 'W','A','V','E', - 'f','m','t',' ', 0,0,0,0, - 1,0, 0,0, 0,0,0,0, 0,0,0,0, 0,0, 8,0, - 'd','a','t','a', 0,0,0,0 }; + 'f','m','t',' ', 0,0,0,0, + 1,0, 0,0, 0,0,0,0, 0,0,0,0, 0,0, 8,0, + 'd','a','t','a', 0,0,0,0 }; buf[4] = (size + 36); buf[5] = (size + 36) >> 8; @@ -50,153 +53,131 @@ write(fd, buf, 44); } -int read_entry(int fd_in) -{ +int read_entry(int fd_in) { int swapped = 0, size, samp, bits, chans; char filename[14], buf[512]; - int fd_out, pos = 0, aligned; + int fd_out, pos = 0; - printf("new entry at %x\n", lseek(fd_in, 0, SEEK_CUR)); + printf("new entry at %x\n", (unsigned int)lseek(fd_in, 0, SEEK_CUR)); - // header + /* header */ read(fd_in, buf, 70); - // byte swapped entry - if (buf[3]) - swapped++; + /* byte swapped entry */ + if (buf[3]) swapped++; - // FIXME: size could be entries aswell? get some non-8bit samples + /* FIXME: size could be entries aswell? get some non-8bit samples */ - if (swapped) - { - size = (buf[0] << 16) | (buf[1] << 24) | (buf[2]) | (buf[3] << 8); - samp = (buf[4] << 16) | (buf[5] << 24) | (buf[6]) | (buf[7] << 8); - bits = (buf[8] << 16) | (buf[9 ] << 24) | (buf[10]) | (buf[11] << 8); - chans = (buf[12] << 16)| (buf[13] << 24) | (buf[14]) | (buf[15] << 8); + if (swapped) { + size = (buf[0] << 16) | (buf[1] << 24) | (buf[2]) | (buf[3] << 8); + samp = (buf[4] << 16) | (buf[5] << 24) | (buf[6]) | (buf[7] << 8); + bits = (buf[8] << 16) | (buf[9 ] << 24) | (buf[10]) | (buf[11] << 8); + chans = (buf[12] << 16)| (buf[13] << 24) | (buf[14]) | (buf[15] << 8); - size += 2; + size += 2; - strncpy(&filename[0], &buf[52], 14); - } - else - { - size = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); - samp = buf[4] | (buf[5] << 8) | (buf[6] << 16) | (buf[7] << 24); - bits = buf[8] | (buf[9] << 8) | (buf[10] << 16) | (buf[11] << 24); - chans = buf[12] | (buf[13] << 8) | (buf[14] << 16) | (buf[15] << 24); + strncpy(&filename[0], &buf[52], 14); + } else { + size = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); + samp = buf[4] | (buf[5] << 8) | (buf[6] << 16) | (buf[7] << 24); + bits = buf[8] | (buf[9] << 8) | (buf[10] << 16) | (buf[11] << 24); + chans = buf[12] | (buf[13] << 8) | (buf[14] << 16) | (buf[15] << 24); - strncpy(&filename[0], &buf[50], 14); + strncpy(&filename[0], &buf[50], 14); } - if (!size) - return -1; + if (!size) return -1; - printf("entry %x: %s size: %x %d/%d/%d\n", - lseek(fd_in, 0, SEEK_CUR), - filename, size, samp, bits, chans); + printf("entry %x: %s size: %x %d/%d/%d\n", (unsigned int)lseek(fd_in, 0, SEEK_CUR), filename, size, samp, bits, chans); strncpy(buf, filename, 14); - if (strrchr(buf, '.')) - { - char *loc = strrchr(buf, '.'); - strncpy(loc, ".wav", 5); + if (strrchr(buf, '.')) { + char *loc = strrchr(buf, '.'); + strncpy(loc, ".wav", 5); } printf("Writing out %s...\n", buf); fd_out = open(buf, O_WRONLY|O_CREAT, 0666); put_wav_header(fd_out, samp, bits, chans, size); - while(pos < size) - { - int ret = read(fd_in, buf, (size-pos > 512) ? 512 : size-pos); - - write(fd_out, buf, ret); - pos += ret; + while(pos < size) { + int ret = read(fd_in, buf, (size-pos > 512) ? 512 : size-pos); + + write(fd_out, buf, ret); + pos += ret; } close(fd_out); - if (size % 4) - { - int aligned = size + (4 - (size % 4)); + if (size % 4) { + int aligned = size + (4 - (size % 4)); - printf("aligned: %d, pos: %d, %d\n", aligned, pos, aligned-pos); - lseek(fd_in, aligned-pos, SEEK_CUR); - - return 70 + size + aligned-pos; + printf("aligned: %d, pos: %d, %d\n", aligned, pos, aligned-pos); + lseek(fd_in, aligned-pos, SEEK_CUR); + + return 70 + size + aligned-pos; } return 70 + size; } -int main(int argc, char *argv[]) -{ - int fd_in, fd_out; +int main(int argc, char *argv[]) { + int fd_in; char buf[16]; int size, pos = 0, counter = 0; - if (argc < 2) - { - printf("Usage: %s input.slv [destination]\n", argv[0]); - exit(1); + if (argc < 2) { + printf("Usage: %s input.slv [destination]\n", argv[0]); + exit(1); } fd_in = open(argv[1], O_RDONLY); - if (fd_in < 0) - { - perror("error opening file"); - exit(1); + if (fd_in < 0) { + perror("error opening file"); + exit(1); } read(fd_in, buf, 12); if ((buf[0] != 'D') && (buf[1] != 'A') && - (buf[2] != 'T') && (buf[3] != 'A')) - { - printf("Invalid file\n"); - close(fd_in); - exit(1); + (buf[2] != 'T') && (buf[3] != 'A')) { + printf("Invalid file\n"); + close(fd_in); + exit(1); } size = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7]; printf("size: %d\n", size); - if (argc > 2) - { - mkdir(argv[2], 0777); - chdir(argv[2]); + if (argc > 2) { + mkdir(argv[2], 0777); + chdir(argv[2]); - printf("directory: %s\n", argv[2]); - } - else - { - // copy the filename - if (strrchr(argv[1], '/')) - strncpy(buf, strrchr(argv[1], '/')+1, 16); - else - strncpy(buf, argv[1], 16); + printf("directory: %s\n", argv[2]); + } else { + /* copy the filename */ + if (strrchr(argv[1], '/')) strncpy(buf, strrchr(argv[1], '/')+1, 16); + else strncpy(buf, argv[1], 16); - // truncate filename at . - if (strrchr(buf, '.')) - { - char *loc = strrchr(buf, '.'); - *loc = 0; - } + /* truncate filename at . */ + if (strrchr(buf, '.')) { + char *loc = strrchr(buf, '.'); + *loc = 0; + } - mkdir(buf, 0777); - chdir(buf); + mkdir(buf, 0777); + chdir(buf); - printf("directory: %s\n", buf); + printf("directory: %s\n", buf); } - while(pos < size) - { - int tmp = read_entry(fd_in); - if (tmp == -1) - break; - pos += tmp; - counter++; + while(pos < size) { + int tmp = read_entry(fd_in); + if (tmp == -1) break; + pos += tmp; + counter++; } printf("extracted %d items\n", counter); + return 0; } From DONOTREPLY at icculus.org Sat Mar 19 17:22:13 2005 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 19 Mar 2005 17:22:13 -0500 Subject: r108 - trunk/tools/lvl_tools Message-ID: <20050319222213.8975.qmail@icculus.org> Author: jonas Date: 2005-03-19 17:22:13 -0500 (Sat, 19 Mar 2005) New Revision: 108 Removed: trunk/tools/lvl_tools/lvl2magick.c Modified: trunk/tools/lvl_tools/Makefile Log: reorganized the directory structure (part2) Modified: trunk/tools/lvl_tools/Makefile =================================================================== --- trunk/tools/lvl_tools/Makefile 2005-03-19 22:16:09 UTC (rev 107) +++ trunk/tools/lvl_tools/Makefile 2005-03-19 22:22:13 UTC (rev 108) @@ -3,23 +3,17 @@ CC_DEBUG = -g #-fno-inline CC_OPT = -O2 -march=pentium4 -ffast-math CC_TOOL = -lpng -CC_MAGICK = `Magick-config --ldflags --libs` OBJS = png_out.o xpm_out.o pgm_out.o png_xpm_out.o lvlextract.o -OBJS_MAGICK = lvl2magick.o BIN = ../lvlextract -BIN_MAGICK = ../lvl2magick -default: $(BIN_MAGICK) +default: $(BIN) -all: $(BIN) $(BIN_MAGICK) +all: $(BIN) $(BIN): $(OBJS) $(CC) $(CC_TOOL) $(OBJS) -o $(BIN) -$(BIN_MAGICK): $(OBJS_MAGICK) - $(CC) $(CC_MAGICK) $(OBJS_MAGICK) -o $(BIN_MAGICK) - %.o: %.c $(CC) $(CC_FLAGS) $(CC_DEBUG) -c $< -o $@ Deleted: trunk/tools/lvl_tools/lvl2magick.c =================================================================== --- trunk/tools/lvl_tools/lvl2magick.c 2005-03-19 22:16:09 UTC (rev 107) +++ trunk/tools/lvl_tools/lvl2magick.c 2005-03-19 22:22:13 UTC (rev 108) @@ -1,688 +0,0 @@ -/* - * (C) 2004 Jonas Jermann - * - * Extract Images from .lvl files using ImageMagick api - * - * License: GPL - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define EXIT(a) { errno=(a); goto end; } - -enum { - red=0, - green=1, - blue=2 -}; - -enum { - errno_ok=0, - errno_quit=1, - errno_parse=2, - errno_open=3, - errno_invalid=4, - errno_alloc=5, - errno_misc=6 -}; - -typedef struct { - unsigned int x; - unsigned int y; - unsigned int w; - unsigned int h; -} Rectangle; - -typedef struct { - unsigned int start_num; - unsigned int size; - char name[50]; - Rectangle* geometry; -} LVLAnim; - -typedef struct { - /* create unknown.bin chunk files if != 0 */ - int debug; - /* Write the individial animations */ - int write; - /* input lvl file */ - char lvl_file[20]; - /* input data file */ - char data_file[20]; - /* output geometry file */ - char geom_file[20]; - /* base name (used for output directory and output file names) */ - char basename[20]; - /* image format */ - char format[5]; - /* colorkey */ - PixelPacket colorkey; - /* background color */ - PixelPacket bg; -} Config; - -Config config; -int errno=errno_ok; - -/* RGB palette */ -unsigned char lvl_palette[256][3] = { - /* The first two RGB values represent the colorkey (changed accordingly later) */ - { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, }, - - { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00 }, - { 0x08, 0x04, 0x00 }, { 0x00, 0x04, 0x10 }, { 0x08, 0x10, 0x00 }, { 0x08, 0x10, 0x10 }, - { 0x18, 0x10, 0x00 }, { 0x18, 0x14, 0x10 }, { 0x00, 0x08, 0x29 }, { 0x00, 0x0c, 0x39 }, - { 0x10, 0x14, 0x20 }, { 0x18, 0x18, 0x20 }, { 0x08, 0x20, 0x08 }, { 0x08, 0x24, 0x29 }, - { 0x18, 0x28, 0x39 }, { 0x29, 0x10, 0x08 }, { 0x20, 0x24, 0x00 }, { 0x20, 0x24, 0x10 }, - { 0x31, 0x24, 0x00 }, { 0x31, 0x24, 0x00 }, { 0x31, 0x34, 0x00 }, { 0x31, 0x34, 0x10 }, - { 0x20, 0x20, 0x20 }, { 0x29, 0x24, 0x20 }, { 0x20, 0x34, 0x29 }, { 0x31, 0x30, 0x29 }, - { 0x31, 0x30, 0x39 }, { 0x00, 0x0c, 0x4a }, { 0x62, 0x65, 0x08 }, { 0x73, 0x6d, 0x52 }, - { 0x73, 0x00, 0xb4 }, { 0x94, 0x38, 0x20 }, { 0xa4, 0x65, 0x39 }, { 0x31, 0x34, 0x4a }, - { 0x29, 0x34, 0x62 }, { 0x08, 0x44, 0x10 }, { 0x00, 0x65, 0x00 }, { 0x29, 0x59, 0x39 }, - { 0x31, 0x7d, 0x39 }, { 0x29, 0x48, 0x6a }, { 0x4a, 0x0c, 0x08 }, { 0x41, 0x2c, 0x00 }, - { 0x41, 0x28, 0x10 }, { 0x52, 0x2c, 0x10 }, { 0x52, 0x3c, 0x10 }, { 0x4a, 0x38, 0x29 }, - { 0x41, 0x3c, 0x39 }, { 0x62, 0x1c, 0x08 }, { 0x73, 0x08, 0x08 }, { 0x62, 0x3c, 0x10 }, - { 0x7b, 0x20, 0x08 }, { 0x73, 0x34, 0x10 }, { 0x41, 0x3c, 0x4a }, { 0x41, 0x40, 0x00 }, - { 0x41, 0x40, 0x10 }, { 0x4a, 0x55, 0x00 }, { 0x52, 0x40, 0x00 }, { 0x52, 0x55, 0x08 }, - { 0x52, 0x55, 0x18 }, { 0x52, 0x44, 0x39 }, { 0x5a, 0x59, 0x39 }, { 0x62, 0x44, 0x00 }, - { 0x62, 0x55, 0x00 }, { 0x62, 0x55, 0x18 }, { 0x73, 0x44, 0x10 }, { 0x73, 0x59, 0x00 }, - { 0x73, 0x59, 0x10 }, { 0x62, 0x40, 0x20 }, { 0x62, 0x44, 0x39 }, { 0x73, 0x40, 0x20 }, - { 0x7b, 0x44, 0x20 }, { 0x7b, 0x55, 0x20 }, { 0x7b, 0x59, 0x31 }, { 0x62, 0x65, 0x08 }, - { 0x62, 0x65, 0x18 }, { 0x62, 0x75, 0x18 }, { 0x7b, 0x6d, 0x08 }, { 0x73, 0x6d, 0x18 }, - { 0x7b, 0x7d, 0x08 }, { 0x7b, 0x7d, 0x18 }, { 0x7b, 0x6d, 0x29 }, { 0x7b, 0x7d, 0x29 }, - { 0x4a, 0x48, 0x52 }, { 0x52, 0x50, 0x52 }, { 0x4a, 0x4c, 0x6a }, { 0x4a, 0x4c, 0x7b }, - { 0x5a, 0x59, 0x62 }, { 0x4a, 0x71, 0x5a }, { 0x6a, 0x55, 0x52 }, { 0x73, 0x6d, 0x52 }, - { 0x62, 0x65, 0x62 }, { 0x62, 0x6d, 0x7b }, { 0x73, 0x71, 0x6a }, { 0x7b, 0x79, 0x7b }, - { 0x08, 0x10, 0x94 }, { 0x00, 0x04, 0xac }, { 0x10, 0x1c, 0xa4 }, { 0x18, 0x20, 0xbd }, - { 0x20, 0x30, 0x83 }, { 0x00, 0x04, 0xf6 }, { 0x29, 0x30, 0xc5 }, { 0x29, 0x4c, 0x83 }, - { 0x20, 0x40, 0xa4 }, { 0x20, 0x55, 0xc5 }, { 0x20, 0x4c, 0xee }, { 0x73, 0x00, 0xb4 }, - { 0x4a, 0x4c, 0xac }, { 0x4a, 0x71, 0x83 }, { 0x52, 0x6d, 0xac }, { 0x4a, 0x48, 0xcd }, - { 0x52, 0x4c, 0xee }, { 0x5a, 0x6d, 0xe6 }, { 0x00, 0x99, 0x00 }, { 0x10, 0xea, 0x08 }, - { 0x4a, 0x85, 0x39 }, { 0x4a, 0xa5, 0xac }, { 0x7b, 0x85, 0xa4 }, { 0x5a, 0xba, 0xee }, - /* check below */ - { 0x6a, 0x89, 0xee }, { 0x94, 0x08, 0x08 }, { 0x94, 0x2c, 0x08 }, { 0x94, 0x38, 0x20 }, - { 0xac, 0x0c, 0x08 }, { 0xb4, 0x30, 0x10 }, { 0xb4, 0x34, 0x31 }, { 0x94, 0x50, 0x10 }, - { 0x8b, 0x4c, 0x20 }, { 0x8b, 0x5d, 0x20 }, { 0x8b, 0x5d, 0x31 }, { 0x8b, 0x69, 0x00 }, - { 0x9c, 0x69, 0x08 }, { 0x94, 0x7d, 0x00 }, { 0x94, 0x79, 0x39 }, { 0xac, 0x55, 0x00 }, - { 0xa4, 0x59, 0x20 }, { 0xa4, 0x5d, 0x31 }, { 0xbd, 0x50, 0x20 }, { 0xa4, 0x65, 0x39 }, - { 0xa4, 0x7d, 0x20 }, { 0xac, 0x75, 0x39 }, { 0xbd, 0x65, 0x29 }, { 0xbd, 0x6d, 0x39 }, - { 0x8b, 0x61, 0x4a }, { 0x9c, 0x79, 0x5a }, { 0xd5, 0x08, 0x08 }, { 0xd5, 0x30, 0x20 }, - { 0xf6, 0x08, 0x08 }, { 0xf6, 0x28, 0x20 }, { 0xf6, 0x38, 0x39 }, { 0xc5, 0x59, 0x39 }, - { 0xc5, 0x79, 0x29 }, { 0xc5, 0x7d, 0x39 }, { 0xde, 0x7d, 0x31 }, { 0xe6, 0x59, 0x29 }, - { 0xe6, 0x59, 0x52 }, { 0xff, 0x59, 0x52 }, { 0xb4, 0x24, 0xbd }, { 0x8b, 0x81, 0x10 }, - { 0x94, 0x95, 0x00 }, { 0x8b, 0x81, 0x20 }, { 0x9c, 0x99, 0x20 }, { 0xa4, 0x81, 0x00 }, - { 0xa4, 0x81, 0x10 }, { 0xac, 0x9d, 0x00 }, { 0xbd, 0x81, 0x08 }, { 0xac, 0x99, 0x20 }, - { 0xb4, 0xae, 0x18 }, { 0xa4, 0xaa, 0x20 }, { 0xb4, 0xae, 0x29 }, { 0xbd, 0xb6, 0x39 }, - { 0x94, 0x81, 0x73 }, { 0xa4, 0x99, 0x41 }, { 0xbd, 0x99, 0x5a }, { 0xb4, 0x8d, 0x73 }, - { 0xbd, 0xaa, 0x73 }, { 0xc5, 0x9d, 0x00 }, { 0xcd, 0x99, 0x20 }, { 0xcd, 0xb6, 0x00 }, - { 0xc5, 0xb6, 0x29 }, { 0xd5, 0xba, 0x20 }, { 0xde, 0xba, 0x39 }, { 0xff, 0x99, 0x00 }, - { 0xe6, 0xae, 0x00 }, { 0xc5, 0x81, 0x4a }, { 0xc5, 0x95, 0x41 }, { 0xd5, 0x99, 0x41 }, - { 0xd5, 0x99, 0x52 }, { 0xde, 0x85, 0x73 }, { 0xd5, 0xaa, 0x5a }, { 0xd5, 0xb2, 0x6a }, - { 0xd5, 0xb6, 0x7b }, { 0xe6, 0x81, 0x52 }, { 0xf6, 0x85, 0x73 }, { 0xee, 0xa5, 0x5a }, - { 0xf6, 0xb2, 0x73 }, { 0xd5, 0xce, 0x00 }, { 0xd5, 0xca, 0x31 }, { 0xd5, 0xd2, 0x20 }, - { 0xde, 0xda, 0x39 }, { 0xf6, 0xd2, 0x00 }, { 0xff, 0xf2, 0x00 }, { 0xee, 0xee, 0x20 }, - { 0xf6, 0xf2, 0x39 }, { 0xd5, 0xca, 0x41 }, { 0xde, 0xda, 0x4a }, { 0xee, 0xde, 0x52 }, - { 0xf6, 0xde, 0x73 }, { 0xee, 0xe2, 0x41 }, { 0xf6, 0xf2, 0x52 }, { 0x8b, 0x89, 0x83 }, - { 0x94, 0x95, 0x9c }, { 0x8b, 0x99, 0xb4 }, { 0xb4, 0xa5, 0x94 }, { 0xa4, 0xa5, 0xac }, - { 0xb4, 0xb2, 0xb4 }, { 0xbe, 0xbd, 0xbe }, { 0x94, 0x91, 0xf6 }, { 0xac, 0xb6, 0xd5 }, - { 0xac, 0xb2, 0xff }, { 0xbd, 0xd2, 0xee }, { 0xd5, 0xb6, 0x94 }, { 0xcd, 0xba, 0xb4 }, - { 0xf6, 0x99, 0x94 }, { 0xf6, 0xba, 0x9c }, { 0xde, 0xca, 0x8b }, { 0xde, 0xce, 0xa4 }, - { 0xde, 0xd2, 0xb4 }, { 0xff, 0xde, 0x94 }, { 0xf6, 0xda, 0xbd }, { 0xff, 0xfa, 0xbd }, - { 0xcd, 0xca, 0xcd }, { 0xde, 0xda, 0xcd }, { 0xde, 0xda, 0xde }, { 0xd5, 0xf6, 0xff }, - { 0xe6, 0xe2, 0xee }, { 0xf6, 0xf2, 0xe6 }, { 0xff, 0xfa, 0xff }, { 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00 } -}; - - -void usage() { - printf("Usage: lvl2magick [options] file.lvl\n"); - printf("Extracts images from file.lvl.\n\n\n"); - printf("Options:\n"); - printf(" -h, --help Print this help message\n\n"); - printf(" -debug Create additional debug files (default: off)\n\n"); - printf(" -write <0-7> n=0: Just create the geometry data (no images)\n"); - printf(" n=1: Create one big image with all animations in it\n"); - printf(" n=2: Create one image for each animation\n"); - printf(" n=4: Create one image for each frame\n"); - printf(" Values can be added to achieve the desired combination\n"); - printf(" (default: 3)\n\n"); - printf(" -colorkey \"#rrggbb\" Use the specified color for the colorkey. The numbers\n"); - printf(" rr, gg, bb are hex values from 0 to ff. (default: #ff00ff)\n\n"); - printf(" -bg \"#rrggbb\" Use the specified color for the background (default: colorkey)\n\n"); - printf(" -dir, -o Name of the output directory (default: file)\n\n"); - printf(" -format Name of the output image format (default: png)\n\n"); - printf(" -data_file Data filename for file.lvl (default: file.dat)\n\n"); -} - -int parse(int argc, char* argv[]) { - int i; - char buf[20]; - - /* default settings */ - strncpy(config.lvl_file,"",16); - strncpy(config.data_file,"",16); - strncpy(config.basename,"",16); - strncpy(config.format,"png",4); - config.debug=0; - config.write=3; - config.colorkey.red=MaxRGB; - config.colorkey.green=0; - config.colorkey.blue=MaxRGB; - config.colorkey.opacity=0; - config.bg.red=config.colorkey.red; - config.bg.green=config.colorkey.green; - config.bg.blue=config.colorkey.blue; - config.bg.opacity=config.colorkey.opacity; - - /* parse cmdline */ - for (i=1; i7 || config.write<0) { - usage(); - return errno_parse; - } - } else if (strcmp(argv[i],"-colorkey")==0) { - i++; - if (!strncmp(argv[i],"#",1)==0) { usage(); return errno_parse; } - strcpy(buf,argv[i]+1); buf[2]=0; - config.colorkey.red=(Quantum)(MaxRGB*strtol(buf,NULL,16)/255); - strcpy(buf,argv[i]+3); buf[2]=0; - config.colorkey.green=(Quantum)(MaxRGB*strtol(buf,NULL,16)/255); - strcpy(buf,argv[i]+5); buf[2]=0; - config.colorkey.blue=(Quantum)(MaxRGB*strtol(buf,NULL,16)/255); - config.bg.blue=config.colorkey.blue; - config.bg.red=config.colorkey.red; - config.bg.green=config.colorkey.green; - } else if (strcmp(argv[i],"-bg")==0) { - i++; - if (strncmp(argv[i],"#",1)==0) { - strcpy(buf,argv[i]+1); buf[2]=0; - config.bg.red=(Quantum)(MaxRGB*strtol(buf,NULL,16)/255); - strcpy(buf,argv[i]+3); buf[2]=0; - config.bg.green=(Quantum)(MaxRGB*strtol(buf,NULL,16)/255); - strcpy(buf,argv[i]+5); buf[2]=0; - config.bg.blue=(Quantum)(MaxRGB*strtol(buf,NULL,16)/255); - config.bg.opacity=0; - } else { - usage(); - return errno_parse; - } - } else if (strcmp(argv[i],"-dir")==0 || strcmp(argv[i],"-o")==0) { - i++; - if (strncmp(argv[i],"-",1)==0) { usage(); return errno_parse; } - strncpy(config.basename,argv[i],16); - } else if (strcmp(argv[i],"-format")==0) { - i++; - if (strncmp(argv[i],"-",1)==0) { usage(); return errno_parse; } - strncpy(config.format,argv[i],4); - } else if (strcmp(argv[i],"-data_file")==0) { - i++; - if (strncmp(argv[i],"-",1)==0) { usage(); return errno_parse; } - strncpy(config.data_file,argv[i],16); - } else { - printf("Unknown suboption %s!\n",argv[i]); - } - } else if (strcmp(config.lvl_file,"")==0) { - strncpy(config.lvl_file,argv[i],16); - } else { - printf("Option %s ignored, filename is already set!\n",argv[i]); - } - } - - /* check validity */ - if (strcmp(config.lvl_file,"")==0) { - usage(); - return errno_parse; - } - - /* default settings if unspecified */ - if (strcmp(config.basename,"")==0) { - /* copy the filename */ - if (strrchr(config.lvl_file, '/')) strncpy(config.basename, strrchr(config.lvl_file, '/')+1, 16); - else strncpy(config.basename, config.lvl_file, 16); - - /* truncate filename at . */ - if (strrchr(config.basename, '.')) { - char *loc = strrchr(config.basename, '.'); - *loc = 0; - } - } - if (strcmp(config.data_file,"")==0) { - snprintf(config.data_file,16,"%s.dat",config.basename); - } - snprintf(config.geom_file,16,"%s.txt",config.basename); - - /* set colorkey in palette */ - lvl_palette[0][red] = (unsigned char)(config.colorkey.red*255/MaxRGB); - lvl_palette[0][green] = (unsigned char)(config.colorkey.green*255/MaxRGB); - lvl_palette[0][blue] = (unsigned char)(config.colorkey.blue*255/MaxRGB); - lvl_palette[1][red] = (unsigned char)(config.colorkey.red*255/MaxRGB); - lvl_palette[1][green] = (unsigned char)(config.colorkey.green*255/MaxRGB); - lvl_palette[1][blue] = (unsigned char)(config.colorkey.blue*255/MaxRGB); - - return errno_ok; -} - -void freeLVLAnimList(LVLAnim* lvlanims,unsigned int size) { - unsigned int i; - for (i=0; i< size; i++) { - free(lvlanims[i].geometry); - } - free(lvlanims); -} - -/* Parses the specified data file and stores the result (array of LVLAnim) in - * lvlanims. The return value is the size of the array (number of animations). - * Usage: anim_size=parseDataFile("image.dat",&lvlanims); - * - * Data file Format: - * - * ----------------- - * LVLDATA - * - * start_offset size name - * ... - * - * ----------------- - * - * start_offset is the image index off all images in the file - * size is the number of frames of the animation - * name is the unique name of the animation - * - */ -unsigned int parseDataFile(char* data_file_name, LVLAnim** lvlanims) { - const char data_id[]="LVLDATA"; - unsigned int start_num, size, data_size=0; - char name[50], line[80]; - int match=0; - unsigned int i=0; - - FILE* data_file = fopen(data_file_name,"r"); - *lvlanims=NULL; - - if (data_file == NULL) { - printf("Data file %s not found!\n",data_file_name); - return 0; - } - - if (!fgets(line,80,data_file) || strncmp(line,data_id,7)) { - printf("Data file %s is invalid!!\n",data_file_name); - fclose(data_file); - return 0; - } - - /* get the number of entries */ - while (fgets(line,80,data_file)) { - match=sscanf(line, "%u %u %s\n", &start_num, &size, name); - if (match==3) data_size++; - } - if (data_size==0) { - printf("Data file %s is invalid (no entries)!\n",data_file_name); - fclose(data_file); - return 0; - } - /* rewind to the beginning */ - rewind(data_file); - (void)fgets(line,80,data_file); - - /* allocate memory */ - if ((*lvlanims=(LVLAnim*)malloc(data_size*sizeof(LVLAnim))) == NULL) { - printf("Memory allocation of LVLAnim* failed! Couldn't read data file %s!\n", data_file_name); - *lvlanims=NULL; - return 0; - } - - /* parse the file */ - i=0; - while (fgets(line,80,data_file)) { - /* TODO: ignore lines starting with: # */ - match=sscanf(line, "%u %u %s\n", &start_num, &size, name); - if (match!=3) continue; - (*lvlanims)[i].start_num=start_num; - (*lvlanims)[i].size=size; - strncpy((*lvlanims)[i].name,name,50); - - (*lvlanims)[i].geometry=NULL; - i++; - } - - fclose(data_file); - return data_size; -} - - -/* - * Create an ImageMagick image of size width x height - * - * image_info is an initialized ImageMagick ImageInfo* ptr - * ptr is the pointer to the image data offset - */ -Image* getFrame(unsigned char* ptr, ImageInfo* image_info, unsigned int width, unsigned int height) { - Image* image; - unsigned long int y; - register unsigned long int x; - register PixelPacket *q; - register unsigned char *p; - - image=AllocateImage(image_info); - image->columns=width; - image->rows=height; - image->matte_color=config.colorkey; - - p=ptr; - for (y=0; y < image->rows; y++) { - q=SetImagePixels(image,0,(long int)y,image->columns,1); - if (q == (PixelPacket *) NULL) break; - for (x=0; x < image->columns; x++) { - q->red=(Quantum)(MaxRGB*(lvl_palette[*p][red])/255); - q->green=(Quantum)(MaxRGB*(lvl_palette[*p][green])/255); - q->blue=(Quantum)(MaxRGB*(lvl_palette[*p][blue])/255); - p++; - q++; - } - if (!SyncImagePixels(image)) break; - } - return image; -} - -int main(int argc, char *argv[]) { - /* ImageMagick stuff */ - Image *image_list=NULL, *anim_list=NULL; - ImageInfo *image_info=NULL; - MontageInfo montage_info, montage_anim_info; - ExceptionInfo exception; - Image *big_image=NULL, *anim_image=NULL, *tmp_image=NULL; - - /* temporary variables */ - char buf[20]; - struct stat sb; - unsigned int i,j,width,height,x_off=0,y_off=0,maxh=0; - int d_exception=0; - - const char entry_id[]="TRPS"; - unsigned int data_size=0, tot_entries=0, num_entries=0, unknown=0; - FILE *lvl_file=NULL, *unknown_file=NULL, *geom_file=NULL; - LVLAnim* lvlanims=NULL; - unsigned int lvlanim_size=0; - - /* Initial start pointer to the beginning of the file */ - unsigned char *data=NULL; - /* Temporary variable to indicate the last offset to start searching from: - * Either after (1+) an invalid "T" or after the image of a valid "TRPS" */ - unsigned char *last_ptr; - /* Either index position (start) or the last known position after an image */ - unsigned char *save_ptr; - /* Iterates through all offsets at a "T" */ - unsigned char *off_ptr; - - const unsigned int img_off_size_step=32; - unsigned int img_off_size=0; - unsigned char **img_offsets=NULL; - unsigned char **tmp=NULL; - - /* -------------------------------------------------------------------- */ - - /* parse command line options and set config */ - errno=parse(argc,argv); - - if (errno==errno_quit) - EXIT(errno_ok) - else if (errno==errno_parse) - EXIT(errno_parse) - else if (errno!=errno_ok) - EXIT(errno) - - /* Check lvl_file */ - lvl_file = fopen(config.lvl_file,"r"); - - if (lvl_file == NULL) { - printf("Error opening file\n"); - EXIT(errno_open) - } - - (void)fread(buf,1,12,lvl_file); - - if ((buf[0] != 'D') && (buf[1] != 'A') && - (buf[2] != 'T') && (buf[3] != 'A')) { - printf("Invalid file\n"); - fclose(lvl_file); - lvl_file=NULL; - EXIT(errno_invalid) - } - - /* get file size */ - fstat(fileno(lvl_file), &sb); - data_size = (unsigned int)(sb.st_size); - - /* Map the entire file into process memory space */ - if ((data = mmap(NULL, data_size, PROT_READ, MAP_PRIVATE, fileno(lvl_file), 0)) == MAP_FAILED) { - printf("ERROR: Unable to mmap the file content!\n"); - EXIT(errno_alloc) - } - - /* Iterate through all image data offsets to get the number of entries and the - * size of the unknown chunk */ - tot_entries=0; - last_ptr=data; - save_ptr=data; - while (!((off_ptr=(unsigned char*)memchr(last_ptr,'T',(data_size-(last_ptr-data)))) == NULL)) { - unknown+=(off_ptr-last_ptr); - if (!strncmp((char*)off_ptr,entry_id,4)) { - /* Create an image offset table */ - if (img_off_size<=tot_entries) { - if ((tmp = realloc(img_offsets, sizeof(unsigned char*) * (img_off_size += img_off_size_step))) == NULL) { - printf("ERROR: Realloc failed (img_offsets)!\n"); - free(img_offsets); - EXIT(errno_alloc) - } - img_offsets = tmp; - } - img_offsets[tot_entries]=off_ptr; - tot_entries++; - /* - * Write unknown content (up to this image position (off_ptr)) to a file. - * If the file size would be 0, skip it. - */ - if (config.debug && (off_ptr-save_ptr > 0)) { - snprintf(buf, 16, "%08u.bin", unknown); - unknown_file = fopen(buf, "wb"); - (void)fwrite(save_ptr,1,(size_t)(off_ptr-save_ptr),unknown_file); - fclose(unknown_file); - } - /* skip the image */ - width=*((unsigned int *)(off_ptr+4)); - height=*((unsigned int *)(off_ptr+8)); - last_ptr=off_ptr+12+width*height; - save_ptr=last_ptr; - } else { - last_ptr=off_ptr+1; - } - } - - /* Check data_file */ - lvlanim_size=parseDataFile(config.data_file, &lvlanims); - - if (lvlanims==NULL) { - if ( (lvlanims=(LVLAnim*)malloc(sizeof(LVLAnim))) == NULL) { - printf("Memory allocation of LVLAnim* failed!\n"); - lvlanims=NULL; - EXIT(errno_alloc) - } else { - lvlanims->start_num=0; - lvlanims->size=tot_entries; - strncpy(lvlanims->name,config.basename,50); - lvlanims->geometry=NULL; - } - lvlanim_size=1; - } - if (lvlanim_size<=1) config.write&=~2; - - /* Change to the base directory */ - mkdir(config.basename, 0777); - chdir(config.basename); - printf("Directory: %s\n", config.basename); - - /* ImageMagick: global stuff */ - if (config.write!=0) { - image_info=CloneImageInfo((ImageInfo *) NULL); - image_info->colorspace = RGBColorspace; - image_list=NewImageList(); - GetExceptionInfo(&exception); - d_exception=1; - GetMontageInfo(image_info,&montage_info); - montage_info.tile="1x3000"; - montage_info.geometry="+0+0"; - montage_info.background_color=config.bg; - montage_info.matte_color=config.colorkey; - montage_info.gravity=NorthWestGravity; - GetMontageInfo(image_info,&montage_anim_info); - montage_anim_info.tile="3000x1"; - montage_anim_info.geometry="+0+0"; - montage_anim_info.background_color=config.bg; - montage_anim_info.matte_color=config.colorkey; - montage_anim_info.gravity=NorthWestGravity; - } - y_off=0; - - /* Main loop: Process each animation */ - for (i=0; i=tot_entries) { - printf("Illegal animation data file (image number %u does not exist)!\n",j); - break; - } - /* --== Parse header ==-- */ - width=*((unsigned int *)(img_offsets[j]+4)); - height=*((unsigned int *)(img_offsets[j]+8)); - if (height>maxh) maxh=height; - - lvlanims[i].geometry[j-lvlanims[i].start_num].x=x_off; - lvlanims[i].geometry[j-lvlanims[i].start_num].y=y_off; - lvlanims[i].geometry[j-lvlanims[i].start_num].w=width; - lvlanims[i].geometry[j-lvlanims[i].start_num].h=height; - - if (width*height>0) num_entries++; - - /* get the frame and append it to the animation image list */ - if (config.write!=0) { - tmp_image=getFrame(img_offsets[j]+12,image_info,width,height); - if (config.write&4) { - snprintf(buf, 80, "%s_%04u.%s",lvlanims[i].name,(j-lvlanims[i].start_num)+1,config.format); - strcpy(tmp_image->filename,buf); - (void)WriteImage(image_info,tmp_image); - } - AppendImageToList(&anim_list,tmp_image); - } - - x_off+=width; - } - - /* Montage the image and append it to the big image list */ - if (config.write!=0) { - if (anim_list!=(Image *) ((void *)0)) { - anim_image=MontageImages(anim_list,&montage_anim_info,&exception); - anim_image->matte_color=config.colorkey; - - DestroyImageList(anim_list); - anim_list=NULL; - if (config.write&2) { - snprintf(buf, 80, "%s.%s",lvlanims[i].name,config.format); - strcpy(anim_image->filename,buf); - (void)WriteImage(image_info,anim_image); - } - AppendImageToList(&image_list,anim_image); - } else { - printf("Empty animation: %s!\n",lvlanims[i].name); - } - } - y_off+=maxh; - } - - /* Create a big image (montage) using the big image list */ - if (config.write!=0) { - big_image=MontageImages(image_list,&montage_info,&exception); - big_image->matte_color=config.colorkey; - DestroyImageList(image_list); - image_list=NULL; - - if (config.write&1) { - snprintf(buf, 16, "%s.%s",config.basename,config.format); - strcpy(big_image->filename,buf); - (void)WriteImage(image_info,big_image); - } - DestroyImage(big_image); - big_image=NULL; - } - - /* Create the geometry file */ - snprintf(buf,16,"%s.txt",config.basename); - geom_file = fopen(buf,"w"); - geom_file = freopen(buf,"a",geom_file); - - fprintf(geom_file,"LVLGEOM\n"); - fprintf(geom_file,"Size %u %u\n\n",lvlanim_size,num_entries); - for (i=0; i Author: jonas Date: 2005-03-19 17:23:59 -0500 (Sat, 19 Mar 2005) New Revision: 109 Added: trunk/tools/old/ Removed: trunk/tools/lvl_tools/ Log: reorganized the directory structure (part3) Copied: trunk/tools/old (from rev 108, trunk/tools/lvl_tools) From DONOTREPLY at icculus.org Sat Mar 19 17:27:56 2005 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 19 Mar 2005 17:27:56 -0500 Subject: r110 - trunk/tools Message-ID: <20050319222756.9559.qmail@icculus.org> Author: jonas Date: 2005-03-19 17:27:56 -0500 (Sat, 19 Mar 2005) New Revision: 110 Modified: trunk/tools/Makefile Log: reorganized the directory structure (part4), finally done ;) Modified: trunk/tools/Makefile =================================================================== --- trunk/tools/Makefile 2005-03-19 22:23:59 UTC (rev 109) +++ trunk/tools/Makefile 2005-03-19 22:27:56 UTC (rev 110) @@ -4,15 +4,19 @@ CC_OPT = -O2 -march=pentium4 -ffast-math CC_LVL = `Magick-config --ldflags --libs` -SLV = lvlextract +SLV = slvextract SLV_OBJS = slvextract.o LVL = lvl2magick LVL_OBJS = lvl2magick.o +OLD = lvlextract default: $(SLV) $(LVL) -all: $(SLV) $(LVL) +all: $(SLV) $(LVL) $(OLD) +$(OLD): + $(MAKE) -C old/ + $(SLV): $(SLV_OBJS) $(CC) $(SLV_OBJS) -o $(SLV) @@ -25,7 +29,10 @@ clean: rm -f $(SLV) rm -f $(LVL) + rm -f $(OLD) rm -f *.o *.a + $(MAKE) -C old/ clean distclean: clean rm -f *~ + $(MAKE) -C old/ distclean From DONOTREPLY at icculus.org Sat Mar 19 17:28:41 2005 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 19 Mar 2005 17:28:41 -0500 Subject: r111 - trunk/tools Message-ID: <20050319222841.9661.qmail@icculus.org> Author: jonas Date: 2005-03-19 17:28:41 -0500 (Sat, 19 Mar 2005) New Revision: 111 Added: trunk/tools/vik_player_convert.sh Removed: trunk/tools/conversion.sh Log: better name Deleted: trunk/tools/conversion.sh =================================================================== --- trunk/tools/conversion.sh 2005-03-19 22:27:56 UTC (rev 110) +++ trunk/tools/conversion.sh 2005-03-19 22:28:41 UTC (rev 111) @@ -1,15 +0,0 @@ -#!/bin/sh -# -#Conversion script used to change the name from viking to player - -for i in *; do sed s/VIKING/PLAYER/g $i > $i.new; mv $i.new $i; done -for i in *; do sed s/Viking/Player/g $i > $i.new; mv $i.new $i; done -for i in *; do sed s/player/player/g $i > $i.new; mv $i.new $i; done -for i in *; do sed s/vkit/plit/g $i > $i.new; mv $i.new $i; done -for i in *; do sed s/vpool/ppool/g $i > $i.new; mv $i.new $i; done -for i in *; do sed s/vik/plr/g $i > $i.new; mv $i.new $i; done -for i in *; do sed s/vit/plit/g $i > $i.new; mv $i.new $i; done -for i in *; do sed s/vpos/ppos/g $i > $i.new; mv $i.new $i; done -for i in *; do sed s/vbar/pbar/g $i > $i.new; mv $i.new $i; done -for i in *; do sed s/vnum/pnum/g $i > $i.new; mv $i.new $i; done -for i in *; do sed s/vname/pname/g $i > $i.new; mv $i.new $i; done Copied: trunk/tools/vik_player_convert.sh (from rev 108, trunk/tools/conversion.sh) From DONOTREPLY at icculus.org Sun Mar 20 05:48:40 2005 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 20 Mar 2005 05:48:40 -0500 Subject: r112 - trunk/tools Message-ID: <20050320104840.19730.qmail@icculus.org> Author: jonas Date: 2005-03-20 05:48:40 -0500 (Sun, 20 Mar 2005) New Revision: 112 Modified: trunk/tools/lvl2magick.c Log: introduce a start index parameter, start_index 0 (default) is very usefull for creating an lvl data file.... Modified: trunk/tools/lvl2magick.c =================================================================== --- trunk/tools/lvl2magick.c 2005-03-19 22:28:41 UTC (rev 111) +++ trunk/tools/lvl2magick.c 2005-03-20 10:48:40 UTC (rev 112) @@ -50,6 +50,8 @@ typedef struct { /* create unknown.bin chunk files if != 0 */ int debug; + /* start index (for the frame names) */ + unsigned int start_index; /* Write the individial animations */ int write; /* input lvl file */ @@ -150,6 +152,7 @@ printf("Options:\n"); printf(" -h, --help Print this help message\n\n"); printf(" -debug Create additional debug files (default: off)\n\n"); + printf(" -start_index Start index of the frame image names (default: 0)\n\n"); printf(" -write <0-7> n=0: Just create the geometry data (no images)\n"); printf(" n=1: Create one big image with all animations in it\n"); printf(" n=2: Create one image for each animation\n"); @@ -174,6 +177,7 @@ strncpy(config.basename,"",16); strncpy(config.format,"png",4); config.debug=0; + config.start_index=0; config.write=3; config.colorkey.red=MaxRGB; config.colorkey.green=0; @@ -192,6 +196,10 @@ return errno_quit; } else if (strcmp(argv[i],"-debug")==0) { config.debug=1; + } else if (strcmp(argv[i],"-start_index")==0) { + i++; + if (strncmp(argv[i],"-",1)==0) { usage(); return errno_parse; } + config.start_index=(unsigned int)atoi(argv[i]); } else if (strcmp(argv[i],"-write")==0) { i++; if (strncmp(argv[i],"-",1)==0) { usage(); return errno_parse; } @@ -594,7 +602,7 @@ if (config.write!=0) { tmp_image=getFrame(img_offsets[j]+12,image_info,width,height); if (config.write&4) { - snprintf(buf, 80, "%s_%04u.%s",lvlanims[i].name,(j-lvlanims[i].start_num)+1,config.format); + snprintf(buf, 80, "%s_%04u.%s",lvlanims[i].name,(j-lvlanims[i].start_num)+config.start_index,config.format); strcpy(tmp_image->filename,buf); (void)WriteImage(image_info,tmp_image); }