home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Toolkit for DOOM
/
DOOMTOOL.ISO
/
editors
/
dme301.zip
/
SOURCE.ZIP
/
TEXTURES.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-07-25
|
26KB
|
1,109 lines
/*
This is a DMapEdit source code module. Though it is copyrighted, you
may modify it and use it for your own personal use, meaning that new
modified code and anything derived from it (such as exe files) doesn't
get distributed to anyone, unless you get my permission first. Code
from this file, or code based on ideas from this file may be used with
other programs, provided that you give credit for it in the source code,
documentation, and 'about' windows or screens, if one exists, for the
programs using it. Giving credit means something like this:
Code from DMapEdit was used in this program
or
Some code for this program was based on ideas presented in DMapEdit
Whatever. Just be sure to mention "DMapEdit" in such a way that it's
self-evident how it was useful to the new program, and be sure to have
"DMapEdit is a trademark of Jason Hoffoss" in the docs. That's all..
*/
#include <stdio.h>
#include <mem.h>
#include <alloc.h>
#include <string.h>
#include <graphics.h>
#include <stdlib.h>
#include "dme.h"
#include "dme2.h"
typedef unsigned char uchar;
int load_textures1(void);
void buffer_pic(uchar far *buffer, int width, int height, int xoffset,
int yoffset, struct pic_struct far *pic);
void draw_fc_texture(int xpos, int ypos, int xsize, int ysize,
int xshift, int yshift, char *name);
void draw_textr(uchar far *ptr, int xpos, int ypos, int xsize, int ysize,
int xshift, int yshift);
char last_name[9]="";
int wall_textr_max=0;
int fc_textr_max=0;
int first_patch;
int last_patch;
extern uchar huge doom_color[256];
extern char doom_path[60]; /* path to doom.wad */
struct texture {
char name[9];
int width;
int height;
struct texture far *next;
int p_size;
struct {
int xoffset;
int yoffset;
int p_index;
} patch[9]; /* actually of variable length */
} far *first_texture;
struct texture far * far *prev_link;
struct patch_struct {
int prev; /* link to previous index */
int next; /* link to next index */
char far *addr;
long offset;
uint len;
} far *ptable;
struct pic_struct {
int xsize;
int ysize;
uint xoffset;
uint yoffset;
long offsets[9]; /* variable size array */
};
struct fc_texture {
char name[9];
long offset;
struct fc_texture far *next;
} far *first_fc_textr;
void load_textures(void)
{
char name[9], *pnames;
int i;
long size;
struct texture far *blank;
struct fc_texture far *ptr, far *tptr, far * far *last_ptr;
struct
{
long ptr;
long len;
char fname[8];
} dir;
first_texture = get_farmem(19, "blank texture");
_fstrcpy(first_texture->name, "-");
first_texture->width = 64;
first_texture->height = 64;
first_texture->p_size = 0;
first_texture->next = NULL;
prev_link = &(first_texture->next);
wall_textr_max = 1;
if (open_wad_seekto("rb", "TEXTURE1"))
goto fatal1;
if (load_textures1() == -1)
goto fatal1;
fseek(fp, dir_ptr, SEEK_SET);
entry_count = dir_size;
if (!wad_seek("TEXTURE2"))
{
fseek(fp, entry_ptr, SEEK_SET);
if (load_textures1() == -1)
{
fclose(fp);
fatal_error("Can't load \"texture2\" subfile");
}
}
fclose(fp);
first_patch = last_patch = -1;
if (open_wad_seekto("rb", "PNAMES"))
goto fatal2;
if ((size = fread_long()) == -1)
goto fatal2;
ptable = get_farmem(size * sizeof(struct patch_struct), "ptable");
pnames = get_mem(size * 8, "pnames");
fread(pnames, 8, size, fp);
for (i=0; i<size; i++)
{
ptable[i].addr = NULL;
ptable[i].offset = 0L;
}
fseek(fp, dir_ptr, SEEK_SET);
entry_count = dir_size;
if (wad_seek("P_START"))
{
fclose(fp);
fatal_error("Texture patch wad entries not found");
}
while (entry_count--)
{
if (!fread(&dir, sizeof(dir), 1, fp))
dir_error();
if (!dir.len)
continue; /* else, read registered patches too */
if (!cmp_entry("P_END", dir.fname))
break;
for (i=0; i<size; i++)
{
if (!cmp_entry(pnames+(i<<3), dir.fname))
{
ptable[i].offset = dir.ptr;
ptable[i].len = dir.len;
break;
}
}
}
fclose(fp);
if (open_wad_seek("rb", "F_START"))
fatal_error("Floor/Ceiling texture entries not found");
last_ptr = &first_fc_textr;
first_fc_textr = NULL;
while (entry_count--)
{
if (!fread(&dir, sizeof(dir), 1, fp))
dir_error();
if (!cmp_entry("F_END", dir.fname))
break;
if (!dir.len)
continue; /* skip headers */
ptr = get_farmem(sizeof(struct fc_texture), "floor/ceiling texture");
if (_fstricmp(dir.fname, name) < 0)
{
last_ptr = &first_fc_textr;
for (tptr=first_fc_textr; tptr; tptr=tptr->next)
{
if (_fstricmp(dir.fname, tptr->name) < 0)
break;
last_ptr = &(tptr->next);
}
}
while (*last_ptr && _fstricmp(dir.fname, (*last_ptr)->name) > 0)
last_ptr = &((*last_ptr)->next);
ptr->next = *last_ptr;
*last_ptr = ptr;
last_ptr = &(ptr->next);
for (i=0; i<8; i++)
ptr->name[i] = name[i] = dir.fname[i];
ptr->name[8] = 0;
ptr->offset = dir.ptr;
fc_textr_max++;
}
fclose(fp);
for (i=0; i<size; i++)
if (!ptable[i].offset)
{
strncpy(name, pnames + (i << 3), 8);
name[8] = 0;
fatal_error("texture list patch \"%s\" not found is wad directory",
name);
}
free_mem(pnames, "pnames");
return;
fatal1:
fclose(fp);
fatal_error("Can't load \"texture1\" subfile");
fatal2:
fclose(fp);
fatal_error("Can't load \"pnames\" subfile");
}
int load_textures1(void)
{
int i, p, p_size;
long size, file_index, offsets[512];
struct texture far *cur_texture, far *tptr;
struct {
char name[8];
long unused1;
int width;
int height;
long unused2;
int p_size;
} header;
struct {
int xoffset;
int yoffset;
int p_index;
int stepdir;
int colormap;
} patch;
file_index = ftell(fp);
if ((size = fread_long()) == -1)
return -1;
if (size > 512)
{
error("Too many textures to track");
return -1;
}
fread(offsets, 4, size, fp); /* get offsets */
for (i=0; i<size; i++)
{
if (ftell(fp) != file_index + offsets[i])
fseek(fp, file_index + offsets[i], SEEK_SET);
fread(&header, sizeof(header), 1, fp);
p = 19 + header.p_size * 6; /* # of bytes for entry */
cur_texture = get_farmem(p, "texture list");
if (_fstricmp(header.name, last_name) < 0)
{
prev_link = &first_texture;
for (tptr=first_texture; tptr; tptr=tptr->next)
{
if (_fstricmp(header.name, tptr->name) < 0)
break;
prev_link = &(tptr->next);
}
}
while (*prev_link && _fstricmp(header.name, (*prev_link)->name) > 0)
prev_link = &((*prev_link)->next);
cur_texture->next = *prev_link; /* insert a link */
*prev_link = cur_texture; /* link last texture to this one */
prev_link = &(cur_texture->next); /* get address to link next */
wall_textr_max++;
_fmemcpy(cur_texture->name, header.name, 8);
_fmemcpy(last_name, header.name, 8);
cur_texture->name[8] = 0;
cur_texture->width = header.width;
cur_texture->height = header.height;
cur_texture->p_size = p_size = header.p_size;
for (p=0; p<p_size; p++)
{
fread(&patch, sizeof(patch), 1, fp);
cur_texture->patch[p].xoffset = patch.xoffset;
cur_texture->patch[p].yoffset = patch.yoffset;
cur_texture->patch[p].p_index = patch.p_index;
}
}
return 0;
}
/* draws a wall texture at screen coord (xpos,ypos). This function has been
written to support multitasking */
int draw_wall_texture(int xpos, int ypos, int xsize, int ysize,
int xshift, int yshift, char *name)
{
static uchar far *ptr=NULL;
static int status=-1;
uchar far *buffer, far *buffer2, far *ptr2;
int i, index, m, width, width2, height, x, y, xx, yy;
long len;
struct texture huge *tptr;
struct pic_struct huge *addr;
if (!name)
goto finished; /* reset call */
tptr = first_texture;
while (_fstricmp(name, tptr->name))
{
tptr = tptr->next;
if (!tptr)
return 1; /* didn't find it */
}
width = tptr->width;
height = tptr->height;
if (status == -1)
{
len = (long) width * height + 4;
ptr = get_farmem(len, "texture image buffer");
buffer = ptr + 4;
if (!ptr)
goto finished;
while (len--)
*(ptr + len) = 0; /* clear image buffer */
*ptr = width - 1; /* setup putimage() parameters */
*(ptr+2) = height - 1;
status++;
return 0;
}
buffer = ptr + 4;
if (status < tptr->p_size)
{
index = tptr->patch[status].p_index;
addr = ptable[index].addr;
if (!addr)
{
len = ptable[index].len;
addr = ptable[index].addr = get_farmem(len, "texture patch");
fp = fopen(iwad, "rb");
fseek(fp, ptable[index].offset, SEEK_SET);
far_read(addr, len);
fclose(fp);
} else { /* is in memory, thus already in list, so take it out */
if (index != last_patch)
{
if (first_patch == index)
first_patch = ptable[index].next;
else
{
ptable[ptable[index].prev].next = ptable[index].next;
ptable[ptable[index].next].prev = ptable[index].prev;
}
}
}
if (index != last_patch)
{
if (first_patch == -1)
first_patch = index;
else
ptable[last_patch].next = index;
ptable[index].prev = last_patch;
last_patch = index;
ptable[index].next = -1; /* new end of list */
}
buffer_pic(buffer, width, height, tptr->patch[status].xoffset,
tptr->patch[status].yoffset, addr);
status++;
return 0;
}
len = (long) width * height;
while (len--)
*(buffer + len) = *(doom_color + *(buffer + len)); /* fix colors */
draw_textr(ptr, xpos, ypos, xsize, ysize, xshift, yshift);
finished:
if (ptr)
free_farmem(ptr, "texture image buffer");
ptr = NULL;
status = -1;
return 1;
}
/* called by the memory management routines, this will remove the oldest
patch from memory, freeing it's memory to make room for some block we
need, but don't have the memory for */
int free_patch(void)
{
if (first_patch == -1)
return -1; /* all patches released, but still not enough memory */
free_farmem(ptable[first_patch].addr, "texture patch");
ptable[first_patch].addr = NULL;
first_patch = ptable[first_patch].next;
return 0; /* return to try again to allocate the memory */
}
/* draws a picture (wall patch) image into the image buffer
More detailed description: This function will draw the patch (pointed to
with *pic) into the image holding buffer (pointed to with *buffer).
It will not wrap around horizontally or vertically.
width = width of the image holding buffer
height = height of the image holding buffer
xoffset = patch x offset from upper left corner of the image holding buffer
yoffset = patch y " " ...
I've highly optimized this from how it originally started, so I'll try
and comment it a bit so you can follow the logic..
*/
void buffer_pic(uchar far *buffer, int width, int height, int xoffset,
int yoffset, struct pic_struct far *pic)
{ /* since both buffers were <64k, I switched to from huge ptrs to far ptrs
This improved the speed quite a bit */
uchar far *ptr, far *end_ptr, far *buf_ptr;
int i, count, x, y, z, xsize;
xsize = pic->xsize; /* faster to use a single variable than to
weave through a structure at every reference */
for (i=0; i<xsize; i++)
{
x = xoffset + i;
if (x >= 0 && x < width) /* if x is out of bounds, skip column */
{
ptr = ((uchar huge *) pic) + pic->offsets[i]; /* set ptr to
column data. Column data is made up of a collection of vertical, one
pixel wide strands. Each strand can have it's own length. */
/* ok, up to this point, iterations hasn't been too bad, but now we need to
start thinking about speed. This code gets run though a lot of times */
while ((y = *ptr++) != 255) /* no more strands, goto next column */
{
y += yoffset;
count = *ptr++;
ptr++; /* skip unused byte */
end_ptr = ptr + count + 1; /* this is where we will find the
next strand */
if (y >= height)
goto next_strand; /* not much chance of this happening, but
if we can take it, it'll save us some time. Even so, we really need it
here for error checking anyway. If the row does start below it's drawing
space, then whoever made the patch did so poorly. */
if (y < 0)
{
if (-y >= count)
goto next_strand; /* this means that the image strand is
above the drawing space, and won't drop into view. So, we can skip to
the next strand. */
count += y; /* adjust pointers, etc */
ptr -= y;
y = 0;
}
buf_ptr = buffer + y * width + x;
if ((z = height - y) < count)
count = z; /* cut strand short */
/* This is the most critical point for speed. Even slightly less efficient
code can cause a noticable difference in speed. So, we want to do as few
checks and well, anything as possible. */
while (count--)
{ /* debugging routines..
if (y < 0)
fatal_error("bug1");
if (y >= height)
fatal_error("bug2");
if (buf_ptr < buffer || buf_ptr > buffer + width * height)
fatal_error("bug3"); */
*buf_ptr = *ptr++;
buf_ptr += width; /* point to next column addr in buffer */
/* y++; ya, this is debugging too */
}
next_strand:
ptr = end_ptr; /* move ptr to the next strand */
}
}
}
return;
}
void wall_textr_pick(char *name)
{
char chr, *names;
int i, j, idx, list_num, list_size, columns, rows, type, repos=0;
int old_num, new_num, cross_status, priority, working_on;
int x, y, tx, ty, *xx, *yy;
struct texture far *tptr;
rows = (maxy / 20) * 2 - 2; /* make sure it's an odd number */
columns = 20;
list_size = (rows - 7) / 2;
cross_status = cross_on;
cross_on = 0;
xx = get_mem(list_size * 2, "xpos_list");
yy = get_mem(list_size * 2, "ypos_list");
names = get_mem(list_size * 9 + 1, "textr_name_list");
list_num = i = 0;
tptr = first_texture;
while (tptr != NULL)
{
if (!_fstricmp(name, tptr->name)) /* found it */
{
list_num = i - list_size / 2;
repos = list_size / 2 + 1;
break;
}
tptr = tptr->next;
i++;
}
re_list:
if (list_num < 0)
list_num += wall_textr_max; /* wrap around */
tptr = first_texture;
for (i=0; i<list_num; i++)
tptr = tptr->next;
re_list1:
set_window1(254, 127, 2);
tx = win.left + 2;
ty = win.top + 2;
setviewport(0, 0, maxx, maxy, 1);
set_window(columns, rows, 0);
text_to_window(0, 0, "Select texture:\t\n\n[ Back ]\t", columns);
text_to_window(0, rows-2, "[ More ]\t", columns);
for (i=0; i<list_size; i++)
{
for (j=0; j<8; j++)
if (chr = tptr->name[j])
*(names + i*9 + j) = chr;
else
break;
*(names + i*9 + j) = '\n';
*(names + i*9 + j + 1) = 0;
text_to_window(11, i*2+5, names + i*9, 0);
*(names + i*9 + j) = 0;
xx[i] = win.left + (i & 1) * 40 + 22;
yy[i] = win.top + i * 20 + 58;
tptr = tptr->next;
if (++list_num == wall_textr_max)
{
list_num = 0;
tptr = first_texture;
}
}
draw_buttons();
set_cancel_bar();
if (repos)
{
mousex = xx[repos-1];
mousey = yy[repos-1];
repos = 0;
}
mouse_on();
draw_wall_texture(0, 0, 0, 0, 0, 0, NULL); /* reset */
working_on = priority = idx = 0;
old_num = -1;
while (mouse_check()); /* wait for mouse button release */
while (1)
{
while (!mouse_check() && !keypress)
{
new_num = -1;
for (i=0; i<list_size; i++)
{
if (mousex > win.left + 90 && abs(mousey - yy[i]) < 10)
new_num = i;
if (abs(mousex - xx[i]) < 19 && abs(mousey - yy[i]) < 19)
new_num = i;
}
if (new_num != old_num)
{
if (old_num != -1)
{
mouse_off();
box_textr(xx[old_num], yy[old_num], 0);
setcolor(255);
erase_text(win.left + 92, yy[old_num] - 4, 8);
outtextxy(win.left + 92, yy[old_num] - 4, names + old_num * 9);
mouse_on();
}
if (new_num != -1)
{
mouse_off();
box_textr(xx[new_num], yy[new_num], 255);
setcolor(254);
erase_text(win.left + 92, yy[new_num] - 4, 8);
outtextxy(win.left + 92, yy[new_num] - 4, names + new_num*9);
if (mousex < win.left + 89)
{
if (!working_on && priority)
draw_wall_texture(0, 0, 0, 0, 0, 0, NULL);
priority = new_num * 9 + 1; /* set up a priority task */
}
mouse_on();
}
old_num = new_num;
}
if (!working_on && priority)
{
if (draw_wall_texture(tx, ty, 256, 128, 0, 0, names+priority-1))
priority = 0;
continue;
}
if (idx < list_size)
{
working_on = 1;
if (draw_wall_texture(xx[idx]-18, yy[idx]-18, 36, 36, 0, 0,
names + idx*9))
{
idx++;
working_on = 0;
}
}
}
if (keypress)
{
if (keypress == 27)
goto leave;
if (keypress == 13 && new_num != -1)
{
mouse_off();
goto select;
}
if (keypress == 1073) /* page up */
{
list_num -= list_size * 2;
mouse_off();
goto re_list;
}
if (keypress == 1081) /* page down */
{
mouse_off();
goto re_list1;
}
if (keypress == 1071) /* home */
{
list_num = 0;
tptr = first_texture;
mouse_off();
goto re_list1;
}
continue; /* end of key checks, below is mouse button pressed */
}
if (mousex < win.canbar + 47 &&
mousex > win.canbar + 2 &&
mousey < win.bottom + 9 &&
mousey > win.bottom - 2)
goto leave;
if (line_dist(bigb.pos[0].x1, bigb.pos[0].y,
bigb.pos[0].x2, bigb.pos[0].y) < 7)
{
list_num -= list_size * 2;
mouse_off();
goto re_list;
}
if (line_dist(bigb.pos[1].x1, bigb.pos[1].y,
bigb.pos[1].x2, bigb.pos[1].y) < 7)
{
mouse_off();
goto re_list1;
}
if (new_num != -1)
{
mouse_off();
break;
}
}
select:
memcpy(name, names + new_num*9, 8);
name[8] = 0;
leave:
free_mem(names, "textr_name_list");
free_mem(yy, "ypos_list");
free_mem(xx, "xpos_list");
cross_on = cross_status;
mouse_off();
draw_map();
return;
}
void box_textr(int x1, int y1, int color)
{
int x2, y2;
x1 -= 19;
y1 -= 19;
x2 = x1 + 37;
y2 = y1 + 37;
setcolor(color);
line(x1, y1, x2, y1);
line(x1, y1, x1, y2);
line(x1, y2, x2, y2);
line(x2, y1, x2, y2);
return;
}
void fc_textr_pick(char *name)
{
char *names;
int i, idx, list_num, list_size, columns, rows, type;
int old_num, new_num, cross_status, priority, repos=0;
int x, y, tx, ty, *xx, *yy;
struct fc_texture far *tptr;
rows = (maxy / 20) * 2 - 2; /* make sure it's an odd number */
columns = 20;
list_size = (rows - 7) / 2;
cross_status = cross_on;
cross_on = 0;
xx = get_mem(list_size * 2, "xpos_list");
yy = get_mem(list_size * 2, "ypos_list");
names = get_mem(list_size * 9 + 1, "textr_name_list");
list_num = i = 0;
tptr = first_fc_textr;
while (tptr != NULL)
{
if (!_fstricmp(name, tptr->name)) /* found it */
{
list_num = i - list_size / 2;
repos = list_size / 2 + 1;
break;
}
tptr = tptr->next;
i++;
}
re_list:
if (list_num < 0)
list_num += fc_textr_max; /* wrap around */
tptr = first_fc_textr;
for (i=0; i<list_num; i++)
tptr = tptr->next;
re_list1:
set_window1(254, 127, 2);
tx = win.left + 2;
ty = win.top + 2;
setviewport(0, 0, maxx, maxy, 1);
set_window(columns, rows, 0);
text_to_window(0, 0, "Select texture:\t\n\n[ Back ]\t", columns);
text_to_window(0, rows-2, "[ More ]\t", columns);
for (i=0; i<list_size; i++)
{
_fmemcpy(names + i*9, tptr->name, 8);
*(names + i*9 + 8) = '\n';
*(names + i*9 + 9) = 0;
text_to_window(11, i*2+5, names + i*9, 0);
*(names + i*9 + 8) = 0;
xx[i] = win.left + (i & 1) * 40 + 22;
yy[i] = win.top + i * 20 + 58;
tptr = tptr->next;
if (++list_num == fc_textr_max)
{
list_num = 0;
tptr = first_fc_textr;
}
}
draw_buttons();
set_cancel_bar();
if (repos)
{
mousex = xx[repos-1];
mousey = yy[repos-1];
repos = 0;
}
mouse_on();
priority = idx = 0;
old_num = -1;
while (mouse_check()); /* wait for mouse button release */
while (1)
{
while (!mouse_check() && !keypress)
{
new_num = -1;
for (i=0; i<list_size; i++)
{
if (mousex > win.left + 90 && abs(mousey - yy[i]) < 10)
new_num = i;
if (abs(mousex - xx[i]) < 19 && abs(mousey - yy[i]) < 19)
new_num = i;
}
if (new_num != old_num)
{
if (old_num != -1)
{
mouse_off();
box_textr(xx[old_num], yy[old_num], 0);
setcolor(255);
erase_text(win.left + 92, yy[old_num] - 4, 8);
outtextxy(win.left + 92, yy[old_num] - 4, names + old_num * 9);
mouse_on();
}
if (new_num != -1)
{
mouse_off();
box_textr(xx[new_num], yy[new_num], 255);
setcolor(254);
erase_text(win.left + 92, yy[new_num] - 4, 8);
outtextxy(win.left + 92, yy[new_num] - 4, names + new_num*9);
if (mousex < win.left + 89)
priority = new_num * 9 + 1; /* set up a priority task */
mouse_on();
}
old_num = new_num;
}
if (priority)
{
draw_fc_texture(tx, ty, 256, 128, 0, 0, names+priority-1);
priority = 0;
continue;
}
if (idx < list_size)
{
draw_fc_texture(xx[idx]-18, yy[idx]-18, 36, 36, 0, 0,
names + idx*9);
idx++;
}
}
if (keypress)
{
if (keypress == 27)
goto leave;
if (keypress == 13 && new_num != -1)
{
mouse_off();
goto select;
}
if (keypress == 1073) /* page up */
{
list_num -= list_size * 2;
mouse_off();
goto re_list;
}
if (keypress == 1081) /* page down */
{
mouse_off();
goto re_list1;
}
if (keypress == 1071) /* home */
{
list_num = 0;
tptr = first_fc_textr;
mouse_off();
goto re_list1;
}
continue; /* end of key checks, below is mouse button pressed */
}
if (mousex < win.canbar + 47 &&
mousex > win.canbar + 2 &&
mousey < win.bottom + 9 &&
mousey > win.bottom - 2)
goto leave;
if (line_dist(bigb.pos[0].x1, bigb.pos[0].y,
bigb.pos[0].x2, bigb.pos[0].y) < 7)
{
list_num -= list_size * 2;
mouse_off();
goto re_list;
}
if (line_dist(bigb.pos[1].x1, bigb.pos[1].y,
bigb.pos[1].x2, bigb.pos[1].y) < 7)
{
mouse_off();
goto re_list1;
}
if (new_num != -1)
{
mouse_off();
break;
}
}
select:
memcpy(name, names + new_num*9, 8);
name[8] = 0;
leave:
free_mem(names, "textr_name_list");
free_mem(yy, "ypos_list");
free_mem(xx, "xpos_list");
cross_on = cross_status;
mouse_off();
draw_map();
return;
}
void draw_fc_texture(int xpos, int ypos, int xsize, int ysize,
int xshift, int yshift, char *name)
{
uchar far *buffer;
int i, far *buffer2;
struct fc_texture far *ptr;
ptr = first_fc_textr;
while (_fstricmp(ptr->name, name))
ptr = ptr->next;
buffer2 = buffer = get_farmem(4100, "texture image buffer");
*buffer2 = *(buffer2 + 1) = 63;
if (!(fp = fopen(iwad, "rb")))
error("error!");
fseek(fp, ptr->offset, SEEK_SET);
far_read(buffer+4, 4096L);
fclose(fp);
for (i=4; i<4100; i++)
*(buffer + i) = *(doom_color + *(buffer + i)); /* fix colors */
draw_textr(buffer, xpos, ypos, xsize, ysize, xshift, yshift);
free_farmem(buffer, "texture image buffer");
return;
}
void draw_textr(uchar far *ptr, int xpos, int ypos, int xsize, int ysize,
int xshift, int yshift)
{
uchar far *buffer, far *buffer2, far *ptr2;
int m, width, width2, height, x, y;
width = *ptr + 1;
height = *(ptr + 2) + 1;
buffer = ptr + 4;
width2 = xsize % width;
if (width2)
{
ptr2 = get_farmem((long) width2 * height + 4, "texture image buffer");
buffer2 = ptr2 + 4;
_fmemcpy(ptr2, ptr, 4);
*ptr2 = width2 - 1;
for (y=0; y<height; y++)
_fmemcpy(buffer2 + y*width2, buffer + y*width, width2);
}
if (m = mouse)
mouse_off();
y = 0;
while (y < ysize)
{
if (y + height > ysize)
*(ptr+2) = *(ptr2+2) = ysize - y - 1;
x = 0;
while (x + width <= xsize)
{
putimage(xpos + x, ypos + y, ptr, 0);
x += width;
}
if (x != xsize)
putimage(xpos + x, ypos + y, ptr2, 0);
y += height;
}
if (m)
mouse_on();
if (width2)
free_farmem(ptr2, "texture image buffer");
return;
}
/* Future expansion..
void draw_textr(char far *buffer, int xpos, int ypos, int xsize, int ysize,
int xshift, int yshift)
{
char far *tl_buf, far *t_buf, far *tr_buf, far *l_buf, far *r_buf;
int height, width, width2;
width = *buffer;
height = *(buffer + 2);
yy = yshift % height;
xshift %= width;
width2 = xsize % width;
ptr2 = get_farmem((long) width2 * height + 4, "texture image buffer");
buffer2 = ptr2 + 4;
_fmemcpy(ptr2, ptr, 4);
*ptr2 = width2 - 1;
for (y=0; y<height; y++)
_fmemcpy(buffer2 + y*width2, buffer + y*width, width2);
if (m = mouse)
mouse_off();
y = 0;
while (y < ysize)
{
if (y + height > ysize)
*(ptr+2) = *(ptr2+2) = ysize - y - 1;
x = 0;
while (x + width <= xsize)
{
putimage(xpos + x, ypos + y, ptr, 0);
x += width;
}
if (x != xsize)
putimage(xpos + x, ypos + y, ptr2, 0);
y += height;
}
if (m)
mouse_on();
} */