Tutorial *39*

This is my first tutorial on Quake 2. It will map a 24 bit image into the Quake2 engine memory.

I will work on optimizing my mipmap code, or replace it.

First we need to enable Quake2 to convert from 24 bit per pixel TGAs to 8 bit per pixel textures images to use, to do so, Quake2 have a table named 16to8.dat having a link to each of the color palette that quake2 must use for that color.

Note that each color contained in the current palette used by the server have benn reconverted to 32 bit for display. But that's another story... ;)

This table is already used in GL mode and is just so easy to import in sofware mode.

CODE PART :
Set your active project to ref_soft

We first have to modify the color info maintained in Quake2 this is done in the swstate_s struct.

in r_local.h change the following:



typedef struct swstate_s

{

qboolean fullscreen;

int      prev_mode; // last valid SW mode

unsigned char *d_16to8table; // HTrigger : 16 to 8 bit conversion table

byte gammatable[256];

byte currentpalette[1024];



} swstate_t;

Now we need this table to be loaded into the game so we need to load pics/16to8.dat into the d_16to8table, r_image.c is used for image file loading / handling.

So in r_image.c find the function: void R_InitImages (void), and make it look like this :



/*

===============

R_InitImages

===============

*/

void R_InitImages (void)

{

registration_sequence = 1;



// if ( )// HTrigger FIXME look if table really need to be loaded

// {

ri.FS_LoadFile( "pics/16to8.dat", &sw_state.d_16to8table );

if ( !sw_state.d_16to8table )

ri.Sys_Error( ERR_FATAL, "Couldn't load pics/16to8.pcx");

// }

}

Good, now add the folowing to r_image.c, just on top of



/*

================

GL_LoadPic

================

*/

image_t *GL_LoadPic(char *name, byte *pic, int width, int height, imagetype_t type)

Insert the folowing function:



void R_BuildPalettedTexture( unsigned char *paletted_texture, unsigned char

*scaled, int scaled_width, int scaled_height )

{

int i;



for ( i = 0; i < scaled_width * scaled_height; i++ )

{

unsigned int r, g, b, c;



r = ( scaled[0] >> 3 ) & 31;

g = ( scaled[1] >> 2 ) & 63;

b = ( scaled[2] >> 3 ) & 31;



c = r | ( g << 5 ) | ( b << 11 );



paletted_texture[i] = sw_state.d_16to8table[c];



scaled += 4;

}

}

This is a mere copy from GL_BuildPalettedTexture it translate and write the new texture in paletted_texture ("scaled" is the original).

Compile the project.

Ok, so now we need to specify that textures may need to be converted before being used.

Be carefull there's two of these function : *GL_LoadPic, one for software mode one for GL mode. So in R_IMAGE.C find :



image_t *GL_LoadPic (char *name, byte *pic, int width, int height,

imagetype_t type)

Change it to :



image_t *GL_LoadPic (char *name, byte *pic, int width, int height,

imagetype_t type, int bits)

We added "int bits" like in the GL version that is in gl_image. Remember that we want to use both TGA and 8 bit PCX.

right after :



image_t *image;

int i, c, b;

add these var types to the function :



unsigned char paletted_texture[256*256];

int j,z,y;

And after :



image->registration_sequence = registration_sequence;

Add :



if (type == it_wall) file://HTrigger textures loading

{

image->width = LittleLong (width);

image->height = LittleLong (height);



image->type = it_wall;



c = image->width*image->height * (256+64+16+4)/256;

image->pixels[0] = malloc (c);

image->pixels[1] = image->pixels[0] + image->width*image->height;

image->pixels[2] = image->pixels[1] + image->width*image->height/4;

image->pixels[3] = image->pixels[2] + image->width*image->height/16;



if (bits == 32)

{



R_BuildPalettedTexture(paletted_texture, ( unsigned char * ) pic,

image->width, image->height );



pic = paletted_texture;



}



// Load the texture pixels from pic

// FIX ME : MIPMAPING HERE ?

// Temporary mipmaping code



image->transparent = false;



for (z=1,y=0 ; y<=3 ; z*=2,y++)

{

for (j=0; jheight/z ; j++)

{

for (i=0 ; iwidth/z ; i++)

{

b = pic[((j*z)*image->width)+(i*z)];



image->pixels[y][(j*(image->width/z))+(i)] = b;

}

}

}



}

else

{



//End HTrigger

The remaining code will be :



image->width = width;

image->height = height;

image->type = type;



image->pixels[0] = malloc (c);

image->transparent = false;



for (i=0 ; itransparent = true;



image->pixels[0][i] = b;

}



}//HTrigger add this !!!



return image;

}

Ok the hardest part is done. Compile the project. Now still in r_image.c we go in the function called : image_t *R_FindImage, and modify the condition where a PCX wants to load to make it look like this :



if (!strcmp(name+len-4, ".pcx"))

{



LoadPCX (name, &pic, &palette, &width, &height);

if (!pic)

if (type == it_wall)

return r_notexture_mip;

else

return NULL;



image = GL_LoadPic (name, pic, width, height, type, 8);//Added 8 bit spec



}

Now the condition for the tga :



else if (!strcmp(name+len-4, ".tga"))

{



LoadTGA (name, &pic, &width, &height);

if (!pic)

if (type == it_wall)

return r_notexture_mip;

else

return NULL;

image = GL_LoadPic (name, pic, width, height, type, 32);



// ri.Sys_Error (ERR_DROP, "R_FindImage: can't load %s in software

renderer", name);

// return NULL;

}

Compile the project. Now be sure you have your textures as 8 bit pcx or 24 bit tga in the game directory and place them in textures/tga and/or textures/pcx. I'm using different dirs but you can do what you want.
The final step is to specify witch type of pic we want the engine to load.

Go into r_model.c and find the function Mod_LoadTexinfo, theres a line that specify the file to load. Actually its a .wal file. Make it point to your tga or pcx files.



Com_sprintf (name, sizeof(name), "textures/%s.wal", in->texture);

Replace it by :



Com_sprintf (name, sizeof(name), "textures/tga/%s.tga",

in->texture);//HTrigger TGA loading

You're set !

Remember to leave the .wal file where they belong since they are used by map editors as a reference to the directory structure at compile time.

But once the map is compiled .wal are not needed at run time.

High Trigger


 
Not logged in
Sign up
Login:
Passwd: