home *** CD-ROM | disk | FTP | other *** search
- /*
- Texture display by Raphaƫl Quinet <quinet@montefiore.ulg.ac.be>,
- Trevor Phillips <rphillip@cc.curtin.edu.au>,
- and Christian Johannes Schladetsch <s924706@yallara.cs.rmit.OZ.AU>
-
- You are allowed to use any parts of this code in another program, as
- long as you give credits to the authors in the documentation and in
- the program itself. Read the file README.1ST for more information.
-
- This program comes with absolutely no warranty.
-
- TEXTURES.C - Textures in 256 colors.
- */
-
- /* the includes */
- #include "deu.h"
- #include "wstructs.h"
- #include <assert.h>
-
- typedef struct _resource {
- char *name;
- void *data;
- struct _resource *next;
- } resource;
-
- resource *ResourceList;
-
- Bool ForgetAfter = TRUE;
- /* whether DisplayPic should de-allocate the picture resource
- after displaying it */
-
- /*
- display a floor or ceiling texture at coords x0, y0 and not beyond x1, y1
- */
-
- void DisplayFloorTexture( BCINT x0, BCINT y0, BCINT x1, BCINT y1, char *texname)
- {
- MDirPtr dir;
- unsigned char huge *pixels;
-
- dir = FindMasterDir( MasterDir, texname);
- if (dir == NULL) {
- SetColor( DARKGRAY);
- DrawScreenLine( x0, y0, x1, y1);
- DrawScreenLine( x0, y1, x1, y0);
- return;
- }
- BasicWadSeek( dir->wadfile, dir->dir.start);
-
- #if defined(__TURBOC__)
-
- pixels = (unsigned char huge*) GetFarMemory( 4100 * sizeof( char));
- BasicWadRead( dir->wadfile, &(pixels[ 4]), 4096L);
- if (GfxMode < -1) {
- /* Probably a bug in the VESA driver... */
- /* It requires "size-1" instead of "size"! */
- ((UBCINT huge *)pixels)[ 0] = 63;
- ((UBCINT huge *)pixels)[ 1] = 63;
- }
- else {
- ((UBCINT huge *)pixels)[ 0] = 64;
- ((UBCINT huge *)pixels)[ 1] = 64;
- }
-
- #elif defined(__GNUC__)
-
- /* bcc2grx's getimage-bitmap has a lot more info in it's header
- than borland's */
-
- pixels = (unsigned char*) GetFarMemory( 4096+sizeof(GrContext));
- getimage( x0, y0, x0+63, y0+63, pixels); /* Hack! */
- BasicWadRead( dir->wadfile, pixels+sizeof(GrContext), 4096L);
-
- #endif
-
- putimage( x0, y0, pixels, COPY_PUT);
- FreeFarMemory( pixels);
- }
-
- /*
- display a picture "picname" at coords x0, y0 and not beyond x1, y1
- */
-
-
- /* SO 2/4/95:
- DisplayPic now uses GetResource to get the sprite/patch to display.
- It checks the variable ForgetAfter to see whether it should
- call ForgetResource after displaying; this should be set by
- the caller.
- ChooseSprite sets this to TRUE; DisplayWallTexture sets it to FALSE.
- DisplayWallTexture then takes the responsibility for calling
- ForgetResource for all the patches in the texture being displayed.
- This enables us to buffer all the patches in case they are used
- more than once in a texture (e.g. LITE5 in Doom (extreme case!)) */
-
- void DisplayPic( BCINT x0, BCINT y0, BCINT x1, BCINT y1, char *picname)
- {
- PHeader *h;
- PColumn **columns, *c;
- BCINT x, y;
- BYTE *pixels;
- long p_resource;
-
- if(bioskey(1))
- return;
-
- p_resource = (long)GetResource(picname);
- if(!p_resource)
- return;
-
- h = (PHeader *)p_resource;
- columns = (PColumn **)(p_resource + sizeof(PHeader));
-
- for(x = 0; x < h->width; x++) {
- if(x > (x1 - x0))
- continue;
-
- c = (PColumn *)((long)columns[x] + p_resource);
- while(c->yofs != 255) {
- pixels = (BYTE *)((long)c + (long)sizeof(PColumn) +
- (long)c->npixels + 1L);
-
- for(y = c->npixels; y >= 0; y--) {
- if((y + c->yofs) > (y1 - y0))
- pixels--;
- else
- putpixel(x + x0, y + y0 + c->yofs, *pixels--);
- }
- c = (PColumn *)((long)c + (long)(c->npixels) + 4L);
- }
- }
-
- if(ForgetAfter)
- ForgetResource(picname);
- }
-
- void *GetResource(char *name)
- {
- void *t = NULL;
- resource *p, *new = (resource *)NULL;
- MDirPtr r;
-
- for(p = ResourceList; p; p = p->next)
- if(!strcmp(name, p->name))
- return p->data;
-
- r = FindMasterDir(MasterDir, name);
- if(r && (t = GetMemory(r->dir.size))) {
- BasicWadSeek(r->wadfile, r->dir.start);
- BasicWadRead(r->wadfile, t, r->dir.size);
-
- new = (resource *)GetMemory(sizeof(resource));
- assert(new);
- new->data = t;
- new->name = strdup(name);
- new->next = ResourceList;
- ResourceList = new;
- return t;
- }
- return NULL;
- }
-
- void ForgetResource(char *name)
- {
- resource *p, *q = NULL;
-
- for(p = ResourceList; p->next; q = p, p = p->next) {
- if(!strcmp(p->name, name)) {
- if(p == ResourceList)
- ResourceList = p->next;
- else
- q->next = p->next;
-
- FreeMemory(p->data);
- FreeMemory(p->name);
- FreeMemory(p);
-
- return;
- }
- }
- }
-
- void ForgetAllResources()
- {
- resource *p, *q;
- for(p = ResourceList; p; p = q) {
- q = p->next;
- FreeMemory(p->data);
- FreeMemory(p->name);
- FreeMemory(p);
- }
- }
-
-
- Texture *FindTexture(char *name)
- {
- Texture *t;
- SList p;
-
- for(p = Texture_sections; p; p = p->next) {
- t = FindTextureIn(name, GetResource(p->string));
- if(t)
- return t;
- }
- return NULL;
- }
-
- Texture *FindTextureIn(char *name, void *tblock)
- {
- long i, *offsets = tblock;
- Texture *t;
-
- if(tblock)
- for(i = 1; i <= offsets[0]; i++) {
- t = (Texture *)((long)offsets[i] + (long)tblock);
- if(!strncmp(t->name, name, 8))
- return t;
- }
-
- return NULL;
- }
-
- /*
- display a wall texture at coords x0, y0
- */
-
- void DisplayWallTexture( BCINT x0, BCINT y0, BCINT x1, BCINT y1, char *texname) {
- BCINT n, xsize, ysize;
- Texture *tinfo;
- PatchDesc *pinfo;
- char picname[9];
- long patchname;
- void *Pnames;
-
- if (bioskey( 1) != 0)
- return; /* speedup */
-
- Pnames = GetResource("PNAMES");
-
- /* clear the box where the texture size will be drawn - see below */
- SetColor(DARKGRAY);
- DrawScreenBox( x0 - 171, y0 + 40, x0 - 82, y0 + 70);
-
- if (!(tinfo = FindTexture(texname)))
- return;
-
- /* read the info for this texture */
- xsize = tinfo->width;
- ysize = tinfo->height;
-
- SetColor( BLACK);
- DrawScreenText( x0 - 171, y0 + 40, "%dx%d", xsize, ysize);
-
- if (tinfo->nPatches == 1)
- DrawScreenText( x0 - 171, y0 + 60, "Transparent");
- else
- DrawScreenText( x0 - 171, y0 + 60, "%d Patches", tinfo->nPatches);
-
- if (bioskey( 1) != 0)
- return; /* speedup */
-
- if (x1 - x0 > xsize)
- x1 = x0 + xsize;
- if (y1 - y0 > ysize)
- y1 = y0 + ysize;
-
- /* not really necessary, except when xofs or yofs < 0 */
- setviewport( x0, y0, x1, y1, TRUE);
-
- /* display the texture */
- pinfo = (PatchDesc *)((long)tinfo + sizeof(Texture));
- ForgetAfter = FALSE;
- for (n = 0; n < tinfo->nPatches; n++, pinfo++) {
-
- /* OK, now look up the pic's name in Pnames. */
- patchname = (long)Pnames + 4L + ((long)(pinfo->PatchNumber) * 8);
-
- strncpy(picname, (char *)patchname, 8);
- picname[ 8] = '\0';
- /* coords changed because of the "setviewport" */
- DisplayPic( pinfo->xOffset, pinfo->yOffset,
- x1 - x0, y1 - y0, strupr( picname));
- }
-
- /* de-allocate all patches */
- pinfo = (PatchDesc *)((long)tinfo + sizeof(Texture));
- for (n = 0; n < tinfo->nPatches; n++, pinfo++) {
- patchname = (long)Pnames + 4L + ((long)(pinfo->PatchNumber) * 8);
- strncpy(picname, (char *)patchname, 8);
- picname[ 8] = '\0';
- ForgetResource(picname);
- }
- /* restore the normal viewport */
- setviewport( 0, 0, ScrMaxX, ScrMaxY, TRUE);
- }
-
-
-
- /*
- Function to get the size of a wall texture
- It's a lot smaller now that we have functions to get a pointer
- to the texture structure automagically :-)
- */
-
- void GetWallTextureSize( BCINT *xsize_r, BCINT *ysize_r, char *texname)
- {
- Texture *t = FindTexture(texname);
-
- if(t) {
- *xsize_r = t->width;
- *ysize_r = t->height;
- }
- else {
- /* texture data not found */
- *xsize_r = -1;
- *ysize_r = -1;
- }
- }
-
-
-
-
- /*
- choose a floor or ceiling texture
- */
-
- void ChooseFloorTexture( BCINT x0, BCINT y0, char *prompt, BCINT listsize, char **list, char *name)
- {
- if (UseMouse)
- HideMousePointer();
- SwitchToVGA256();
- /* if we only have a 320x200x256 VGA driver, we must change x0 and y0. Yuck! */
- if (GfxMode > -2) {
- x0 = -1;
- y0 = -1;
- }
- InputNameFromListWithFunc( x0, y0, prompt, listsize, list, 5, name, 64, 64, DisplayFloorTexture);
- SwitchToVGA16();
- if (UseMouse)
- ShowMousePointer();
- }
-
-
-
- /*
- choose a wall texture
- */
-
- void ChooseWallTexture( BCINT x0, BCINT y0, char *prompt, BCINT listsize, char **list, char *name)
- {
- if (UseMouse)
- HideMousePointer();
- SwitchToVGA256();
- /* if we only have a 320x200x256 VGA driver, we must change x0 and y0. Yuck! */
- if (GfxMode > -2) {
- x0 = 0;
- y0 = -1;
- }
- InputNameFromListWithFunc( x0, y0, prompt, listsize, list, 11, name, 256, 128, DisplayWallTexture);
- SwitchToVGA16();
- if (UseMouse)
- ShowMousePointer();
- }
-
-
-
- /*
- function used by qsort to sort the sprite names
- */
- int SortSprites( const void *a, const void *b)
- {
- return strcmp( *((char **)a), *((char **)b));
- }
-
-
-
- /*
- choose a "sprite"
- */
-
- void ChooseSprite( BCINT x0, BCINT y0, char *prompt, char *sname)
- {
- MDirPtr dir;
- BCINT n, listsize;
- char **list;
- char name[ 9];
-
- /* count the names */
- dir = FindMasterDir( MasterDir, "S_START");
- dir = dir->next;
- for (n = 0; dir && strcmp(dir->dir.name, "S_END"); n++)
- dir = dir->next;
- listsize = n;
- /* get the actual names from master dir. */
- dir = FindMasterDir( MasterDir, "S_START");
- dir = dir->next;
- list = (char**) GetMemory( listsize * sizeof( char *));
- for (n = 0; n < listsize; n++) {
- list[ n] = (char*) GetMemory( 9 * sizeof( char));
- strncpy( list[ n], dir->dir.name, 8);
- list[ n][ 8] = '\0';
- dir = dir->next;
- }
- qsort( list, listsize, sizeof( char *), SortSprites);
- if (sname != NULL)
- strncpy( name, sname, 8);
- else
- strcpy( name, list[ 0]);
- /* if (UseMouse)
- HideMousePointer(); */
- SwitchToVGA256();
- /* if we only have a 320x200x256 VGA driver, we must change x0 and y0. Yuck! */
- if (GfxMode > -2) {
- x0 = 0;
- y0 = -1;
- }
- ForgetAfter = TRUE;
- InputNameFromListWithFunc( x0, y0, prompt, listsize, list, 11, name, 256, 128, DisplayPic);
- /* SwitchToVGA16();
- if (UseMouse)
- ShowMousePointer(); */
- for (n = 0; n < listsize; n++)
- FreeMemory( list[ n]);
- FreeMemory( list);
- }
-