mirror of
https://github.com/UberGames/GtkRadiant.git
synced 2024-11-29 23:22:23 +00:00
489 lines
9.7 KiB
C
489 lines
9.7 KiB
C
/*
|
|
Copyright (C) 1999-2007 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 "q3data.h"
|
|
|
|
byte *byteimage, *lbmpalette;
|
|
int byteimagewidth, byteimageheight;
|
|
|
|
|
|
char mip_prefix[1024]; // directory to dump the textures in
|
|
|
|
qboolean colormap_issued;
|
|
byte colormap_palette[768];
|
|
|
|
/*
|
|
==============
|
|
Cmd_Grab
|
|
|
|
$grab filename x y width height
|
|
==============
|
|
*/
|
|
void Cmd_Grab( void ){
|
|
int xl,yl,w,h,y;
|
|
byte *cropped;
|
|
char savename[1024];
|
|
char dest[1024];
|
|
|
|
GetToken( qfalse );
|
|
|
|
if ( token[0] == '/' || token[0] == '\\' ) {
|
|
sprintf( savename, "%s%s.pcx", writedir, token + 1 );
|
|
}
|
|
else{
|
|
sprintf( savename, "%spics/%s.pcx", writedir, token );
|
|
}
|
|
|
|
if ( g_release ) {
|
|
if ( token[0] == '/' || token[0] == '\\' ) {
|
|
sprintf( dest, "%s.pcx", token + 1 );
|
|
}
|
|
else{
|
|
sprintf( dest, "pics/%s.pcx", token );
|
|
}
|
|
|
|
ReleaseFile( dest );
|
|
return;
|
|
}
|
|
|
|
GetToken( qfalse );
|
|
xl = atoi( token );
|
|
GetToken( qfalse );
|
|
yl = atoi( token );
|
|
GetToken( qfalse );
|
|
w = atoi( token );
|
|
GetToken( qfalse );
|
|
h = atoi( token );
|
|
|
|
if ( xl < 0 || yl < 0 || w < 0 || h < 0 || xl + w > byteimagewidth || yl + h > byteimageheight ) {
|
|
Error( "GrabPic: Bad size: %i, %i, %i, %i",xl,yl,w,h );
|
|
}
|
|
|
|
// crop it to the proper size
|
|
cropped = malloc( w * h );
|
|
for ( y = 0 ; y < h ; y++ )
|
|
{
|
|
memcpy( cropped + y * w, byteimage + ( y + yl ) * byteimagewidth + xl, w );
|
|
}
|
|
|
|
// save off the new image
|
|
printf( "saving %s\n", savename );
|
|
CreatePath( savename );
|
|
WritePCXfile( savename, cropped, w, h, lbmpalette );
|
|
|
|
free( cropped );
|
|
}
|
|
|
|
/*
|
|
==============
|
|
Cmd_Raw
|
|
|
|
$grab filename x y width height
|
|
==============
|
|
*/
|
|
void Cmd_Raw( void ){
|
|
int xl,yl,w,h,y;
|
|
byte *cropped;
|
|
char savename[1024];
|
|
char dest[1024];
|
|
|
|
GetToken( qfalse );
|
|
|
|
sprintf( savename, "%s%s.lmp", writedir, token );
|
|
|
|
if ( g_release ) {
|
|
sprintf( dest, "%s.lmp", token );
|
|
ReleaseFile( dest );
|
|
return;
|
|
}
|
|
|
|
GetToken( qfalse );
|
|
xl = atoi( token );
|
|
GetToken( qfalse );
|
|
yl = atoi( token );
|
|
GetToken( qfalse );
|
|
w = atoi( token );
|
|
GetToken( qfalse );
|
|
h = atoi( token );
|
|
|
|
if ( xl < 0 || yl < 0 || w < 0 || h < 0 || xl + w > byteimagewidth || yl + h > byteimageheight ) {
|
|
Error( "GrabPic: Bad size: %i, %i, %i, %i",xl,yl,w,h );
|
|
}
|
|
|
|
// crop it to the proper size
|
|
cropped = malloc( w * h );
|
|
for ( y = 0 ; y < h ; y++ )
|
|
{
|
|
memcpy( cropped + y * w, byteimage + ( y + yl ) * byteimagewidth + xl, w );
|
|
}
|
|
|
|
// save off the new image
|
|
printf( "saving %s\n", savename );
|
|
CreatePath( savename );
|
|
|
|
SaveFile( savename, cropped, w * h );
|
|
|
|
free( cropped );
|
|
}
|
|
|
|
/*
|
|
=============================================================================
|
|
|
|
COLORMAP GRABBING
|
|
|
|
=============================================================================
|
|
*/
|
|
|
|
/*
|
|
===============
|
|
BestColor
|
|
===============
|
|
*/
|
|
byte BestColor( int r, int g, int b, int start, int stop ){
|
|
int i;
|
|
int dr, dg, db;
|
|
int bestdistortion, distortion;
|
|
int bestcolor;
|
|
byte *pal;
|
|
|
|
//
|
|
// let any color go to 0 as a last resort
|
|
//
|
|
bestdistortion = 256 * 256 * 4;
|
|
bestcolor = 0;
|
|
|
|
pal = colormap_palette + start * 3;
|
|
for ( i = start ; i <= stop ; i++ )
|
|
{
|
|
dr = r - (int)pal[0];
|
|
dg = g - (int)pal[1];
|
|
db = b - (int)pal[2];
|
|
pal += 3;
|
|
distortion = dr * dr + dg * dg + db * db;
|
|
if ( distortion < bestdistortion ) {
|
|
if ( !distortion ) {
|
|
return i; // perfect match
|
|
|
|
}
|
|
bestdistortion = distortion;
|
|
bestcolor = i;
|
|
}
|
|
}
|
|
|
|
return bestcolor;
|
|
}
|
|
|
|
|
|
/*
|
|
==============
|
|
Cmd_Colormap
|
|
|
|
$colormap filename
|
|
|
|
the brightes colormap is first in the table (FIXME: reverse this now?)
|
|
|
|
64 rows of 256 : lightmaps
|
|
256 rows of 256 : translucency table
|
|
==============
|
|
*/
|
|
void Cmd_Colormap( void ){
|
|
int levels, brights;
|
|
int l, c;
|
|
float frac, red, green, blue;
|
|
float range;
|
|
byte *cropped, *lump_p;
|
|
char savename[1024];
|
|
char dest[1024];
|
|
|
|
colormap_issued = qtrue;
|
|
if ( !g_release ) {
|
|
memcpy( colormap_palette, lbmpalette, 768 );
|
|
}
|
|
|
|
if ( !TokenAvailable() ) { // just setting colormap_issued
|
|
return;
|
|
}
|
|
|
|
GetToken( qfalse );
|
|
sprintf( savename, "%spics/%s.pcx", writedir, token );
|
|
|
|
if ( g_release ) {
|
|
sprintf( dest, "pics/%s.pcx", token );
|
|
ReleaseFile( dest );
|
|
return;
|
|
}
|
|
|
|
range = 2;
|
|
levels = 64;
|
|
brights = 1; // ignore 255 (transparent)
|
|
|
|
cropped = malloc( ( levels + 256 ) * 256 );
|
|
lump_p = cropped;
|
|
|
|
// shaded levels
|
|
for ( l = 0; l < levels; l++ )
|
|
{
|
|
frac = range - range * (float)l / ( levels - 1 );
|
|
for ( c = 0 ; c < 256 - brights ; c++ )
|
|
{
|
|
red = lbmpalette[c * 3];
|
|
green = lbmpalette[c * 3 + 1];
|
|
blue = lbmpalette[c * 3 + 2];
|
|
|
|
red = (int)( red * frac + 0.5 );
|
|
green = (int)( green * frac + 0.5 );
|
|
blue = (int)( blue * frac + 0.5 );
|
|
|
|
//
|
|
// note: 254 instead of 255 because 255 is the transparent color, and we
|
|
// don't want anything remapping to that
|
|
// don't use color 0, because NT can't remap that (or 255)
|
|
//
|
|
*lump_p++ = BestColor( red,green,blue, 1, 254 );
|
|
}
|
|
|
|
// fullbrights allways stay the same
|
|
for ( ; c < 256 ; c++ )
|
|
*lump_p++ = c;
|
|
}
|
|
|
|
// 66% transparancy table
|
|
for ( l = 0; l < 255; l++ )
|
|
{
|
|
for ( c = 0 ; c < 255 ; c++ )
|
|
{
|
|
red = lbmpalette[c * 3] * 0.33 + lbmpalette[l * 3] * 0.66;
|
|
green = lbmpalette[c * 3 + 1] * 0.33 + lbmpalette[l * 3 + 1] * 0.66;
|
|
blue = lbmpalette[c * 3 + 2] * 0.33 + lbmpalette[l * 3 + 2] * 0.66;
|
|
|
|
*lump_p++ = BestColor( red,green,blue, 1, 254 );
|
|
}
|
|
*lump_p++ = 255;
|
|
}
|
|
for ( c = 0 ; c < 256 ; c++ )
|
|
*lump_p++ = 255;
|
|
|
|
// save off the new image
|
|
printf( "saving %s\n", savename );
|
|
CreatePath( savename );
|
|
WritePCXfile( savename, cropped, 256, levels + 256, lbmpalette );
|
|
|
|
free( cropped );
|
|
}
|
|
|
|
/*
|
|
=============================================================================
|
|
|
|
MIPTEX GRABBING
|
|
|
|
=============================================================================
|
|
*/
|
|
|
|
byte pixdata[256];
|
|
|
|
int d_red, d_green, d_blue;
|
|
|
|
byte palmap[32][32][32];
|
|
qboolean palmap_built;
|
|
|
|
/*
|
|
=============
|
|
FindColor
|
|
=============
|
|
*/
|
|
int FindColor( int r, int g, int b ){
|
|
int bestcolor;
|
|
|
|
if ( r > 255 ) {
|
|
r = 255;
|
|
}
|
|
if ( r < 0 ) {
|
|
r = 0;
|
|
}
|
|
if ( g > 255 ) {
|
|
g = 255;
|
|
}
|
|
if ( g < 0 ) {
|
|
g = 0;
|
|
}
|
|
if ( b > 255 ) {
|
|
b = 255;
|
|
}
|
|
if ( b < 0 ) {
|
|
b = 0;
|
|
}
|
|
#ifndef TABLECOLORS
|
|
bestcolor = BestColor( r, g, b, 0, 254 );
|
|
#else
|
|
bestcolor = palmap[r >> 3][g >> 3][b >> 3];
|
|
#endif
|
|
|
|
return bestcolor;
|
|
}
|
|
|
|
|
|
void BuildPalmap( void ){
|
|
#ifdef TABLECOLORS
|
|
int r, g, b;
|
|
int bestcolor;
|
|
|
|
if ( palmap_built ) {
|
|
return;
|
|
}
|
|
palmap_built = qtrue;
|
|
|
|
for ( r = 4 ; r < 256 ; r += 8 )
|
|
{
|
|
for ( g = 4 ; g < 256 ; g += 8 )
|
|
{
|
|
for ( b = 4 ; b < 256 ; b += 8 )
|
|
{
|
|
bestcolor = BestColor( r, g, b, 1, 254 );
|
|
palmap[r >> 3][g >> 3][b >> 3] = bestcolor;
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
if ( !colormap_issued ) {
|
|
Error( "You must issue a $colormap command first" );
|
|
}
|
|
|
|
}
|
|
|
|
/*
|
|
=============
|
|
AveragePixels
|
|
=============
|
|
*/
|
|
byte AveragePixels( int count ){
|
|
int r,g,b;
|
|
int i;
|
|
int vis;
|
|
int pix;
|
|
int bestcolor;
|
|
byte *pal;
|
|
int fullbright;
|
|
|
|
vis = 0;
|
|
r = g = b = 0;
|
|
fullbright = 0;
|
|
for ( i = 0 ; i < count ; i++ )
|
|
{
|
|
pix = pixdata[i];
|
|
|
|
r += lbmpalette[pix * 3];
|
|
g += lbmpalette[pix * 3 + 1];
|
|
b += lbmpalette[pix * 3 + 2];
|
|
vis++;
|
|
}
|
|
|
|
r /= vis;
|
|
g /= vis;
|
|
b /= vis;
|
|
|
|
// error diffusion
|
|
r += d_red;
|
|
g += d_green;
|
|
b += d_blue;
|
|
|
|
//
|
|
// find the best color
|
|
//
|
|
bestcolor = FindColor( r, g, b );
|
|
|
|
// error diffusion
|
|
pal = colormap_palette + bestcolor * 3;
|
|
d_red = r - (int)pal[0];
|
|
d_green = g - (int)pal[1];
|
|
d_blue = b - (int)pal[2];
|
|
|
|
return bestcolor;
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
=============================================================================
|
|
|
|
ENVIRONMENT MAP GRABBING
|
|
|
|
Creates six pcx files from tga files without any palette edge seams
|
|
also copies the tga files for GL rendering.
|
|
=============================================================================
|
|
*/
|
|
|
|
// 3dstudio environment map suffixes
|
|
char *suf[6] = {"rt", "ft", "lf", "bk", "up", "dn"};
|
|
|
|
/*
|
|
=================
|
|
Cmd_Environment
|
|
=================
|
|
*/
|
|
void Cmd_Environment( void ){
|
|
char name[1024];
|
|
int i, x, y;
|
|
byte image[256 * 256];
|
|
byte *tga;
|
|
|
|
GetToken( qfalse );
|
|
|
|
if ( g_release ) {
|
|
for ( i = 0 ; i < 6 ; i++ )
|
|
{
|
|
sprintf( name, "env/%s%s.pcx", token, suf[i] );
|
|
ReleaseFile( name );
|
|
sprintf( name, "env/%s%s.tga", token, suf[i] );
|
|
ReleaseFile( name );
|
|
}
|
|
return;
|
|
}
|
|
// get the palette
|
|
BuildPalmap();
|
|
|
|
sprintf( name, "%senv/", gamedir );
|
|
CreatePath( name );
|
|
|
|
// convert the images
|
|
for ( i = 0 ; i < 6 ; i++ )
|
|
{
|
|
sprintf( name, "%senv/%s%s.tga", gamedir, token, suf[i] );
|
|
printf( "loading %s...\n", name );
|
|
LoadTGA( name, &tga, NULL, NULL );
|
|
|
|
for ( y = 0 ; y < 256 ; y++ )
|
|
{
|
|
for ( x = 0 ; x < 256 ; x++ )
|
|
{
|
|
image[y * 256 + x] = FindColor( tga[( y * 256 + x ) * 4 + 0],tga[( y * 256 + x ) * 4 + 1],tga[( y * 256 + x ) * 4 + 2] );
|
|
}
|
|
}
|
|
free( tga );
|
|
sprintf( name, "%senv/%s%s.pcx", writedir, token, suf[i] );
|
|
if ( FileTime( name ) != -1 ) {
|
|
printf( "%s already exists, not overwriting.\n", name );
|
|
}
|
|
else{
|
|
WritePCXfile( name, image, 256, 256, colormap_palette );
|
|
}
|
|
}
|
|
}
|