home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Toolkit for DOOM
/
DOOMTOOL.ISO
/
editors
/
dme301.zip
/
SOURCE.ZIP
/
THINGS.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-11
|
19KB
|
913 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 <stdlib.h>
#include <math.h>
#include <string.h>
#include <graphics.h>
#include <conio.h>
#include "dme.h"
#include "dme2.h"
void mark_thing(int num);
void update_button(int num);
extern int old_mark_color;
extern int thing_rad[96]; /* thing's radius */
int cur_box_color=0; /* color of selection box */
int default_type=2007; /* default type of added things */
int default_angle=0; /* default angle of added things */
int default_flags=7; /* default flags of added things */
uint tshape;
int thing_edit(void)
{
char name[41], msg[81], msg2[81], flags[9];
int i, z, cur_thing=-1, new_thing, dx, dy;
int dis, dis_min, shape_no, num, type;
mark_mask = 4;
mouse_on();
sync_time();
while (1)
{
mouse_check();
dis_min = 15;
new_thing = -1;
for (i=0; i<lthing_count; i++)
{
dx = mousex - lthingx[i];
dy = mousey - lthingy[i];
if ((dis = abs(dx) + abs(dy)) < dis_min)
{
dis_min = dis;
new_thing = i;
}
}
if (new_thing != cur_thing)
{
if (cur_thing != -1)
{
setcolor(cur_box_color);
cur_box_color = 0;
box_local_thing(cur_thing);
}
if (new_thing != -1)
{
strcpy(name, "???");
num = lthing_num[new_thing];
type = things[num].type;
for (i=0; i<thing_max; i++)
{
if (thing_types[i] == type)
{
_fstrcpy(name, thing_names[i]);
break;
}
}
strcpy(flags, "....");
if (things[num].flags & 1)
{
flags[0] = '1';
flags[1] = '2';
}
if (things[num].flags & 2)
flags[2] = '3';
if (things[num].flags & 4)
flags[3] = '4';
if (testmode)
{
strcat(flags, ".....");
if (things[num].flags & 0x8)
flags[4] = 'd';
if (things[num].flags & 0x10)
flags[5] = 'D';
if (things[num].flags & 0x20)
flags[6] = '?';
if (things[num].flags & 0x40)
flags[7] = '?';
if (things[num].flags & 0x80)
flags[8] = '?';
}
sprintf(msg, "Item #%d: Type=%d (%s)", num, type, name);
if (things[num].flags & 0x8)
strcat(msg, " Deaf");
sprintf(msg2, "Angle: %d degrees, Skill levels: %s",
things[num].angle, flags);
if (things[num].flags & 0x10)
strcat(msg2, ", Deathmatch mode thing");
toptext2(msg, msg2);
} else toptext2("", "");
cur_thing = new_thing;
}
if (wait(8))
{
if (cur_thing != -1)
{
z = lthing_num[cur_thing];
for (i=0; i<*mthings; i++)
if (mthings[i+2] == z)
{
z = -9;
break;
}
}
if (*mthings)
{
plot_marked(-1);
if (cur_thing != -1)
color_num--;
}
if (cur_thing != -1)
{
if (z == -9)
i = rand_color() ^ old_mark_color;
else
i = rand_color();
setcolor(i ^ cur_box_color);
cur_box_color = i;
box_local_thing(cur_thing);
}
}
if (button_status & 1)
{
if (*mthings)
{
if (cur_thing != -1)
{
setcolor(cur_box_color);
box_local_thing(cur_thing);
cur_box_color = 0;
}
edit_mode = 1;
return 0;
}
if (cur_thing != -1)
{
edit_mode = 1;
cur_drag = cur_thing;
return 0;
}
if (t_size == t_max)
{
void far *ptr;
if (t_max)
ptr = resize_farmem(things, (t_max+20) * sizeof(struct
t_struct), "Things");
else
ptr = get_farmem(20 * sizeof(struct t_struct), "Things");
if (!ptr)
{
error("Maximum number of Things reached");
draw_map();
return 0;
}
things = ptr;
t_max += 20;
}
things[t_size].x = re_x();
things[t_size].y = re_y();
things[t_size].angle = default_angle;
things[t_size].type = default_type;
things[t_size++].flags = default_flags;
if (things_on == 2)
z = shp_offsets[1];
else
z = shp_offsets[0];
dis = 8 / scalers[scale] * 2;
for (i=0; i<thing_max; i++)
{
if (thing_types[i] == default_type)
{
if (things_on == 2)
z = shp_offsets[thing_shapes[i]+1];
else
z = shp_offsets[thing_shapes[i]];
dis = thing_rad[i] / scalers[scale] * 2;
break;
}
}
lthing_num[lthing_count] = t_size - 1;
lthingx[lthing_count] = crossx + 2;
lthingy[lthing_count] = crossy + 2;
if (things_on == -1)
lthing_offsets[lthing_count] = dis;
else
lthing_offsets[lthing_count] = z;
cur_drag = lthing_count++;
edit_mode = 1;
return 0;
}
if (button_status & 2)
{
if (marked)
{
sort_marked(mthings);
i = *mthings;
while (i--)
del_thing(mthings[i+2]);
unmark_all();
cur_thing = -1;
draw_map();
await_release_on();
} else if (cur_thing != -1) {
del_thing(lthing_num[cur_thing]);
cur_thing = -1;
draw_map();
await_release_on();
}
}
if (button_status & 4)
{
plot_marked(0);
if (cur_thing == -1)
change_thing(-1);
else
change_thing(lthing_num[cur_thing]);
return 0;
}
if (button_status & 8)
{
mouse_off();
if (cur_thing != -1)
{
setcolor(cur_box_color);
box_local_thing(cur_thing);
cur_box_color = 0;
}
if (!boxmark(4) && cur_thing != -1)
mark_thing(cur_thing);
}
if (keypress)
{
if (keypress == 13)
{
if (cur_thing != -1)
{
i = lthing_num[cur_thing];
default_type = things[i].type;
default_angle = things[i].angle;
default_flags = things[i].flags;
}
} else {
mouse_off();
if (cur_thing != -1)
{
setcolor(cur_box_color);
box_local_thing(cur_thing);
cur_box_color = 0;
}
plot_marked(0);
toptext2("", "");
return keypress;
}
}
}
}
void change_thing(int thing)
{
char msg[4096], title[41], desc[41], old_image[4096];
int i, num, type, angle, flags, shape, x=38, y=20, init=0;
int masks[] = { 0x01, 0x02, 0x04, 0x10, 0x8 };
int angles[] = { 90, 135, 45, 180, 0, 225, 315, 270 };
mouse_off();
strcpy(title, "Change default Thing");
type = default_type;
angle = default_angle;
flags = default_flags;
if (thing != -1)
{
sprintf(title, "Change Thing #%d", thing);
type = things[thing].type;
angle = things[thing].angle;
flags = things[thing].flags;
}
if (*mthings)
{
strcpy(title, "Change marked Things");
init = -2;
}
set_button_statuses(init);
relist:
set_window(x, y, 1);
strcpy(desc, "???");
shape = 0;
for (i=0; i<thing_max; i++)
{
if (thing_types[i] == type)
{
_fstrcpy(desc, thing_names[i]);
shape = thing_shapes[i];
break;
}
}
sprintf(msg, "%s\t\n"
"@ Type: %-5d -or- [ Picklist ]\t\n"
"(%s)\t\n", title, type, desc);
text_to_window(0, 0, msg, x);
sprintf(msg, "Angle: %d degrees\n\n"
"90\t"
"135 @ 45 \t"
"@ @\t\n"
"@ @\t\n"
"@ @\t"
"225 @ 315\t"
"270\t\n"
"@ Other\t", angle);
text_to_window(0, 6, msg, 17);
text_to_window(0, 12, "|180 0\n", 0);
text_to_window(17, 9, "Availability:\t\n"
"@ Skill levels 1 & 2\n"
"@ Skill level 3\n"
"@ Skill level 4\n"
"@ Deathmatch mode\n"
"@ Deaf\n", 20);
line(51, 127, 91, 127);
line(71, 109, 71, 145);
line(57, 115, 85, 139);
line(57, 139, 85, 115);
draw_buttons();
set_window_bars();
draw_item(shape, win.left+2, win.top+2, old_image);
while (1)
{
for (i=1; i<15; i++)
b.pos[i].on = 0;
for (i=0; i<8; i++)
if (angle == angles[i])
break;
b.pos[i+1].on = 1;
for (i=0; i<5; i++)
if (flags & masks[i])
b.pos[i+10].on = 1;
if ((num = window_check()) == -1 || num == -99)
break;
if (button_status & 4 && init && num >= 0)
{
if (b.pos[num].status == -2)
b.pos[num].status = 0;
else
b.pos[num].status = -2;
if (num > 0 && num < 10)
for (i=1; i<10; i++)
b.pos[i].status = b.pos[num].status;
draw_buttons();
continue;
}
if (num == 0)
{
update_button(0);
type = get_number(11, 2, type, 32767, 0);
if ((shape = print_typedesc(type)) == thing_max)
shape = 0;
else
shape = thing_shapes[shape];
putimage(win.left+2, win.top+2, old_image, 0);
draw_item(shape, win.left+2, win.top+2, old_image);
continue;
}
if (num == -2)
{
b.pos[0].status = 0;
type = picklist(type);
draw_map();
await_release();
goto relist;
}
if (num < 9)
{
for (i=1; i<10; i++)
update_button(i);
angle = angles[num-1];
print_angle(angle);
continue;
}
if (num == 9)
{
for (i=1; i<10; i++)
update_button(i);
erase_text(win.left + 60, win.top + 64, 13);
angle = get_number(7, 6, angle, 359, 0);
print_angle(angle);
continue;
}
update_button(num);
flags ^= masks[num-10];
}
if (num == -1)
{
if (*mthings)
{
int z, mask=0;
for (i=0; i<5; i++)
if (b.pos[i+10].status)
{
flags &= ~masks[i];
mask |= masks[i];
}
mask |= 0xFFE0;
flags &= 0x001F;
for (i=0; i<*mthings; i++)
{
z = mthings[i+2];
if (!b.pos[0].status)
things[z].type = type;
if (!b.pos[9].status)
things[z].angle = angle;
things[z].flags &= mask;
things[z].flags |= flags;
}
} else if (thing == -1) {
default_type = type;
default_angle = angle;
default_flags = flags;
} else {
things[thing].type = type;
things[thing].angle = angle;
things[thing].flags &= 0xFFE0; /* don't change unknowns */
things[thing].flags |= flags;
}
}
draw_map();
await_release();
set_button_statuses(0);
return;
}
int picklist(int num)
{
char msg[60], dots[] = "....", temp[6];
int i, list_num, list_size, columns, rows, type;
int old_num, new_num, cross_status, repos=0;
int xx[50], yy[50], index[50], x, y, shp;
rows = (maxy / 20) * 2 - 3; /* make sure it's an odd number */
columns = thing_name_size + 13;
list_size = (rows - 7) / 2;
cross_status = cross_on;
cross_on = 0;
list_num = 0;
for (i=0; i<thing_max; i++)
if (thing_types[i] == num)
{
list_num = i - list_size / 2;
repos = list_size / 2 + 1;
break;
}
re_list:
if (list_num < 0)
list_num += thing_max; /* wrap around */
set_window(columns, rows, 0);
text_to_window(0, 0, "Select type:\t\n\n[ Back ]\t", columns);
text_to_window(0, rows-2, "[ More ]\t", columns);
for (i=0; i<list_size; i++)
{
type = thing_types[list_num];
sprintf(msg, "%s%d: %Fs\n", &dots[strlen(itoa(type, temp, 10))-1],
type, thing_names[list_num]);
text_to_window(6, i*2+5, msg, 0);
yy[i] = i * 20 + 57;
xx[i] = draw_thing2( (i & 1) * 24 + 14, yy[i], list_num);
xx[i] += win.left;
yy[i] += win.top;
index[i] = list_num++;
if (list_num >= thing_max)
list_num = 0;
}
draw_buttons();
set_cancel_bar();
if (repos)
{
mousex = xx[repos-1];
mousey = yy[repos-1];
repos = 0;
}
mouse_on();
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+50 && abs(mousey - yy[i]) < 10)
new_num = i;
if (abs(mousex - xx[i]) + abs(mousey - yy[i]) < 16)
new_num = i;
}
if (new_num != old_num)
{
if (old_num != -1)
{
mouse_off();
box_thing(x, y, shp); /* turn off box */
setcolor(255);
reprint_line(index[old_num], old_num, columns-6);
mouse_on();
}
if (new_num != -1)
{
x = xx[new_num];
y = yy[new_num];
shp = shp_offsets[thing_shapes[index[new_num]]];
mouse_off();
box_thing(x, y, shp); /* turn on box */
setcolor(254);
reprint_line(index[new_num], new_num, columns-6);
mouse_on();
}
old_num = new_num;
}
}
if (keypress)
{
if (keypress == 27)
{
mouse_off();
cross_on = cross_status;
return num;
}
if (keypress == 13 && new_num != -1)
{
mouse_off();
cross_on = cross_status;
return thing_types[index[new_num]];
}
if (keypress == 1073) /* page up */
{
list_num -= list_size * 2;
mouse_off();
goto re_list;
}
if (keypress == 1081) /* page down */
{
mouse_off();
goto re_list;
}
if (keypress == 1071) /* home */
{
list_num = 0;
mouse_off();
goto re_list;
}
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)
{
mouse_off();
cross_on = cross_status;
return num;
}
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_list;
}
if (new_num != -1)
{
mouse_off();
cross_on = cross_status;
return thing_types[index[new_num]];
}
}
}
void reprint_line(int num, int yy, int max)
{
char msg[41], dots[] = "....", temp[6];
int x, y, type;
x = win.left + 52;
y = win.top + yy * 20 + 54;
type = thing_types[num];
sprintf(msg, "%s%d: %Fs", &dots[strlen(itoa(type, temp, 10))-1],
type, thing_names[num]);
erase_text(x, y, max);
outtextxy(x, y, msg);
return;
}
int draw_thing2(int xpos, int ypos, int num)
{
char far *shape;
int i, shape_no;
int xsize, ysize; /* size of shape */
int xhalf, yhalf; /* size of half the shape */
shape_no = thing_shapes[num];
if (shape_no > 9 && shape_no < 170) /* monster shape */
shape_no += 4;
if (shape_no >= no_shapes)
fatal_error("shape # out of bounds");
shape = shapes + shp_offsets[shape_no]; /* point to the shape */
xhalf = *shape >> 1; /* quick div by 2 */
yhalf = *(shape+2) >> 1;
if ((xpos - xhalf) < 4)
xpos = xhalf + 4;
if ((xpos + xhalf) > 49)
xpos = 49 - xhalf;
putimage(xpos-xhalf, ypos-yhalf, shape, 3);
return xpos;
}
int print_typedesc(int num)
{
char desc[41];
int i, x, y;
strcpy(desc, "(???)");
for (i=0; i<thing_max; i++)
{
if (thing_types[i] == num)
{
sprintf(desc, "(%Fs)", thing_names[i]);
break;
}
}
x = (win.left + win.right) / 2 - strlen(desc)*4 + 2;
y = win.top + 44;
erase_text(win.left, y, 38);
outtextxy(x, y, desc);
return i;
}
void print_angle(int num)
{
char msg[14];
int x, y;
x = win.left + 60;
y = win.top + 64;
erase_text(x, y, 13);
sprintf(msg, "%d degrees", num);
outtextxy(x, y, msg);
return;
}
void box_local_thing(int num)
{
int m;
if (num == -1) return;
if (m = mouse)
mouse_off();
if (things_on != -1)
box_thing(lthingx[num], lthingy[num], lthing_offsets[num]);
else {
int x, y, x1, y1, x2, y2, rad;
x = lthingx[num];
y = lthingy[num];
rad = lthing_offsets[num];
x1 = x - rad - 1;
y1 = y - rad - 1;
x2 = x + rad + 1;
y2 = y + rad + 1;
setwritemode(XOR_PUT);
line(x1, y1, x2, y1);
line(x1, y1+1, x1, y2-1);
line(x2, y1+1, x2, y2-1);
line(x1, y2, x2, y2);
setwritemode(COPY_PUT);
}
if (m)
mouse_on();
return;
}
void box_thing(int x1, int y1, uint offset)
{
char far *ptr;
int x2, y2;
ptr = shapes + offset;
x1 -= (ptr[0] >> 1) + 1;
y1 -= (ptr[2] >> 1) + 1;
x2 = x1 + ptr[0] + 2;
y2 = y1 + ptr[2] + 2;
setwritemode(XOR_PUT);
line(x1, y1, x2, y1);
line(x1, y1+1, x1, y2-1);
line(x2, y1+1, x2, y2-1);
line(x1, y2, x2, y2);
setwritemode(COPY_PUT);
return;
}
int thing_drag(void)
{
int i, j, z, x, y, dx, dy, dx2, dy2, origx, origy;
origx = x = crossx + 2;
origy = y = crossy + 2;
while (1)
{
if (crossx+2 != x || crossy+2 != y)
{
dx = crossx + 2 - x;
dy = crossy + 2 - y;
dx2 = dx * scalers[scale] / 2;
dy2 = dy * scalers[scale] / 2;
x = crossx + 2;
y = crossy + 2;
if (*mthings)
{
plot_marked(0);
for (i=0; i<*mthings; i++)
{
z = mthings[i+2];
things[z].x += dx2;
things[z].y -= dy2;
for (j=0; j<lthing_count; j++)
if (lthing_num[j] == z)
{
lthingx[j] += dx;
lthingy[j] += dy;
break;
}
}
color_num--;
plot_marked(-1);
} else {
mouse_off();
setcolor(cur_box_color);
box_local_thing(cur_drag);
lthingx[cur_drag] += dx;
lthingy[cur_drag] += dy;
box_local_thing(cur_drag);
mouse_on();
z = lthing_num[cur_drag];
things[z].x += dx2;
things[z].y -= dy2;
}
}
if (wait(8))
{
if (marked)
plot_marked(-1);
else {
i = rand_color();
setcolor(i ^ cur_box_color);
cur_box_color = i;
box_local_thing(cur_drag);
}
}
if (!(mouse_check() & 1))
{
draw_map();
old_mark_color = edit_mode = 0;
return 0;
}
if (button_status & 2)
{
del_thing(cur_drag);
mouse_off();
draw_map();
await_release();
edit_mode = 0;
return 0;
}
}
}
void del_thing(int thing)
{
int i;
if (thing != t_size-1)
for (i=thing; i<t_size-1; i++)
things[i] = things[i+1];
t_size--;
return;
}
void draw_item(int num, int x, int y, char *save)
{
char far *shape;
int xsize, ysize;
shape = shapes + shp_offsets[num]; /* point to the shape */
xsize = *shape;
ysize = *(shape+2);
getimage(x, y, x + xsize, y + ysize, save);
putimage(x, y, shape, 3);
return;
}