/* Copyright (C) 1999-2006 Id Software, Inc. and contributors. For a list of contributors, see the accompanying CONTRIBUTORS file. This file is part of GtkRadiant. GtkRadiant is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. GtkRadiant is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GtkRadiant; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "qdata.h" byte *byteimage, *lbmpalette; int byteimagewidth, byteimageheight; qboolean TrueColorImage; int longimagewidth, longimageheight; char book_prefix[1024]; byte buffer[640 * 480]; unsigned long bufferl[640 * 480]; miptex_t *CreateBook8(byte *buffer, int w, int h, byte *palette, int *FinalSize) { miptex_t *mp; int i, j; byte *pos; int size; size = sizeof(*mp) + (w * h); mp = (miptex_t *)SafeMalloc(size, "CreateBook8"); memset(mp, 0, size); mp->version = MIP_VERSION; for(i=j=0;i<256;i++,j+=3) { mp->palette[i].r = palette[j]; mp->palette[i].g = palette[j+1]; mp->palette[i].b = palette[j+2]; } pos = (byte *)(mp + 1); mp->width[0] = w; mp->height[0] = h; mp->offsets[0] = sizeof(*mp); memcpy(pos, buffer, w * h); *FinalSize = size; return(mp); } miptex32_t *CreateBook32(long *buffer, int w, int h, int *FinalSize) { miptex32_t *mp; byte *pos; int size; size = sizeof(*mp) + (w * h * 4); mp = (miptex32_t *)SafeMalloc(size, "CreateBook32"); memset(mp, 0, size); mp->version = MIP32_VERSION; pos = (byte *)(mp + 1); mp->width[0] = w; mp->height[0] = h; mp->offsets[0] = sizeof(*mp); memcpy(pos, buffer, w * h * 4); *FinalSize = size; return(mp); } // Routines to chop a random sized image into gl texture friendly chunks typedef struct rect_s { int x, y; int w, h; char name[4]; } rect_t; int GetCoords(int x, int store[MAX_MD2SKINS]) { int index, start, delta; index = 0; start = 0; delta = 256; store[index++] = start; while(x) { if(x >= delta) { start += delta; store[index++] = start; x -= delta; } else { delta >>= 1; } } return(index); } int ChopImage(int w, int h, rect_t coords[MAX_MD2SKINS]) { int xs[MAX_MD2SKINS], ys[MAX_MD2SKINS]; int xcount, ycount, x, y, index; index = 0; xcount = GetCoords(w, xs) - 1; ycount = GetCoords(h, ys) - 1; for(y = 0; y < ycount; y++) { for(x = 0; x < xcount; x++, index++) { coords[index].x = xs[x]; coords[index].y = ys[y]; coords[index].w = xs[x + 1] - xs[x]; coords[index].h = ys[y + 1] - ys[y]; coords[index].name[0] = x + '0'; coords[index].name[1] = y + '0'; coords[index].name[2] = 0; } } return(index); } /* =============== Cmd_Pic =============== */ void Cmd_Book() { int xl,yl,xh,yh,w,h; byte *dest, *source; int flags, value, contents; char lumpname[64]; char filename[1024]; unsigned long *destl, *sourcel; int linedelta, x, y; int size; miptex_t *qtex; miptex32_t *qtex32; float scale_x, scale_y; int numrects, i; rect_t coords[MAX_MD2SKINS]; bookframe_t bframes[MAX_MD2SKINS]; bookframe_t *bf; book_t book; GetScriptToken (false); strcpy (lumpname, token); GetScriptToken (false); xl = atoi (token); GetScriptToken (false); yl = atoi (token); GetScriptToken (false); w = atoi (token); GetScriptToken (false); h = atoi (token); total_x += w; total_y += h; total_textures++; if ( (w & 7) || (h & 7) ) Error ("line %i: miptex sizes must be multiples of 8", scriptline); flags = 0; contents = 0; value = 0; scale_x = scale_y = 0.5; if (g_release) return; if(TrueColorImage) { xh = xl + w; yh = yl + h; if (xl >= longimagewidth || xh > longimagewidth || yl >= longimageheight || yh > longimageheight) { Error ("line %i: bad clip dimmensions (%d,%d) (%d,%d) > image (%d,%d)", scriptline, xl,yl,w,h,longimagewidth,longimageheight); } sourcel = (unsigned long *) longimage + (yl * longimagewidth) + xl; destl = (unsigned long *) longimage; linedelta = (longimagewidth - w); for(y = yl; y < yh; y++) { for(x = xl; x < xh; x++) { *destl++ = *sourcel++; // RGBA } sourcel += linedelta; } // Get rectangles to chop into numrects = ChopImage(w, h, coords); bf = bframes; for(i = 0; i < numrects; i++, bf++) { // Copy section of image to buffer sourcel = (unsigned long *) longimage + (coords[i].y * w) + coords[i].x; destl = bufferl; linedelta = w - coords[i].w; for(y = 0; y < coords[i].h; y++) { for(x = 0; x < coords[i].w; x++) { *destl++ = *sourcel++; } sourcel += linedelta; } qtex32 = CreateBook32(bufferl, coords[i].w, coords[i].h, &size); qtex32->flags = flags; qtex32->contents = contents; qtex32->value = value; qtex32->scale_x = scale_x; qtex32->scale_y = scale_y; sprintf (filename, "%sbook/%s/%s_%s.m32", gamedir, book_prefix, lumpname, coords[i].name); sprintf (qtex32->name, "%s/%s_%s.m32", book_prefix, lumpname, coords[i].name); strcpy(bf->name, qtex32->name); bf->x = coords[i].x; bf->y = coords[i].y; bf->w = coords[i].w; bf->h = coords[i].h; // // write it out // printf ("writing %s\n", filename); SaveFile (filename, (byte *)qtex32, size); free (qtex32); } } else { xh = xl + w; yh = yl + h; if (xl >= byteimagewidth || xh > byteimagewidth || yl >= byteimageheight || yh > byteimageheight) { Error ("line %i: bad clip dimmensions (%d,%d) (%d,%d) > image (%d,%d)", scriptline, xl,yl,w,h,byteimagewidth,byteimageheight); } // Copy image to top left source = byteimage + yl*byteimagewidth + xl; dest = byteimage; linedelta = byteimagewidth - w; for(y = yl; y < yh; y++) { for(x = xl; x < xh; x++) { *dest++ = *source++; } source += linedelta; } // Get rectangles to chop into numrects = ChopImage(w, h, coords); bf = bframes; for(i = 0; i < numrects; i++, bf++) { // Copy section of image to buffer source = byteimage + (coords[i].y * w) + coords[i].x; dest = buffer; linedelta = w - coords[i].w; for(y = 0; y < coords[i].h; y++) { for(x = 0; x < coords[i].w; x++) { *dest++ = *source++; } source += linedelta; } qtex = CreateBook8(buffer, coords[i].w, coords[i].h, lbmpalette, &size); qtex->flags = flags; qtex->contents = contents; qtex->value = value; sprintf (filename, "%sbook/%s/%s_%s.m8", gamedir, book_prefix, lumpname, coords[i].name); sprintf (qtex->name, "%s/%s_%s.m8", book_prefix, lumpname, coords[i].name); strcpy(bf->name, qtex->name); bf->x = coords[i].x; bf->y = coords[i].y; bf->w = coords[i].w; bf->h = coords[i].h; // // write it out // printf ("writing %s\n", filename); SaveFile (filename, (byte *)qtex, size); free (qtex); } } // Set up descriptor size = sizeof(bookframe_t) * numrects; book.bheader.ident = IDBOOKHEADER; book.bheader.version = BOOK_VERSION; book.bheader.num_segments = numrects; book.bheader.total_w = w; book.bheader.total_h = h; memcpy(book.bframes, bframes, size); // Save out segment descriptor sprintf (filename, "%sBook/%s/%s.bk", gamedir, book_prefix, lumpname); printf ("writing %s\n", filename); SaveFile (filename, (byte *)&book, size + sizeof(bookheader_t)); } /* =============== Cmd_picdir =============== */ void Cmd_Bookdir (void) { char filename[1024]; GetScriptToken (false); strcpy (book_prefix, token); // create the directory if needed sprintf (filename, "%sBook", gamedir); Q_mkdir (filename); sprintf (filename, "%sBook/%s", gamedir, book_prefix); Q_mkdir (filename); } // end