home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Toolkit for DOOM
/
DOOMTOOL.ISO
/
editors
/
dme301.zip
/
SOURCE.ZIP
/
EDITS.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-03
|
62KB
|
2,858 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 <graphics.h>
#include <string.h>
#include <math.h>
#include <limits.h>
#include <alloc.h>
#include <stdlib.h>
#include "dme.h"
#include "dme2.h"
#define F_MIN -63
#define F_MAX 63
#define C_MIN -63
#define C_MAX 63
void update_button(int num);
int linetype_picklist(int num);
void reprint_linetype(int num, int yy, int max);
int select_fc_textr(char far *farname, int x, int y);
int find_new_id(void);
void add_num_to_list(int num, int *index);
void change_sidedefs(void);
int save_sidedef(int sd1, int sd2, int mask, int sector, int xoffset,
int yoffset, char *top_tx, char *mid_tx, char *bottom_tx);
void mark_sector(int num);
void mark_line_vertexes(void);
uint default_attrib=3;
int default_linedef_type=0;
int default_linedef_trig=0;
int default_sidedef_sector=-1;
int default_xoffset=0;
int default_yoffset=0;
char default_top[8]="-";
char default_middle[8]="STARTAN3";
char default_bottom[8]="-";
char default_floor_name[9]="FLOOR4_8";
char default_ceiling_name[9]="CEIL3_5";
int default_light=255;
int default_sector_trig=0;
int default_fheight=0;
int default_cheight=72;
int default_sector_type=0;
int lightc=0, lightv=255;
int floorc=0, floorv=0;
int ceilc=0, ceilv=72;
int floortc=0, ceiltc=0;
char floort[9] = "FLOOR4_8";
char ceilt[9] = "CEIL3_5";
int cur_line;
int *counts=0;
char saved_image[125]; /* point image background save buffer */
int vertex_edit(void)
{
char image[125], msg[61], count;
int i, dx, dy, x, y, color, num;
int cur_vertex=-1, new_vertex, dist, dist_min;
mouse_on();
mark_mask = 1;
sync_time();
if (marked)
{
sprintf(msg, "%d vertexes marked", *mvertexes);
toptext2("", msg);
}
while(1)
{
mouse_check();
dist_min = 10;
new_vertex = -1;
for (i=0; i<max_vertex; i++)
{
dx = adjvx[i];
dy = adjvy[i];
if (dx < point_size ||
dy < point_size ||
dx > maxx-point_size ||
dy > maxy-point_size) continue;
dx -= mousex;
dy -= mousey;
if ((dist = abs(dx) + abs(dy)) < dist_min)
{
dist_min = dist;
new_vertex = i;
}
}
if (new_vertex != cur_vertex)
{
mouse_off();
if (cur_vertex != -1)
putimage(x - point_size, y - point_size, saved_image, 0);
if (new_vertex != -1)
{
x = adjvx[new_vertex];
y = adjvy[new_vertex];
getimage(x - point_size, y - point_size, x + point_size,
y + point_size, saved_image);
for (i=0, num=0; i<l_size; i++)
if (linedefs[i].v1 == new_vertex ||
linedefs[i].v2 == new_vertex)
num++;
sprintf(msg, "Vertex #%d at (%d, %d), connecting %d line",
new_vertex, vertexes[new_vertex].x, vertexes[new_vertex].y,
num);
if (num != 1)
strcat(msg, "s");
toptext(msg);
} else
toptext("");
mouse_on();
cur_vertex = new_vertex;
}
if (wait(8))
{
if (*mvertexes)
{
plot_marked(-1);
if (cur_vertex != -1)
color_num--;
}
if (cur_vertex != -1)
plot_colored_point(x, y, rand_color());
}
if (button_status & 1)
{
if (*mvertexes)
{
move_marked();
return 0;
}
if (cur_vertex != -1)
cur_drag = cur_vertex;
else if ((cur_drag = add_vertex()) == -1)
{
error("Maximum number of vertexes reached");
draw_map();
return 0;
}
edit_mode = 3;
mouse_off();
return 0;
}
if (button_status & 2)
{
if (marked)
{
sort_marked(mvertexes);
i = *mvertexes;
while (i--)
del_vertex(mvertexes[i+2]);
unmark_all();
cur_vertex = -1;
draw_map();
await_release_on();
} else if (cur_vertex != -1) {
del_vertex(cur_vertex);
cur_vertex = -1;
mouse_off();
draw_map();
await_release_on();
}
}
if (button_status & 8)
{
if (cur_vertex != -1)
putimage(x - point_size, y - point_size, saved_image, 0);
if (!boxmark(0) && cur_vertex != -1)
mark_vertex(cur_vertex);
toptext2("", "");
return 0;
}
if (keypress)
{
mouse_off();
plot_marked(255);
if (cur_vertex != -1)
putimage(x - point_size, y - point_size, saved_image, 0);
toptext2("", "");
return keypress;
}
}
}
int vertex_drag(void)
{
char image[125];
int i, x, y, num, color, count;
x = adjvx[cur_drag];
y = adjvy[cur_drag];
mouse_on();
while (1)
{
if (!(mouse_check() & 1))
{
vertexes[cur_drag].x = x = re_x();
vertexes[cur_drag].y = y = re_y();
for (i=0; i<max_vertex; i++)
if (x == vertexes[i].x && y == vertexes[i].y && i != cur_drag)
{
for (num=0; num<l_size; num++)
{
if (linedefs[num].v1 == i)
linedefs[num].v1 = cur_drag;
if (linedefs[num].v2 == i)
linedefs[num].v2 = cur_drag;
}
del_vertex(i);
if (cur_drag > i)
cur_drag--;
i--;
}
mouse_off();
draw_map();
edit_mode = 2;
return 0;
}
if (button_status & 2)
{
del_vertex(cur_drag);
mouse_off();
draw_map();
await_release();
edit_mode = 2;
return 0;
}
if (wait(8))
plot_colored_point(x, y, rand_color());
}
}
int line_edit(void)
{
char msg[125], msg2[90], bitstr[17], top_texture[9], mid_texture[9];
char bottom_texture[9];
int i, j, line, dist, dist_min, new_line, counter, id;
int new_vertex, cur_vertex=-1, color, count, len;
int v1, v2, x, y, x1, x2, y1, y2, dx, dy;
int side, old_side=-1, sidedef, old_sd=-1;
uint angle, mask;
char bits[] = "0123456789ABCDEF";
char *side_dir[] = { "Left", "Right" };
char *sides[] = { "0 sidedefs", "1 sidedef", "2 sidedefs" };
cur_line = -1;
mark_mask = 3;
mouse_on();
sync_time();
while (1)
{
mouse_check();
dist_min = 15;
new_line = -1;
for (i=0; i<ll_size; i++) /* this loop finds the closest line */
{ /* to the mouse cursor */
line = llines[i];
v1 = linedefs[line].v1;
v2 = linedefs[line].v2;
x1 = adjvx[v1];
x2 = adjvx[v2];
y1 = adjvy[v1];
y2 = adjvy[v2];
dist = line_dist(x1, y1, x2, y2);
if (dist < dist_min)
{
dist_min = dist;
new_line = line;
if (side = (line_side(line, mouse_x, mouse_y) < 0))
side = 1;
}
}
if (side)
sidedef = linedefs[new_line].sd1;
else
sidedef = linedefs[new_line].sd2;
new_vertex = -1;
dist_min = 8;
for (i=0; i<max_vertex; i++)
{
dx = adjvx[i];
dy = adjvy[i];
if (dx < point_size ||
dy < point_size ||
dx > maxx-point_size ||
dy > maxy-point_size) continue;
dx -= mousex;
dy -= mousey;
if ((dist = abs(dx) + abs(dy)) < dist_min)
{
dist_min = dist;
new_vertex = i;
}
}
if (new_vertex != cur_vertex)
{
mouse_off();
if (cur_vertex != -1)
putimage(x - point_size, y - point_size, saved_image, 0);
if (new_vertex != -1)
{
x = adjvx[new_vertex];
y = adjvy[new_vertex];
getimage(x - point_size, y - point_size, x + point_size,
y + point_size, saved_image);
}
mouse_on();
cur_vertex = new_vertex;
}
if (new_line != cur_line || sidedef != old_sd || side != old_side)
{
if (cur_line != -1)
{
mouse_off();
line_and_seg(cur_line);
mouse_on();
}
cur_line = new_line;
old_sd = sidedef;
old_side = side;
if (new_line != -1)
{
strcpy(bitstr, "................");
for (i=0, mask=1; i<16; i++, mask <<= 1)
{
if (linedefs[new_line].attrib & mask)
bitstr[i] = bits[i];
}
count = 0;
if (linedefs[new_line].sd1 != -1)
count++;
if (linedefs[new_line].sd2 != -1)
count++;
dx = vertexes[linedefs[new_line].v1].x -
vertexes[linedefs[new_line].v2].x;
dy = vertexes[linedefs[new_line].v1].y -
vertexes[linedefs[new_line].v2].y;
len = sqrt((double) dx * dx + (double) dy * dy);
sprintf(msg, "Line #%d: type: %d, attrib: %s, trig: %d, "
"%s, len: %d", new_line, linedefs[new_line].type, bitstr,
linedefs[new_line].trig, sides[count], len);
if (sidedef == -1)
sprintf(msg2, "%s (No Sidedef)", side_dir[side]);
else {
for (i=0; i<8; i++)
{
top_texture[i] = sidedefs[sidedef].top[i];
mid_texture[i] = sidedefs[sidedef].middle[i];
bottom_texture[i] = sidedefs[sidedef].bottom[i];
}
top_texture[8] = mid_texture[8] = bottom_texture[8] = 0;
sprintf(msg2, "%s Sidedef #%d: sector: %d, textures: (%s) "
"(%s) (%s), shift: (%d,%d)", side_dir[side], sidedef,
sidedefs[sidedef].sector, top_texture, mid_texture,
bottom_texture, sidedefs[sidedef].xoffset,
sidedefs[sidedef].yoffset);
if (strlen(msg2) * 8 > maxx)
sprintf(msg2, "%s Sidef #%d: sec: %d, txtrs: (%s) (%s) "
"(%s), sh: (%d,%d)", side_dir[side], sidedef,
sidedefs[sidedef].sector, top_texture, mid_texture,
bottom_texture, sidedefs[sidedef].xoffset,
sidedefs[sidedef].yoffset);
}
setcolor(255);
toptext2(msg, msg2);
} else toptext2("", "");
}
if (wait(8))
{
if (marked)
{
plot_marked(-1);
color_num--;
}
rand_color();
if (new_line != -1)
{
draw_line(new_line, SOLID_LINE);
mouse_redraw();
if (id = linedefs[new_line].trig) /* is linked to a sector */
for (i=0; i<sec_size; i++)
if (sectors[i].trig == id) /* sector linked to */
for (j=0; j<l_size; j++)
if (((line = linedefs[j].sd1) != -1 &&
sidedefs[line].sector == i) ||
((line = linedefs[j].sd2) != -1 &&
sidedefs[line].sector == i))
draw_line(j, DOTTED_LINE);
mouse_redraw();
}
if (new_vertex != -1)
plot_colored_point(x, y, stagger_color());
}
if (button_status & 1)
{
if (*mvertexes)
{
move_marked();
return 0;
}
if (l_size == l_max)
{
void far *ptr;
if (!l_max)
ptr = get_farmem(20 * sizeof(struct l_struct), "Linedefs");
else
ptr = resize_farmem(linedefs, (l_max+20) *
sizeof(struct l_struct), "Linedefs");
if (!ptr)
return -1;
linedefs = ptr;
l_max += 20;
}
if (cur_vertex != -1)
{
edit_mode = 5;
cur_drag = cur_vertex;
} else {
if ((cur_drag = add_vertex()) == -1)
{
error("Maximum number of vertexes reached");
draw_map();
return 0;
}
if (cur_line != -1)
edit_mode = 6;
else
edit_mode = 5;
}
mouse_off();
if (cur_line != -1)
line_and_seg(cur_line);
return 0;
}
if (button_status & 2)
{
if (marked)
{
sort_marked(mlinedefs);
i = *mlinedefs;
while (i--)
del_line(mlinedefs[i+2]);
unmark_all();
cur_line = cur_vertex = -1;
mouse_off();
draw_map();
await_release_on();
} else if (cur_line != -1) {
del_line(cur_line);
cur_line = cur_vertex = -1;
mouse_off();
draw_map();
await_release_on();
} else if (cur_vertex != -1) {
del_vertex(cur_vertex);
cur_line = cur_vertex = -1;
mouse_off();
draw_map();
await_release_on();
}
}
if ((button_status & 4) && (cur_line != -1 || *mlinedefs))
{
mouse_off();
if (cur_vertex != -1)
putimage(x-point_size, y-point_size, saved_image, 0);
if (cur_line != -1)
line_and_seg(cur_line);
i = 0;
if (sidedef == linedefs[new_line].sd1)
i++;
change_line(new_line, i);
cur_vertex = -1;
cur_line = -1;
}
if (button_status & 8)
{
mouse_off();
if (cur_vertex != -1)
putimage(x-point_size, y-point_size, saved_image, 0);
if (cur_line != -1)
line_and_seg(cur_line);
if (!boxmark(1))
{
if (cur_line != -1)
{
mark_line(cur_line);
mark_line_vertexes();
} else if (cur_vertex != -1)
mark_vertex(cur_vertex);
}
toptext2("", "");
return 0;
}
if (keypress)
{
if (keypress == 1034)
{
fix_sidedefs(new_line);
continue;
}
if (keypress == 'f')
{
v1 = linedefs[new_line].v1;
linedefs[new_line].v1 = linedefs[new_line].v2;
linedefs[new_line].v2 = v1;
i = linedefs[new_line].sd1;
linedefs[new_line].sd1 = linedefs[new_line].sd2;
linedefs[new_line].sd2 = i;
flip_line(new_line);
cur_line = -1;
continue;
}
if (keypress == 1033)
{
v1 = linedefs[new_line].v1;
linedefs[new_line].v1 = linedefs[new_line].v2;
linedefs[new_line].v2 = v1;
cur_line = -1;
continue;
}
plot_marked(255);
if (cur_vertex != -1)
putimage(x-point_size, y-point_size, saved_image, 0);
mouse_off();
if (cur_line != -1)
line_and_seg(cur_line);
toptext2("", "");
return keypress;
}
}
}
/* edit mode 5: Add line between 2 points (make second point if needed) */
int line_drag1(void)
{
char image[125], image2[125], saved_point[125];
int i, num, color, xcolor, last_color, count, cur_vertex=-1, new_vertex;
int dx, dy, x1, y1, x2, y2, x3, y3, dist_min, dist, cross_status;
x1 = x3 = adjvx[cur_drag];
y1 = y3 = adjvy[cur_drag];
mouse_on();
while (1)
{
mouse_check();
dist_min = 10;
new_vertex = -1;
for (i=0; i<max_vertex; i++)
{
dx = adjvx[i];
dy = adjvy[i];
if (dx < point_size ||
dy < point_size ||
dx > maxx-point_size ||
dy > maxy-point_size) continue;
dx -= mousex;
dy -= mousey;
if ((dist = abs(dx) + abs(dy)) < dist_min)
{
dist_min = dist;
new_vertex = i;
}
}
if (new_vertex != cur_vertex)
{
mouse_off();
if (cur_vertex != -1)
putimage(x2 - point_size, y2 - point_size, saved_point, 0);
if (new_vertex != -1)
{
x2 = adjvx[new_vertex];
y2 = adjvy[new_vertex];
getimage(x2 - point_size, y2 - point_size, x2 + point_size,
y2 + point_size, saved_point);
}
mouse_on();
cur_vertex = new_vertex;
}
if (new_vertex == -1)
{
x2 = crossx + 2;
y2 = crossy + 2;
}
if (!(button_status & 1))
{
if (cur_vertex == cur_drag)
{
mouse_off();
edit_mode = 4;
return 0;
}
if (cur_vertex == -1)
{
if ((cur_vertex = add_vertex()) == -1)
{
error("Maximum number of vertexes reached");
draw_map();
edit_mode = 4;
return 0;
}
} else
for (i=0; i<max_vertex; i++)
{
dx = linedefs[i].v1;
dy = linedefs[i].v2;
if ((cur_drag == dx && cur_vertex == dy) ||
(cur_drag == dy && cur_vertex == dx)) /* check for overlap */
{
draw_map(); /* leave without creating it */
edit_mode = 4;
return 0;
}
}
linedefs[l_size].v1 = cur_drag;
linedefs[l_size].v2 = cur_vertex;
linedefs[l_size].attrib = 3;
linedefs[l_size].type = 0;
linedefs[l_size].trig = 0;
linedefs[l_size].sd1 = -1;
linedefs[l_size].sd2 = -1;
if (!match_line(cur_drag, cur_vertex))
if (match_line(cur_vertex, cur_drag))
{
num = linedefs[l_size].sd1;
linedefs[l_size].sd1 = linedefs[l_size].sd2;
linedefs[l_size].sd2 = num;
}
flip_line(l_size);
l_size++;
mouse_off();
draw_map();
edit_mode = 4;
return 0;
}
if (button_status & 2)
{
mouse_off();
draw_map();
await_release();
edit_mode = 4;
return 0;
}
if (wait(8))
{
color = rand_color();
mouse_off();
setwritemode(XOR_PUT);
if (x2 == x3 && y2 == y3)
setcolor(color ^ last_color);
else {
if (x1 != x3 || y1 != y3)
{
setcolor(last_color);
line(x1, y1, x3, y3);
}
x3 = x2;
y3 = y2;
setcolor(color);
}
if (x1 != x2 || y1 != y2)
line(x1, y1, x2, y2);
setwritemode(COPY_PUT);
last_color = color;
color = stagger_color();
for (i=0; i<4; i++)
image[i] = image2[i] = point_ptr[point_size-1][i];
for (i=4; i<125; i++)
{
if (point_ptr[point_size-1][i])
image[i] = image2[i] = color;
else {
image[i] = saved_image[i];
image2[i] = saved_point[i];
}
}
putimage(x1-point_size, y1-point_size, image, 0);
if (cur_vertex != -1)
putimage(x2-point_size, y2-point_size, image2, 0);
if ((crossx+2 == x1 && crossy+2 == y1) || (crossx+2 == x2 &&
crossy+2 == y2))
cross_on = 0;
mouse_on();
}
}
}
/* edit mode 6: split existing line in half */
int line_drag2(void)
{
char image[125], image2[125];
int i, num, color, last_color, count, cur_vertex=-1;
int dx, dy, x, y, xx, yy, x1, y1, x2, y2, xx1, yy1, xx2, yy2;
int dist_min, dist, vertex1;
x1 = adjvx[linedefs[cur_line].v1];
x2 = adjvx[linedefs[cur_line].v2];
y1 = adjvy[linedefs[cur_line].v1];
y2 = adjvy[linedefs[cur_line].v2];
setcolor(0);
line(x1, y1, x2, y2);
vertex1 = max_vertex - 1;
x = xx = adjvx[vertex1];
y = yy = adjvy[vertex1];
getimage(x - point_size, y - point_size, x + point_size,
y + point_size, saved_image);
setwritemode(XOR_PUT);
last_color = rand_color();
line(x, y, x1, y1);
line(x, y, x2, y2);
setwritemode(COPY_PUT);
mouse_on();
while (1)
{
mouse_check();
dist_min = 10;
cur_vertex = -1;
for (i=0; i<max_vertex-1; i++)
{
dx = adjvx[i];
dy = adjvy[i];
if (dx < point_size ||
dy < point_size ||
dx > maxx-point_size ||
dy > maxy-point_size) continue;
dx -= mousex;
dy -= mousey;
if ((dist = abs(dx) + abs(dy)) < dist_min)
{
dist_min = dist;
cur_vertex = i;
}
}
if (cur_vertex == -1)
{
x = crossx + 2;
y = crossy + 2;
} else {
x = adjvx[cur_vertex];
y = adjvy[cur_vertex];
}
if (!(button_status & 1))
{
if (cur_vertex == linedefs[cur_line].v1 ||
cur_vertex == linedefs[cur_line].v2)
{
mouse_off();
putimage(xx - point_size, yy - point_size, saved_image, 0);
max_vertex--;
v_size--;
edit_mode = 4;
return 0;
}
if (cur_vertex != -1)
{
vertex1 = cur_vertex;
max_vertex--;
v_size--;
} else {
vertexes[vertex1].x = re_x();
vertexes[vertex1].y = re_y();
}
linedefs[l_size].v1 = vertex1;
linedefs[l_size].v2 = linedefs[cur_line].v2;
linedefs[l_size].attrib = linedefs[cur_line].attrib;
linedefs[l_size].type = linedefs[cur_line].type;
linedefs[l_size].trig = linedefs[cur_line].trig;
if ((num = linedefs[cur_line].sd1) == -1)
linedefs[l_size].sd1 = -1;
else if ((linedefs[l_size].sd1 = add_sidedef(num)) == -1)
return 0;
if ((num = linedefs[cur_line].sd2) == -1)
linedefs[l_size].sd2 = -1;
else if ((linedefs[l_size].sd2 = add_sidedef(num)) == -1)
return 0;
flip_line(l_size);
l_size++;
linedefs[cur_line].v2 = vertex1;
mouse_off();
draw_map();
edit_mode = 4;
return 0;
}
if (button_status & 2)
{
mouse_off();
draw_map();
max_vertex--;
v_size--;
await_release();
edit_mode = 4;
return 0;
}
if (wait(8))
{
color = rand_color();
mouse_off();
if (x == xx && y == yy)
setcolor(color ^ last_color);
else {
setcolor(last_color);
setwritemode(XOR_PUT);
if (x1 != xx || y1 != yy)
line(xx, yy, x1, y1);
if (x2 != xx || y2 != yy)
line(xx, yy, x2, y2);
setwritemode(COPY_PUT);
setcolor(color);
putimage(xx - point_size, yy - point_size, saved_image, 0);
getimage(x - point_size, y - point_size, x + point_size,
y + point_size, saved_image);
xx = x;
yy = y;
}
setwritemode(XOR_PUT);
if (x != x1 || y != y1)
line(x, y, x1, y1);
if (x != x2 || y != y2)
line(x, y, x2, y2);
setwritemode(COPY_PUT);
last_color = color;
mouse_on();
plot_colored_point(x, y, stagger_color());
}
}
}
void line_and_seg(int num)
{
int i, j, id, sd;
wall_color(num);
draw_line(num, SOLID_LINE);
if (id = linedefs[num].trig) /* is linked to a sector */
for (i=0; i<sec_size; i++)
if (sectors[i].trig == id) /* sector linked to */
for (j=0; j<l_size; j++)
if (((sd = linedefs[j].sd1) != -1 &&
sidedefs[sd].sector == i) ||
((sd = linedefs[j].sd2) != -1 &&
sidedefs[sd].sector == i))
{
wall_color(j);
draw_line(j, DOTTED_LINE);
}
return;
}
void change_line(int line_num, int cur_side)
{
char msg[8192], name[9], top_tx1[9], mid_tx1[9], bottom_tx1[9];
char msg2[20], top_tx2[9], mid_tx2[9], bottom_tx2[9];
int i, j, sd1, sd2, type, trig, button, b2, sd, num, x=57, y=29;
int sector1, sector2, xoffset1, xoffset2, yoffset1, yoffset2;
int init=0;
uint attrib;
int bits[] = { 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, 0x100 };
char *text1 = "%s\t\n"
"@ Sector facing: %d\n"
"@ Top texture: %s\n"
"@ Middle texture: %s\n"
"@ Bottom texture: %s\n"
"@ Horz. shift: %d\n"
"@ Vert. shift: %d\n\n"
"@ Delete this sidedef\n";
if (line_num == -1)
{
attrib = default_attrib;
type = default_linedef_type;
trig = default_linedef_trig;
sd1 = sd2 = -1;
} else {
attrib = linedefs[line_num].attrib;
type = linedefs[line_num].type;
trig = linedefs[line_num].trig;
sd1 = linedefs[line_num].sd1;
if (sd1 != -1)
{
sector1 = sidedefs[sd1].sector;
xoffset1 = sidedefs[sd1].xoffset;
yoffset1 = sidedefs[sd1].yoffset;
for (i=0; i<8; i++)
{
top_tx1[i] = sidedefs[sd1].top[i];
mid_tx1[i] = sidedefs[sd1].middle[i];
bottom_tx1[i] = sidedefs[sd1].bottom[i];
}
}
sd2 = linedefs[line_num].sd2;
if (sd2 != -1)
{
sector2 = sidedefs[sd2].sector;
xoffset2 = sidedefs[sd2].xoffset;
yoffset2 = sidedefs[sd2].yoffset;
for (i=0; i<8; i++)
{
top_tx2[i] = sidedefs[sd2].top[i];
mid_tx2[i] = sidedefs[sd2].middle[i];
bottom_tx2[i] = sidedefs[sd2].bottom[i];
}
}
}
top_tx1[8] = top_tx2[8] = mid_tx1[8] = mid_tx2[8] =
bottom_tx1[8] = bottom_tx2[8] = 0;
if (*mlinedefs)
init = -2;
set_button_statuses(init);
redraw:
set_window(x, y, 1);
strcpy(msg+4096, "^?? <Unknown effect> ??");
for (i=0; i<linetype_max; i++)
if (linetypes[i] == type)
_fstrcpy(msg+2048, linetype_names[i]);
strcpy(msg+4097, msg+2053);
msg[4101+x] = 0;
strcat(msg+4096, "\t");
strcpy(msg+2052, ")");
if (*mlinedefs)
strcpy(msg, "Change marked Linedefs\t");
else
sprintf(msg, "Change Linedef #%d\t", line_num);
text_to_window(0, 0, msg, x);
sprintf(msg, "@ Type: %-3d (%-15s @ Trigger id: %-4d @ Auto\t",
type, msg+2048, trig);
text_to_window(0, 3, msg, x);
text_to_window(0, 5, msg+4096, x);
text_to_window(1, 7,
"@ Players and monster can't cross this line\n"
"@ Monsters can't cross this line\n"
"@ Transparent Sidedef textures allowed in line\n"
"@ Top texture is not pegged\n"
"@ Bottom texture is not pegged\n"
"@ Show line as a wall on automap (Secret door)\n"
"@ Sound doesn't cross this line\n"
"@ Line never appears on the automap\n"
"@ Line already discovered on the automap\n", 0);
if (sd2 == -1)
strcpy(msg, "Left Sidedef: none\t\n"
"@ Add Sidedef\t");
else
{
if (sd2 == -2)
strcpy(msg2, "Left Sidedef: new");
else
sprintf(msg2, "Left Sidedef: %d", sd2);
sprintf(msg, text1, msg2, sector2, top_tx2, mid_tx2,
bottom_tx2, xoffset2, yoffset2);
}
text_to_window(1, 18, msg, 26);
if (sd1 == -1)
sprintf(msg, "Right Sidedef: none\t\n"
"@ Add Sidedef\t");
else
{
if (sd1 == -2)
strcpy(msg2, "Right Sidedef: new");
else
sprintf(msg2, "Right Sidedef: %d", sd1);
sprintf(msg, text1, msg2, sector1, top_tx1, mid_tx1,
bottom_tx1, xoffset1, yoffset1);
}
text_to_window(30, 18, msg, 26);
draw_buttons();
set_window_bars();
i = (win.left + win.right) / 2;
j = win.top + 177;
setcolor(82);
line(win.left-1, j, win.right, j);
setcolor(86);
line(win.left, j+1, win.right, j+1);
line(i, j+1, i, win.bottom);
setcolor(82);
line(i-1, j, i-1, win.bottom);
setcolor(254);
if (line_num != -1)
outtextxy(win.left + cur_side*232 - cur_side, win.top + 179, "\x07");
for (i=0; i<9; i++)
if (attrib & bits[i])
b.pos[i+3].on = 1;
while (1)
{
draw_buttons();
if ((button = b2 = window_check()) < 0)
break;
if (button_status & 4 && *mlinedefs && button != 2)
{
if (b.pos[button].status == -2)
b.pos[button].status = 0;
else
b.pos[button].status = -2;
continue;
}
if (button == 0)
{
update_button(0);
if (true_button & 1)
{
type = linetype_picklist(type);
draw_map();
goto redraw;
} else {
type = get_number(9, 3, type, 999, 0);
strcpy(msg, "?? <Unknown effect> ??");
for (i=0; i<linetype_max; i++)
if (linetypes[i] == type)
_fstrcpy(msg+4096, linetype_names[i]);
strcpy(msg, msg+4101);
msg[x] = 0;
strcpy(msg+4099, ")");
erase_text(win.left + 116, win.top + 34, 15);
text(win.left + 116, win.top + 34, msg + 4096);
i = midx - strlen(msg) * 4;
erase_text(win.left + 4, win.top + 54, x);
text_color = 128;
text(i, win.top + 54, msg);
text_color = 255;
}
continue;
}
if (button == 1)
{
update_button(1);
draw_buttons();
trig = get_number(45, 3, trig, 9999, -999);
continue;
}
if (button == 2)
{
trig = find_new_id();
sprintf(msg, "%d", trig);
erase_text(win.left + 364, win.top + 34, 4);
text(win.left + 364, win.top + 34, msg);
update_button(1);
continue;
}
if (button > 2 && button < 12)
{
update_button(button);
attrib ^= bits[button-3];
b.pos[button].on ^= 1;
continue;
}
button -= 12;
i = 7;
if (sd2 == -1)
i = 1;
if (button < i)
{
if (sd2 == -1)
{
sd2 = -2;
sector2 = -1;
strncpy(top_tx2, default_top, 8);
strncpy(mid_tx2, default_middle, 8);
strncpy(bottom_tx2, default_bottom, 8);
xoffset2 = default_xoffset;
yoffset2 = default_yoffset;
i = 7;
while (i--)
b.pos[19+i].status = b.pos[13+i].status;
for (i=0; i<7; i++)
b.pos[12+i].status = init;
b.pos[18].status = 0;
goto redraw;
}
switch (button)
{
case 0:
update_button(b2);
sector2 = get_number(19, 20, sector2, 32767, 0);
break;
case 1:
update_button(b2);
if (select_wall_textr(top_tx2, 156, 214))
goto redraw;
break;
case 2:
update_button(b2);
if (select_wall_textr(mid_tx2, 156, 224))
goto redraw;
break;
case 3:
update_button(b2);
if (select_wall_textr(bottom_tx2, 156, 234))
goto redraw;
break;
case 4:
update_button(b2);
xoffset2 = get_number(19, 24, xoffset2, 32767, 0);
break;
case 5:
update_button(b2);
yoffset2 = get_number(19, 25, yoffset2, 32767, 0);
break;
case 6:
sd2 = -1;
b.pos[12].status = 0;
for (i=0; i<7; i++)
b.pos[13+i].status = b.pos[19+i].status;
goto redraw;
}
} else {
button -= i;
if (sd1 == -1)
{
sd1 = -2;
sector1 = -1;
strncpy(top_tx1, default_top, 8);
strncpy(mid_tx1, default_middle, 8);
strncpy(bottom_tx1, default_bottom, 8);
xoffset1 = default_xoffset;
yoffset1 = default_yoffset;
for (i=0; i<6; i++)
b.pos[b2 + i].status = init;
b.pos[b2 + 6].status = 0;
goto redraw;
}
j = linedefs[line_num].sd1;
switch (button)
{
case 0:
update_button(b2);
sector1 = get_number(48, 20, sector1, 32767, 0);
break;
case 1:
update_button(b2);
if (select_wall_textr(top_tx1, 388, 214))
goto redraw;
break;
case 2:
update_button(b2);
if (select_wall_textr(mid_tx1, 388, 224))
goto redraw;
break;
case 3:
update_button(b2);
if (select_wall_textr(bottom_tx1, 388, 234))
goto redraw;
break;
case 4:
update_button(b2);
xoffset1 = get_number(48, 24, xoffset1, 32767, 0);
break;
case 5:
update_button(b2);
yoffset1 = get_number(48, 25, yoffset1, 32767, 0);
break;
case 6:
sd1 = -1;
b.pos[b2 - 6].status = 0;
goto redraw;
}
}
}
draw_map();
await_release_on();
if (button == -99)
{
set_button_statuses(0);
return;
}
if (*mlinedefs)
{
int mask=0, mask1=0, mask2=0;
for (i=0; i<9; i++)
if (b.pos[i+3].status == -2)
{
mask |= bits[i];
attrib &= ~bits[i];
}
b2 = 13;
if (sd2 != -1)
b2 = 19;
for (i=0; i<7; i++)
{
if (b.pos[i+12].status != -2)
mask2 |= bits[i];
if (b.pos[i+b2].status != -2)
mask1 |= bits[i];
}
for (i=0; i<*mlinedefs; i++)
{
j = mlinedefs[i+2];
if (!b.pos[0].status)
linedefs[j].type = type;
if (!b.pos[1].status)
linedefs[j].trig = trig;
linedefs[j].attrib &= mask;
linedefs[j].attrib |= attrib;
linedefs[j].sd1 = save_sidedef(linedefs[j].sd1, sd1, mask1,
sector1, xoffset1, yoffset1, top_tx1, mid_tx1, bottom_tx1);
linedefs[j].sd2 = save_sidedef(linedefs[j].sd2, sd2, mask2,
sector2, xoffset2, yoffset2, top_tx2, mid_tx2, bottom_tx2);
flip_line(j);
}
} else {
linedefs[line_num].attrib = attrib;
linedefs[line_num].type = type;
linedefs[line_num].trig = trig;
linedefs[line_num].sd1 = save_sidedef(linedefs[line_num].sd1, sd1,
255, sector1, xoffset1, yoffset1, top_tx1, mid_tx1, bottom_tx1);
linedefs[line_num].sd2 = save_sidedef(linedefs[line_num].sd2, sd2,
255, sector2, xoffset2, yoffset2, top_tx2, mid_tx2, bottom_tx2);
flip_line(line_num);
}
set_button_statuses(0);
return;
}
int save_sidedef(int sd1, int sd2, int mask, int sector, int xoffset,
int yoffset, char *top_tx, char *mid_tx, char *bottom_tx)
{
int i;
if (sd2 == -1)
{
if (sd1 != -1 && mask & 1)
{
del_sidedef(sd1);
sd1 = -1;
}
} else {
if (sd1 == -1)
{
if (!(mask & 64))
return -1;
sd1 = add_sidedef(-1);
}
if (mask & 1)
sidedefs[sd1].sector = sector;
if (mask & 16)
sidedefs[sd1].xoffset = xoffset;
if (mask & 32)
sidedefs[sd1].yoffset = yoffset;
if (mask & 2)
_fstrncpy(sidedefs[sd1].top, top_tx, 8);
if (mask & 4)
_fstrncpy(sidedefs[sd1].middle, mid_tx, 8);
if (mask & 8)
_fstrncpy(sidedefs[sd1].bottom, bottom_tx, 8);
}
return sd1;
}
void update_button(int num)
{
b.pos[num].status = 0;
setcolor(255);
circle(b.pos[num].x, b.pos[num].y, 4);
return;
}
int linetype_picklist(int num)
{
char msg[80], spc[] = " ", temp[6];
int i, list_num, list_size, columns, rows, type;
int old_num, new_num, cross_status;
int index[50], x, y, shp;
rows = (maxy / 20) * 2 - 3; /* make sure it's an odd number */
columns = linetype_name_size + 5;
list_size = (rows - 7) / 2;
cross_status = cross_on;
cross_on = 0;
list_num = 0;
re_list:
if (list_num < 0)
list_num += linetype_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 = linetypes[list_num];
sprintf(msg, "%s%d: %Fs\n", &spc[strlen(itoa(type, temp, 10))-1],
type, linetype_names[list_num]);
text_to_window(0, i*2+5, msg, 0);
index[i] = list_num++;
if (list_num >= linetype_max)
list_num = 0;
}
draw_buttons();
set_cancel_bar();
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 && abs(mousey - win.top - i*20 - 57) < 10)
new_num = i;
}
if (new_num != old_num)
{
if (old_num != -1)
{
mouse_off();
setcolor(255);
reprint_linetype(index[old_num], old_num, columns);
mouse_on();
}
if (new_num != -1)
{
mouse_off();
setcolor(254);
reprint_linetype(index[new_num], new_num, columns);
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 linetypes[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 linetypes[index[new_num]];
}
}
}
void reprint_linetype(int num, int yy, int max)
{
char msg[81], spc[] = " ", temp[6];
int x, y, type;
x = win.left + 4;
y = win.top + yy * 20 + 54;
type = linetypes[num];
sprintf(msg, "%s%d: %Fs", &spc[strlen(itoa(type, temp, 10))-1],
type, linetype_names[num]);
erase_text(x, y, max);
outtextxy(x, y, msg);
return;
}
int select_wall_textr(char far *farname, int x, int y)
{
char name[9];
int i, redraw=0;
if (true_button & 1)
{
for (i=0; i<8; i++)
name[i] = farname[i];
name[8] = 0;
wall_textr_pick(name);
redraw = 1;
} else
get8(name, "-", win.left + x, win.top + y);
for (i=0; i<8; i++)
if (!(farname[i] = name[i]))
break;
while (i < 8)
farname[i++] = 0;
return redraw;
}
int sector_edit(void)
{
char temp[41], msg[125], msg2[80], name1[9], name2[9];
int i, j, dist, dist_min, old_sec=-2, sector, counter, id;
int count, line;
int v1, v2, x1, x2, y1, y2, dx, dy;
uint mask;
mark_mask = 2;
sync_time();
mouse_on();
while (1)
{
mouse_check();
dist_min = INT_MAX;
sector = line = -1;
for (i=0; i<l_size; i++)
{
v1 = linedefs[i].v1;
v2 = linedefs[i].v2;
x1 = adjvx[v1];
x2 = adjvx[v2];
y1 = adjvy[v1];
y2 = adjvy[v2];
if (x1 == x2)
continue; /* vertical line, so skip it */
if ((x1 < mousex) && (x2 < mousex))
continue; /* doesn't cross line */
if ((x1 > mousex) && (x2 > mousex))
continue; /* doesn't cross line either */
dist = line_dist2(mousex, mousey, x1, y1, x2, y2);
if (dist < 0)
continue; /* wrong direction now */
if (dist > dist_min)
continue;
if (dist == dist_min) /* time to decide which one we want.. */
if (line_least_angle(line, i, 16384) == line)
continue;
dist_min = dist;
line = i;
if (x1 > x2)
id = linedefs[i].sd1;
else
id = linedefs[i].sd2;
sector = -1;
if (id != -1)
sector = sidedefs[id].sector;
}
if (sector >= sec_size)
sector = -1;
if (sector != old_sec)
{
if (old_sec > -1)
{
mouse_off();
redraw_sector(old_sec);
mouse_on();
}
old_sec = sector;
if (edit_mode == 7)
{
if (sector != -1)
{
for (i=0; i<8; i++)
{
name1[i] = sectors[sector].floor_name[i];
name2[i] = sectors[sector].ceiling_name[i];
}
name1[8] = name2[8] = 0;
sprintf(msg, "Sector #%d: light: %d, floor: %d (%s), "
"ceiling: %d (%s)", sector, (sectors[sector].light+8)/16,
round8(sectors[sector].floor), name1,
round8(sectors[sector].ceiling), name2);
sprintf(msg2, "effect: %d, trig: %d", sectors[sector].type,
sectors[sector].trig);
if (*msectors)
{
sprintf(temp, ", %d sectors marked", *msectors);
strcat(msg2, temp);
}
toptext2(msg, msg2);
} else toptext2("", "");
} else {
*msg = *msg2 = 0;
if (lightc != -9)
{
sprintf(temp, "Light => %d <%+d> ", (lightv + 8) / 16,
lightc);
strcat(msg, temp);
}
if (floorc != -9 || floortc)
{
strcat(msg, "Floor => ");
if (floorc != -9)
{
sprintf(temp, "%d <%+d> ",
round8(floorv), floorc);
strcat(msg, temp);
}
if (floortc)
{
sprintf(temp, "(%s) ", floort);
strcat(msg, temp);
}
strcat(msg, " ");
}
if (ceilc != -9 || ceiltc)
{
strcat(msg, "Ceiling => ");
if (ceilc != -9)
{
sprintf(temp, "%d <%+d> ",
round8(ceilv), ceilc);
strcat(msg, temp);
}
if (ceiltc)
{
sprintf(temp, "(%s)", ceilt);
strcat(msg, temp);
}
}
if (sector != -1)
{
for (i=0; i<8; i++)
{
name1[i] = sectors[sector].floor_name[i];
name2[i] = sectors[sector].ceiling_name[i];
}
name1[8] = name2[8] = 0;
sprintf(msg2, "Sector #%d: light: %d, floor: %d (%s), "
"ceiling: %d (%s)", sector, (sectors[sector].light+8)/16,
round8(sectors[sector].floor), name1,
round8(sectors[sector].ceiling), name2);
}
toptext2(msg, msg2);
}
}
if (wait(8))
{
if (marked)
{
plot_marked(-1);
color_num--;
}
rand_color();
if (sector != -1)
{
for (i=0; i<ll_size; i++)
{
line = llines[i];
if ((j = linedefs[line].sd1) != -1 &&
sidedefs[j].sector == sector)
draw_line(line, SOLID_LINE);
if ((j = linedefs[line].sd2) != -1 &&
sidedefs[j].sector == sector)
draw_line(line, SOLID_LINE);
}
if (j = sectors[sector].trig)
for (i=0; i<ll_size; i++)
{
line = llines[i];
if (linedefs[line].trig == j)
draw_line(line, DOTTED_LINE);
}
mouse_redraw();
}
}
if (edit_mode == 7)
{
if (button_status & 1)
{
if (*mvertexes)
{
move_marked();
return 0;
}
mouse_off();
redraw_sector(sector);
if (make_sector(mouse_x, mouse_y, -1, 0, 0) == -1)
draw_map();
mouse_on();
old_sec = sec_size - 1;
}
if (button_status & 2)
{
if (marked)
{
sort_marked(msectors);
i = *msectors;
while (i--)
del_sector(msectors[i+2]);
unmark_all();
draw_map();
await_release();
return 0;
}
if (sector != -1)
{
mouse_off();
redraw_sector(sector);
mouse_on();
i = s_size;
while (i--)
{
if ((j = linedefs[i].sd1) != -1)
if (sidedefs[j].sector == sector)
{
del_sidedef(j);
linedefs[i].sd1 = -1;
}
if ((j = linedefs[i].sd2) != -1)
if (sidedefs[j].sector == sector)
{
del_sidedef(j);
linedefs[i].sd2 = -1;
}
}
old_sec = -2;
}
}
if ((button_status & 4) && (sector != -1 || *msectors))
{
mouse_off();
if (sector != -1)
redraw_sector(sector);
change_sector(sector);
}
if (button_status & 8)
{
mouse_off();
if (sector != -1)
redraw_sector(sector);
if (!boxmark(5))
if (sector != -1)
mark_sector(sector);
draw_map();
return 0;
}
} else {
if ((button_status & 9) && (sector != -1))
{
if (lightc != -9)
{
sectors[sector].light = lightv;
if ((lightv += lightc * 16) > 255)
lightv = 255;
if (lightv < 0)
lightv = 0;
}
if (floorc != -9)
{
sectors[sector].floor = floorv;
floorv += floorc * 8;
}
if (ceilc != -9)
{
sectors[sector].ceiling = ceilv;
ceilv += ceilc * 8;
}
if (floortc)
{
for (i=0; i<8; i++)
if (!(sectors[sector].floor_name[i] = floort[i]))
break;
while (i++ < 7)
sectors[sector].floor_name[i] = 0;
}
if (ceiltc)
{
for (i=0; i<8; i++)
if (!(sectors[sector].ceiling_name[i] = ceilt[i]))
break;
while (i++ < 7)
sectors[sector].ceiling_name[i] = 0;
}
mouse_off();
redraw_sector(sector);
await_release_on();
old_sec = -2;
}
if (button_status & 6)
{
mouse_off();
if (sector != -1)
redraw_sector(sector);
mouse_on();
edit_mode = 7;
old_sec = -1;
}
}
if (keypress)
{
mouse_off();
plot_marked(255);
if (sector != -1)
redraw_sector(sector);
if (keypress == 27 && edit_mode == 8)
{
edit_mode = 7;
return 0;
}
if (keypress == 'b')
{
blend_sector(sector);
return 0;
}
if (keypress == 'd')
{
make_door(sector);
continue;
}
return keypress;
}
}
}
void redraw_sector(int num)
{
int i, j, l;
for (i=0; i<ll_size; i++)
{
l = llines[i];
if (sidedefs[linedefs[l].sd1].sector == num ||
sidedefs[linedefs[l].sd2].sector == num)
{
wall_color(l);
draw_line(l, SOLID_LINE);
}
}
if (j = sectors[num].trig)
for (i=0; i<ll_size; i++)
{
l = llines[i];
if (linedefs[l].trig == j)
{
wall_color(l);
draw_line(l, SOLID_LINE);
}
}
return;
}
int round8(int num)
{
return ((num + 4) >> 3);
}
void make_door(int sector)
{
int i, sd, temp;
for (i=0; i<l_size; i++)
if ((sd = linedefs[i].sd1) != -1)
if (sidedefs[sd].sector == sector)
{
temp = linedefs[i].v1;
linedefs[i].v1 = linedefs[i].v2;
linedefs[i].v2 = temp;
linedefs[i].sd1 = linedefs[i].sd2;
linedefs[i].sd2 = sd;
}
sectors[sector].ceiling = sectors[sector].floor;
return;
}
void blend_sector(int sector)
{
char floor_textr[9], ceil_textr[9];
char msg[8192], desc[41], name[9];
int i, button, num;
if (sector != -1)
{
lightv = sectors[sector].light;
floorv = sectors[sector].floor;
ceilv = sectors[sector].ceiling;
for (i=0; i<8; i++)
{
floort[i] = sectors[sector].floor_name[i];
ceilt[i] = sectors[sector].ceiling_name[i];
}
}
floort[8] = ceilt[8] = 0;
redraw:
sprintf(msg, "Blend/Copy Sectors\t\n\n"
" Adjust values by: -2 -1 0 +1 +2 \n\n"
" @ Light level: %-5d @ @ @ @ @\n\n"
" @ Floor height: %-5d @ @ @ @ @\n\n"
" @ Ceiling height: %-5d @ @ @ @ @\n\n"
" @ Floor texture: %-8s @\n\n"
" @ Ceiling texture: %-8s @\n\n"
"[ Engage ]\t\n", (lightv + 8) / 16,
round8(floorv), round8(ceilv), floort, ceilt);
window_text1(msg, 1, 0, 4);
b.pos[2].x += 4;
b.pos[4].x += 4;
b.pos[8].x += 4;
b.pos[10].x += 4;
b.pos[14].x += 4;
b.pos[16].x += 4;
draw_buttons();
set_cancel_bar();
if (lightc != -9)
b.pos[3 + lightc].on = 1;
if (floorc != -9)
b.pos[9 + floorc].on = 1;
if (ceilc != -9)
b.pos[15 + ceilc].on = 1;
b.pos[19].on = floortc;
b.pos[21].on = ceiltc;
while ((button = window_check()) > -1)
{
switch (button)
{
case 0:
num = get_number(16, 5, (lightv + 8) / 16, 16, 0) * 16;
if (num == 256)
num = 255;
lightv = num;
break;
case 1:
lightc = change_adjust(3, -2);
break;
case 2:
lightc = change_adjust(3, -1);
break;
case 3:
lightc = change_adjust(3, 0);
break;
case 4:
lightc = change_adjust(3, 1);
break;
case 5:
lightc = change_adjust(3, 2);
break;
case 6:
if ((num = get_number(17, 7, round8(floorv),
F_MAX, F_MIN) * 8) > ceilv)
ceilv = num;
floorv = num;
break;
case 7:
floorc = change_adjust(9, -2);
break;
case 8:
floorc = change_adjust(9, -1);
break;
case 9:
floorc = change_adjust(9, 0);
break;
case 10:
floorc = change_adjust(9, 1);
break;
case 11:
floorc = change_adjust(9, 2);
break;
case 12:
if ((num = get_number(19, 9, round8(ceilv),
C_MAX, C_MIN) * 8) < floorv)
floorv = num;
ceilv = num;
break;
case 13:
ceilc = change_adjust(15, -2);
break;
case 14:
ceilc = change_adjust(15, -1);
break;
case 15:
ceilc = change_adjust(15, 0);
break;
case 16:
ceilc = change_adjust(15, 1);
break;
case 17:
ceilc = change_adjust(15, 2);
break;
case 18:
if (select_fc_textr(floor_textr, 148, 114))
goto redraw;
break;
case 19:
floortc = b.pos[19].on = !b.pos[19].on;
break;
case 20:
if (select_fc_textr(ceil_textr, 164, 134))
goto redraw;
break;
case 21:
ceiltc = b.pos[21].on = !b.pos[21].on;
break;
}
}
if (button == -2)
{
edit_mode = 8;
strcpy(floort, floor_textr);
strcpy(ceilt, ceil_textr);
}
draw_map();
await_release();
return;
}
int change_adjust(int button, int value)
{
int i, on;
on = b.pos[button+value].on;
for (i=-2; i<3; i++)
b.pos[button+i].on = 0;
if (on)
return -9;
b.pos[button+value].on = 1;
return value;
}
void change_sector(int sector)
{
char msg[8192], desc[41], fname[9], cname[9], name[9];
int light, trig, fheight, cheight, type;
int i, button, num, x=56, y=27, init=0;
if (sector != -1)
{
for (i=0; i<8; i++)
{
fname[i] = sectors[sector].floor_name[i];
cname[i] = sectors[sector].ceiling_name[i];
}
fname[8] = cname[8] = 0;
light = sectors[sector].light;
trig = sectors[sector].trig;
fheight = sectors[sector].floor;
cheight = sectors[sector].ceiling;
type = sectors[sector].type;
} else {
for (i=0; i<8; i++)
{
fname[i] = default_floor_name[i];
cname[i] = default_ceiling_name[i];
}
fname[8] = cname[8] = 0;
light = default_light;
trig = default_sector_trig;
fheight = default_fheight;
cheight = default_cheight;
type = default_sector_type;
}
if (*msectors)
init = -2;
set_button_statuses(init);
redraw:
set_window(x, y, 1);
sprintf(msg, "Change sector #%d\t\n\n"
" @ Light level: %-6d @ Trigger id: %-5d @ Auto\n\n"
" @ Floor height: %-6d @ Ceiling height: %d\n\n"
" @ Floor texture: %-8s @ Ceiling texture: %s\n\n"
"Special effects:\t",
sector, (light + 8) / 16, trig, round8(fheight), round8(cheight),
fname, cname);
text_to_window(0, 0, msg, x);
text_to_window(1, 11, "@ 00: None\n"
"@ 01: Light level flickers, random period\n"
"@ 02: Light level pulsates, 1/2 second period\n"
"@ 03: Light level pulsates, 1 second period\n"
"@ 04: Same as (02), also -20% health drop\n"
"@ 05: -10% health drop (Blood3 floor)\n"
"@ 07: -5% health drop (Nukage3 floor)\n"
"@ 08: Light level oscillates\n"
"@ 09: Secret area\n"
"@ 10: Dropping ceiling?\n"
"@ 11: -20% health drop, end episode when dead\n"
"@ 12: Light level oscillates between normal and 0\n"
"@ 13: Strobe light, 1/2 second period\n"
"@ 14: Unknown as of yet\n"
"@ 16: -20% health drop (Lava4/Fwater4 floor)\n", 0);
draw_buttons();
set_window_bars();
while (1)
{
num = type;
if (num == 16)
num--;
if (num > 6)
num--;
if (num >= 0 && num < 15)
b.pos[num+7].on = 1;
if ((button = window_check()) < 0)
break;
if (button_status & 4 && *msectors && button != 2)
{
if (b.pos[button].status == -2)
b.pos[button].status = 0;
else
b.pos[button].status = -2;
if (button > 6)
for (i=7; i<22; i++)
b.pos[i].status = b.pos[button].status;
draw_buttons();
continue;
}
if (button == 0)
{
update_button(0);
num = get_number(16, 3, (light + 8) / 16, 16, 0) * 16;
if (num == 256)
num = 255;
light = num;
continue;
}
if (button == 1)
{
update_button(1);
trig = get_number(42, 3, trig, 32767, 0);
continue;
}
if (button == 2)
{
trig = 0;
trig = find_new_id();
sprintf(msg, "%d", trig);
erase_text(win.left + 340, win.top + 34, 5);
text(win.left + 340, win.top + 34, msg);
update_button(1);
continue;
}
if (button == 3)
{
update_button(3);
if ((num = get_number(17, 5, round8(fheight), F_MAX, F_MIN) * 8)
> cheight)
cheight = num;
fheight = num;
continue;
}
if (button == 4)
{
update_button(4);
if ((num = get_number(46, 5, round8(cheight), C_MAX, C_MIN) * 8)
< fheight)
fheight = num;
cheight = num;
continue;
}
if (button == 5)
{
update_button(5);
if (select_fc_textr(fname, 148, 74))
goto redraw;
continue;
}
if (button == 6)
{
update_button(6);
if (select_fc_textr(cname, 380, 74))
goto redraw;
continue;
}
if (button > 6 && button < 13)
{
type = button - 7;
for (i=7; i<22; i++)
b.pos[i].status = b.pos[i].on = 0;
draw_buttons();
continue;
}
if (button > 12 && button < 21)
{
type = button - 6;
for (i=7; i<22; i++)
b.pos[i].status = b.pos[i].on = 0;
draw_buttons();
continue;
}
if (button == 21)
{
type = 16;
for (i=7; i<22; i++)
b.pos[i].status = b.pos[i].on = 0;
draw_buttons();
continue;
}
}
if (button == -1)
{
if (*msectors)
{
for (i=0; i<*msectors; i++)
{
num = msectors[i+2];
if (!b.pos[0].status)
sectors[num].light = light;
if (!b.pos[1].status)
sectors[num].trig = trig;
if (!b.pos[3].status)
sectors[num].floor = fheight;
if (!b.pos[4].status)
sectors[num].ceiling = cheight;
if (!b.pos[5].status)
_fstrncpy(sectors[num].floor_name, fname, 8);
if (!b.pos[6].status)
_fstrncpy(sectors[num].ceiling_name, cname, 8);
if (b.pos[7].status > -1)
sectors[num].type = type;
}
} else {
sectors[sector].light = light;
sectors[sector].trig = trig;
sectors[sector].floor = fheight;
sectors[sector].ceiling = cheight;
sectors[sector].type = type;
_fstrncpy(sectors[sector].floor_name, fname, 8);
_fstrncpy(sectors[sector].ceiling_name, cname, 8);
}
}
draw_map();
await_release_on();
set_button_statuses(0);
return;
}
int select_fc_textr(char far *farname, int x, int y)
{
char name[9];
int i, redraw=0;
if (true_button & 1)
{
for (i=0; i<8; i++)
name[i] = farname[i];
name[8] = 0;
fc_textr_pick(name);
redraw = 1;
} else
get8(name, "FLOOR5_4", win.left + x, win.top + y);
for (i=0; i<8; i++)
if (!(farname[i] = name[i]))
break;
while (i < 8)
farname[i++] = 0;
return redraw;
}
void del_sector(int num)
{
int i;
sec_size--;
for (i=num; i<sec_size; i++)
sectors[i] = sectors[i+1];
for (i=0; i<s_size; i++)
if (sidedefs[i].sector == num)
sidedefs[i].sector = -1;
return;
}
int make_sector(int x, int y, int line, int side, int sector)
{
char msg[60];
int i, j, sec, max, orig_line, dir, size=0, temp, mode=0;
int v1, v2, minv, xmin, ymin, xmax, ymax, x2, y2;
uint angle;
struct sec_struct deflt_sec = { 0, 72, "FLOOR4_8", "CEIL3_5", 255, 0, 0 };
if (line != -1)
mode = 1; /* recursed for donut fixing */
else {
if (sec_size == sec_max) /* allocate space for new sector */
{
void far *ptr;
if (sec_max)
ptr = resize_farmem(sectors, (sec_max+20) *
sizeof(struct sec_struct), "Sectors");
else
ptr = get_farmem(20 * sizeof(struct sec_struct), "Sectors");
if (!ptr)
{
error("Maximum sectors reached. Can't add one");
return -1;
}
sectors = ptr;
sec_max += 20;
}
sector = sec_size++;
counts = get_mem(sec_size * 2, "counts");
if (!counts)
fatal_error("No memory");
for (i=0; i<sec_size; i++)
counts[i] = 0; /* reset sector count list */
line = inside_poly(x, y, &side, testmode); /* get starting line */
if (temp = outside_detect(line, side))
{
if (temp > 0)
error("The outside void region can't be a sector");
goto return1;
}
xmax = ymax = INT_MIN; /* reset sector bounding box */
xmin = ymin = INT_MAX;
setcolor(96);
}
recalc_outside_part:
orig_line = line;
v1 = minv = linedefs[line].v1;
v2 = linedefs[line].v2;
angle = calc_angle(vertexes[v1].x, vertexes[v1].y,
vertexes[v2].x, vertexes[v2].y);
dir = 0;
do
{
if (dir != side)
{
if ((temp = linedefs[line].sd1) == -1) /* make sidedef if not one */
if ((temp = linedefs[line].sd1 = add_sidedef(-1)) == -1)
goto return1;
} else
if ((temp = linedefs[line].sd2) == -1)
if ((temp = linedefs[line].sd2 = add_sidedef(-1)) == -1)
goto return1;
if (size + 1 < LL_MAX)
llist[size++] = temp; /* build list of sidedefs in sector */
else
{
error("Line list limit has been exceeded");
goto return1;
}
draw_line(line, SOLID_LINE);
if ((temp = vertexes[v2].y) < vertexes[minv].y)
minv = v2; /* track lowest point */
adjust_limit(vertexes[v2].x, temp, &xmin, &ymin, &xmax, &ymax);
dir = find_next_line(&v2, &angle, &line, side);
if (dir == -1)
{
deadend_error();
goto return1;
}
} while (line != orig_line);
for (i=0; i<size; i++)
{
if ((temp = sidedefs[llist[i]].sector) != -1)
{
if (temp >= sec_size || temp < 0)
continue; /* bad sector: out of limits */
else
counts[temp]++; /* track majority sector */
}
sidedefs[llist[i]].sector = sector; /* make it the new sector */
}
if (mode)
return 0; /* end of resursive part */
/* Now, we need to figure out if we are actually on an inside part. If so,
we need to try and find the outside part and then go back and recalculate
it.
*/
if ((orig_line = downward_line(minv, &side, testmode)) != -1)
{
if (side)
temp = linedefs[orig_line].sd1;
else
temp = linedefs[orig_line].sd2;
if (temp != -1 && sidedefs[temp].sector == sector)
{
line = inside_poly(vertexes[minv].x, vertexes[minv].y,
&side, testmode);
goto recalc_outside_part;
}
}
/* This loop runs through all the vertexes inside our new sector. It then
figures out if a line to this vertex is totally inside our sector. If
so, it creates a "donut" sector
*/
for (i=0; i<max_vertex; i++)
{
x = vertexes[i].x;
y = vertexes[i].y;
if (x > xmin && x < xmax && y > ymin && y < ymax)
{
if ((orig_line = downward_line(i, &side, testmode)) == -1)
{
deadend_error();
goto return1;
}
if (side)
temp = linedefs[orig_line].sd1;
else
temp = linedefs[orig_line].sd2;
if (temp != -1 && sidedefs[temp].sector == sector)
continue;
if ((v1 = linedefs[orig_line].v1) == i)
v1 = linedefs[orig_line].v2;
x2 = vertexes[v1].x;
y2 = vertexes[v1].y;
if (x2 > xmin && x2 < xmax && y2 > ymin && y2 < ymax)
{
if ((line = inside_poly(x, y, &temp, testmode)) != -1)
{
if (temp)
temp = linedefs[line].sd1;
else
temp = linedefs[line].sd2;
if (temp != -1 && sidedefs[temp].sector == sector)
{ /* need to merge a donut in */
if (make_sector(x, y, orig_line, side, sector) == -1)
goto return1;
i = 0; /* need to recheck previous groups now */
}
}
}
}
}
/* now, all the sidedefs are set up to our new sector. Time to clean up.
First, we set up the new sector definition
*/
max = 0;
sec = -1;
for (i=0; i<sec_size; i++)
{
if (counts[i] > max) /* find the majority sector # */
{
max = counts[i];
sec = i;
}
counts[i] = 0; /* reset for use again by next part */
}
if (sec != -1)
sectors[sector] = sectors[sec]; /* assume identity of that sector */
else
sectors[sector] = deflt_sec;
/* now, we go though and find out if any sectors are now not used by any
sidedefs, and remove them if so. This will happen if we overwrite all
the sectors references with our new sector. Always a good idea to clean
up after ourselves..
*/
for (i=0; i<s_size; i++)
{
temp = sidedefs[i].sector;
if (temp >= 0 && temp < sec_size)
counts[temp]++;
else
sidedefs[i].sector = -1; /* out of limits, so fix */
}
i = sec_size;
while (i--)
if (!counts[i]) /* sector not used */
{
for (j=i; j<sec_size-1; j++) /* so eliminate it */
sectors[j] = sectors[j+1];
for (j=0; j<s_size; j++)
if (sidedefs[j].sector > i)
sidedefs[j].sector--;
sec_size--;
}
free_mem(counts, "counts");
if (testmode > 1)
return -1; /* cause a redraw of the map */
return 0;
return1:
if (counts)
free_mem(counts, "counts");
counts = 0;
return -1;
}
void plot_colored_point(int x, int y, int color)
{
char image[125];
int i, cross_status;
for (i=0; i<4; i++)
image[i] = point_ptr[point_size-1][i];
for (i=4; i<125; i++)
{
if (point_ptr[point_size-1][i])
image[i] = color;
else
image[i] = saved_image[i];
}
mouse_off();
putimage(x - point_size, y - point_size, image, 0);
cross_status = cross_on;
if (crossx+2 == x && crossy+2 == y)
cross_on = 0;
mouse_on();
cross_on = cross_status;
return;
}
void restore_point(int num)
{
int x, y;
x = adjvx[num] - point_size;
y = adjvy[num] - point_size;
putimage(x, y, saved_image, 0);
return;
}
int find_new_id(void)
{
int i, index=0, num;
for (i=0; i<l_size; i++)
if (num = linedefs[i].trig)
add_num_to_list(num, &index);
for (i=0; i<sec_size; i++)
if (num = sectors[i].trig)
add_num_to_list(num, &index);
num=1;
for (i=0; i<index; i++)
if (num == llist[i])
{
num++;
i = 0; /* start checking all over again */
}
return num;
}
void add_num_to_list(int num, int *index)
{
int i;
for (i=0; i<*index; i++)
if (num == llist[i])
return;
if (*index < LL_MAX)
llist[(*index)++] = num;
return;
}
void change_sidedefs(void)
{
char msg[8192], name[9], top_tx[9], mid_tx[9], bottom_tx[9];
int i, j, type, button, sd, num;
int sector, xoffset, yoffset;
sector = default_sidedef_sector;
xoffset = default_xoffset;
yoffset = default_yoffset;
for (i=0; i<8; i++)
{
top_tx[i] = default_top[i];
mid_tx[i] = default_middle[i];
bottom_tx[i] = default_bottom[i];
}
top_tx[8] = mid_tx[8] = bottom_tx[8] = 0;
redraw:
sprintf(msg, "Change marked Sidedefs\t\n"
"@ Sector facing: %d\n"
"@ Top texture: %s\n"
"@ Middle texture: %s\n"
"@ Bottom texture: %s\n"
"@ Horz. shift: %d\n"
"@ Vert. shift: %d\n\n",
sector, top_tx, mid_tx, bottom_tx, xoffset, yoffset);
window_text1(msg, 1, 0, 0);
draw_buttons();
set_window_bars();
while (1)
{
draw_buttons();
if ((button = window_check()) < 0)
break;
if (button_status & 4)
{
if (b.pos[button].status == -2)
b.pos[button].status = 0;
else
b.pos[button].status = -2;
continue;
}
switch (button)
{
case 0:
update_button(0);
sidedefs[j].sector = get_number(19, 2, sector, 32767, 0);
break;
case 1:
update_button(1);
if (select_wall_textr(top_tx, 156, 34))
goto redraw;
break;
case 2:
update_button(2);
if (select_wall_textr(mid_tx, 156, 44))
goto redraw;
break;
case 3:
update_button(3);
if (select_wall_textr(bottom_tx, 156, 54))
goto redraw;
break;
case 4:
update_button(4);
xoffset = get_number(19, 6, xoffset, 32767, 0);
break;
case 5:
update_button(5);
yoffset = get_number(19, 7, yoffset, 32767, 0);
}
}
draw_map();
await_release_on();
if (button == -99)
return;
for (i=0; i<*msidedefs; i++)
{
if (!b.pos[0].status)
sidedefs[i].sector = sector;
if (!b.pos[1].status)
for (j=0; j<8; j++)
sidedefs[i].top[j] = top_tx[j];
if (!b.pos[2].status)
for (j=0; j<8; j++)
sidedefs[i].middle[j] = mid_tx[j];
if (!b.pos[3].status)
for (j=0; j<8; j++)
sidedefs[i].bottom[j] = bottom_tx[j];
if (!b.pos[4].status)
sidedefs[i].xoffset = xoffset;
if (!b.pos[5].status)
sidedefs[i].yoffset = yoffset;
}
set_button_statuses(0);
return;
}