- Implemented copy/paste of objects, text and maps

- Changed background of object box to be light grey instead of black
- Made object box buttons look more 3d
- Fixed crash when adding zero-length text
- Size/position match tool now works on text
- Implemented "rollover" context sensitive help
- Toolbox buttons are now highlighted when the mouse moves over them
- Partially implemented snap-to-grid feature (no toolbox button yet, toggle with 'g')
- Implemented AP_BOTH for lines with arrowheads on both ends
- Implement change object type function (RMB on object tool, or 'm')
- Mouse wheel now scrolls object box
- Added two new vector shapes:
	Ellipse
	Filled box
- Added new objects:
	Person
	Truck
	Webcam
	Camera
	Satellite Dish
	Satellite
	Wireless Router
	VPN Concentrator
	Generic circle
This commit is contained in:
Rob Pearce 2005-11-11 12:42:29 +00:00
parent ab5c2e18f5
commit 5983f417a3
6 changed files with 922 additions and 116 deletions

View File

@ -7,15 +7,44 @@ Ideas for future versions:
- Export diagrams to some format which Visio can import
- Perhaps change to SVG for objects
- Add more objects (eg. broadband router, etc)
- Snap-to-grid feature
- Make size+position matching work for text (currently only works on objects)
- Implement a toggle-able traffic flow display (for example, you might click
a button and have arrows appear to show all SMTP mail flows)
Version 1.2:
- Implemented copy/paste of objects, text and maps
- Changed background of object box to be light grey instead of black
- Made object box buttons look more 3d
- Fixed crash when adding zero-length text
- Size/position match tool now works on text
- Implemented "rollover" context sensitive help
- Toolbox buttons are now highlighted when the mouse moves over them
- Partially implemented snap-to-grid feature (no toolbox button yet, toggle with 'g')
- Implemented AP_BOTH for lines with arrowheads on both ends
- Implement change object type function (RMB on object tool, or 'm')
- Mouse wheel now scrolls object box
- Added two new vector shapes:
Ellipse
Filled box
- Added new objects:
Person
Truck
Webcam
Camera
Satellite Dish
Satellite
Wireless Router
VPN Concentrator
Generic circle (replaces "blue square")
- Updated CHANGELOG
Version 1.1:
- Added rollover help text and highlights
- Added object: VPN concentrator
- Added dual-head arrows on lines
- Replaced "grey box" object with "VPN concentrator"
Version 1.0:
- Sub-map list is now scrollable

View File

@ -1,4 +1,4 @@
#define VERSION "1.1"
#define VERSION "1.1a"
#define BUFLEN 512
@ -71,6 +71,8 @@
#define VT_BOX (1)
#define VT_DOT (2)
#define VT_FILL (3)
#define VT_ELLIPSE (4)
#define VT_FILLBOX (5)
#define TRUE (-1)
#define FALSE (0)
@ -99,6 +101,7 @@
#define S_REALLYQUIT (21)
#define S_FILLCOL (22)
#define S_EDITTEXT (23)
#define S_CHANGEOBJECT (24)
#define TB_POINTER (0)

678
netmapr.c
View File

@ -36,6 +36,10 @@ SDL_Color grey2 = { 70, 70, 70, 0};
SDL_Color grey3 = { 50, 50, 50, 0};
SDL_Color grey4 = { 30, 30, 30, 0};
SDL_Color gridhigh = {255, 255, 255, 0};
SDL_Color gridmiddle = {90, 90, 90, 0};
SDL_Color gridlow = {50, 50, 50, 0};
SDL_Cursor *normalmouse;
SDL_Cursor *objmouse;
SDL_Cursor *textmouse;
@ -59,6 +63,12 @@ int copyfrom = -1;
int copymap = -1;
int copytype = T_MAP;
int grid = TRUE;
int gridsize = 10;
SDL_Color gridcol = {0, 0, 0, 0 };
int matchtype = 0;
int numobjtypes = 0;
int numletters = 0;
int numbuttons = 0;
@ -199,7 +209,6 @@ int main (int argc, char **argv) {
break;
}
}
}
} else if ((event.button.button == SDL_BUTTON_MIDDLE) ||
((event.button.button == SDL_BUTTON_LEFT) && (mod & KMOD_CTRL))) {
@ -252,6 +261,27 @@ int main (int argc, char **argv) {
}
}
}
} else if (isonobox(event.button.x, event.button.y)) {
if (event.button.button == SDL_BUTTON_WHEELUP) {
if (obox.pos > 0) {
obox.pos--;
drawobox();
}
} else if (event.button.button == SDL_BUTTON_WHEELDOWN) {
int fitx,fity,fit;
/* figure out how many objects we can fit in the box */
fitx = (obox.width / obox.gridsize);
fity = ((obox.height+3) / obox.gridsize);
fit = fitx * fity;
/* check if incrementing position is okay or not */
if (((obox.pos+1)*3 + fit) <= (numobjtypes+2)) {
obox.pos++;
drawobox();
}
}
} else if (isonobox(event.button.x, event.button.y)) {
}
break;
case SDL_MOUSEBUTTONUP:
@ -307,63 +337,134 @@ int main (int argc, char **argv) {
drawmap();
}
} else if (state == S_MATCHSIZE) {
o = objat(event.button.x, event.button.y);
if (o == -1) {
changestate(S_NONE);
sprintf(statustext, "Size match mode aborted.");
drawstatusbar();
} else {
int n;
/* resize selected item to match one which was clicked */
map[curmap].obj[map[curmap].selecteditem].w = map[curmap].obj[o].w;
map[curmap].obj[map[curmap].selecteditem].h = map[curmap].obj[o].h;
/* adjust offsets on all links to/from object */
for (n = 0; n < map[curmap].numlinks; n++) {
if (map[curmap].olink[n].srcobj == map[curmap].selecteditem) {
map[curmap].olink[n].srcxoff = (map[curmap].obj[o].w / 2);
map[curmap].olink[n].srcyoff = (map[curmap].obj[o].h / 2);
}
if (map[curmap].olink[n].dstobj == map[curmap].selecteditem) {
map[curmap].olink[n].dstxoff = (map[curmap].obj[o].w / 2);
map[curmap].olink[n].dstyoff = (map[curmap].obj[o].h / 2);
if (matchtype == T_OBJECT) {
o = objat(event.button.x, event.button.y);
if (o == -1) {
changestate(S_NONE);
sprintf(statustext, "Size match mode aborted.");
drawstatusbar();
} else {
int n;
/* resize selected item to match one which was clicked */
map[curmap].obj[map[curmap].selecteditem].w = map[curmap].obj[o].w;
map[curmap].obj[map[curmap].selecteditem].h = map[curmap].obj[o].h;
/* adjust offsets on all links to/from object */
for (n = 0; n < map[curmap].numlinks; n++) {
if (map[curmap].olink[n].srcobj == map[curmap].selecteditem) {
map[curmap].olink[n].srcxoff = (map[curmap].obj[o].w / 2);
map[curmap].olink[n].srcyoff = (map[curmap].obj[o].h / 2);
}
if (map[curmap].olink[n].dstobj == map[curmap].selecteditem) {
map[curmap].olink[n].dstxoff = (map[curmap].obj[o].w / 2);
map[curmap].olink[n].dstyoff = (map[curmap].obj[o].h / 2);
}
}
changestate(S_NONE);
sprintf(statustext, "Object #%d resized to match object #%d.",map[curmap].selecteditem,o);
drawmap();
}
} else if (matchtype == T_TEXT) {
o = textat(event.button.x, event.button.y);
if (o == -1) {
changestate(S_NONE);
sprintf(statustext, "Size match mode aborted.");
drawstatusbar();
} else {
int tw,th;
/* resize selected text to match one which was clicked */
map[curmap].textob[map[curmap].selecteditem].h = map[curmap].textob[o].h;
TTF_SizeText(font[map[curmap].textob[o].h], map[curmap].textob[map[curmap].selecteditem].text, &tw,&th);
map[curmap].textob[map[curmap].selecteditem].w = tw;
/* adjust offsets on all links to/from object */
changestate(S_NONE);
sprintf(statustext, "Text #%d resized to match text #%d.",map[curmap].selecteditem,o);
drawmap();
}
changestate(S_NONE);
sprintf(statustext, "Object #%d resized to match object #%d.",map[curmap].selecteditem,o);
drawmap();
}
} else if (state == S_MATCHX) {
o = objat(event.button.x, event.button.y);
if (o == -1) {
changestate(S_NONE);
sprintf(statustext, "X position match mode aborted.");
drawstatusbar();
} else {
/* move selected item to match one which was clicked */
/* match middle of objects! */
map[curmap].obj[map[curmap].selecteditem].x =
(map[curmap].obj[o].x + (map[curmap].obj[o].w/2))
-
(map[curmap].obj[map[curmap].selecteditem].w/2);
changestate(S_NONE);
sprintf(statustext, "Object #%d X relocated to match object #%d.",map[curmap].selecteditem,o);
drawmap();
if (matchtype == T_OBJECT) {
o = objat(event.button.x, event.button.y);
if (o == -1) {
changestate(S_NONE);
sprintf(statustext, "X position match mode aborted.");
drawstatusbar();
} else {
/* move selected item to match one which was clicked */
/* match middle of objects! */
map[curmap].obj[map[curmap].selecteditem].x =
(map[curmap].obj[o].x + (map[curmap].obj[o].w/2))
-
(map[curmap].obj[map[curmap].selecteditem].w/2);
changestate(S_NONE);
sprintf(statustext, "Object #%d X relocated to match object #%d.",map[curmap].selecteditem,o);
drawmap();
}
} else if (matchtype == T_TEXT) {
o = textat(event.button.x, event.button.y);
if (o == -1) {
changestate(S_NONE);
sprintf(statustext, "X position match mode aborted.");
drawstatusbar();
} else {
/* move selected item to match one which was clicked */
/* match middle of text */
map[curmap].textob[map[curmap].selecteditem].x =
(map[curmap].textob[o].x + (map[curmap].textob[o].w/2))
-
(map[curmap].textob[map[curmap].selecteditem].w/2);
/* validate */
if (map[curmap].textob[map[curmap].selecteditem].x < 1) map[curmap].textob[map[curmap].selecteditem].x = 1;
if (map[curmap].textob[map[curmap].selecteditem].x + map[curmap].textob[map[curmap].selecteditem].w > map[curmap].width) map[curmap].textob[map[curmap].selecteditem].x = map[curmap].width - map[curmap].textob[map[curmap].selecteditem].w;
changestate(S_NONE);
sprintf(statustext, "Text #%d X relocated to match text #%d.",map[curmap].selecteditem,o);
drawmap();
}
}
} else if (state == S_MATCHY) {
o = objat(event.button.x, event.button.y);
if (o == -1) {
changestate(S_NONE);
sprintf(statustext, "Y position match mode aborted.");
drawstatusbar();
} else {
/* move selected item to match one which was clicked */
map[curmap].obj[map[curmap].selecteditem].y =
(map[curmap].obj[o].y + (map[curmap].obj[o].h / 2))
-
map[curmap].obj[map[curmap].selecteditem].h/2;
changestate(S_NONE);
sprintf(statustext, "Object #%d Y relocated to match object #%d.",map[curmap].selecteditem,o);
drawmap();
if (matchtype == T_OBJECT) {
o = objat(event.button.x, event.button.y);
if (o == -1) {
changestate(S_NONE);
sprintf(statustext, "Y position match mode aborted.");
drawstatusbar();
} else {
/* move selected item to match one which was clicked */
map[curmap].obj[map[curmap].selecteditem].y =
(map[curmap].obj[o].y + (map[curmap].obj[o].h / 2))
-
map[curmap].obj[map[curmap].selecteditem].h/2;
changestate(S_NONE);
sprintf(statustext, "Object #%d Y relocated to match object #%d.",map[curmap].selecteditem,o);
drawmap();
}
} else if (matchtype == T_TEXT) {
o = textat(event.button.x, event.button.y);
if (o == -1) {
changestate(S_NONE);
sprintf(statustext, "Y position match mode aborted.");
drawstatusbar();
} else {
int curh, copyh;
curh = TTF_FontHeight(font[map[curmap].textob[map[curmap].selecteditem].h]);
copyh = TTF_FontHeight(font[map[curmap].textob[o].h]);
/* move selected item to match one which was clicked */
map[curmap].textob[map[curmap].selecteditem].y =
(map[curmap].textob[o].y + (copyh / 2))
-
(curh / 2);
/* validate */
if (map[curmap].textob[map[curmap].selecteditem].y < 1) map[curmap].textob[map[curmap].selecteditem].y = 1;
if (map[curmap].textob[map[curmap].selecteditem].y + curh > map[curmap].height) map[curmap].textob[map[curmap].selecteditem].y = map[curmap].height - curh - 1;
/* match middle of text */
changestate(S_NONE);
sprintf(statustext, "Text #%d Y relocated to match text #%d.",map[curmap].selecteditem,o);
drawmap();
}
}
} else if (state == S_OBJMOVING) {
/* has mouse actually moved? */
@ -537,11 +638,30 @@ int main (int argc, char **argv) {
} else if (isonobox(event.button.x, event.button.y)) {
int tempx,tempy;
tempx = (event.button.x - obox.x) / obox.gridsize;
tempy = (event.button.y - obox.y) / obox.gridsize;
map[curmap].selectedtype = tempy*obox.gridrowlen + tempx + (obox.pos*3);
if (map[curmap].selectedtype >= numobjtypes) map[curmap].selectedtype = numobjtypes-1;
sprintf(statustext,"Object type '%s' selected.\n",objtype[map[curmap].selectedtype].name);
tempx = (event.button.x - obox.x) / (obox.gridsize+3);
tempy = (event.button.y - obox.y) / (obox.gridsize+3);
if (state == S_CHANGEOBJECT) {
int seltype;
seltype = tempy*obox.gridrowlen + tempx + (obox.pos*3);
if (seltype >= numobjtypes) seltype = numobjtypes-1;
if (map[curmap].selecteditemtype != T_OBJECT) {
sprintf(statustext, "Must select an object to change the type of!");
drawstatusbar();
} else if (map[curmap].selecteditem == -1) {
sprintf(statustext, "Must select an object to change the type of!");
drawstatusbar();
} else {
sprintf(statustext, "Object #%d type changed from '%s' to '%s'.", map[curmap].selecteditem, objtype[map[curmap].obj[map[curmap].selecteditem].type].name, objtype[seltype].name);
map[curmap].obj[map[curmap].selecteditem].type = seltype;
state = S_NONE;
drawtoolbox();
drawmap();
}
} else {
map[curmap].selectedtype = tempy*obox.gridrowlen + tempx + (obox.pos*3);
if (map[curmap].selectedtype >= numobjtypes) map[curmap].selectedtype = numobjtypes-1;
sprintf(statustext,"Object type '%s' selected.\n",objtype[map[curmap].selectedtype].name);
}
drawstatusbar();
drawobox();
@ -669,17 +789,25 @@ int main (int argc, char **argv) {
break;
case TB_MATCHSIZE:
if (map[curmap].selecteditem != -1) {
if (map[curmap].selecteditemtype == T_OBJECT) {
changestate(S_MATCHSIZE);
drawmap();
switch (map[curmap].selecteditemtype) {
case T_OBJECT:
case T_TEXT:
matchtype = map[curmap].selecteditemtype;
changestate(S_MATCHSIZE);
drawmap();
break;
}
}
break;
case TB_MATCHX:
if (map[curmap].selecteditem != -1) {
if (map[curmap].selecteditemtype == T_OBJECT) {
changestate(S_MATCHX);
drawmap();
switch (map[curmap].selecteditemtype) {
case T_OBJECT:
case T_TEXT:
matchtype = map[curmap].selecteditemtype;
changestate(S_MATCHX);
drawmap();
break;
}
}
break;
@ -885,6 +1013,17 @@ int main (int argc, char **argv) {
boxy = toolbox.y + (tempy*(toolbox.gridsize+3));
selection = tempy*toolbox.gridrowlen + tempx;
switch (selection) {
case TB_ADDOBJ:
if (map[curmap].selecteditemtype != T_OBJECT) {
sprintf(statustext, "Must select an object to change the type of first!");
drawstatusbar();
} else if (map[curmap].selecteditem == -1) {
sprintf(statustext, "Must select an object to change the type of first!");
drawstatusbar();
} else {
changestate(S_CHANGEOBJECT);
}
break;
case TB_FGCOL:
changestate(S_FGCOL);
drawmap();
@ -1022,7 +1161,7 @@ int main (int argc, char **argv) {
drawstatusbar();
break;
case TB_ADDOBJ:
sprintf(statustext, "LMB = Add an object to the map");
sprintf(statustext, "LMB = Add an object to the map, RMB = Change object type");
drawstatusbar();
break;
case TB_ADDTEXT:
@ -1048,15 +1187,15 @@ int main (int argc, char **argv) {
drawstatusbar();
break;
case TB_MATCHSIZE:
sprintf(statustext, "LMB = Match size of current selection to next object clicked");
sprintf(statustext, "LMB = Match size of current selection to next item clicked");
drawstatusbar();
break;
case TB_MATCHX:
sprintf(statustext, "LMB = Match horizontal position of currently selected object to next object clicked");
sprintf(statustext, "LMB = Match horizontal position of currently selected item to next item clicked");
drawstatusbar();
break;
case TB_MATCHY:
sprintf(statustext, "LMB = Match vertical position of currently selected object to next object clicked");
sprintf(statustext, "LMB = Match vertical position of currently selected item to next item clicked");
drawstatusbar();
break;
case TB_DRILLDOWN:
@ -1217,6 +1356,11 @@ int main (int argc, char **argv) {
changestate(S_ADDOBJ);
}
}
if (c == 'm') { /* modify object type */
if (state == S_NONE) {
changestate(S_CHANGEOBJECT);
}
}
if (c == 't') { /* add text */
if (state == S_NONE) {
changestate(S_ADDTEXT);
@ -1271,28 +1415,50 @@ int main (int argc, char **argv) {
}
if (c == 'x') {
if (map[curmap].selecteditem != -1) {
if (map[curmap].selecteditemtype == T_OBJECT) {
changestate(S_MATCHX);
drawmap();
switch (map[curmap].selecteditemtype) {
case T_OBJECT:
case T_TEXT:
matchtype = map[curmap].selecteditemtype;
changestate(S_MATCHX);
drawmap();
break;
}
}
}
if (c == 'y') {
if (map[curmap].selecteditem != -1) {
if (map[curmap].selecteditemtype == T_OBJECT) {
changestate(S_MATCHY);
drawmap();
switch (map[curmap].selecteditemtype) {
case T_OBJECT:
case T_TEXT:
matchtype = map[curmap].selecteditemtype;
changestate(S_MATCHY);
drawmap();
break;
}
}
}
if (c == 'b') {
if (map[curmap].selecteditem != -1) {
if (map[curmap].selecteditemtype == T_OBJECT) {
changestate(S_MATCHSIZE);
drawmap();
switch (map[curmap].selecteditemtype) {
case T_OBJECT:
case T_TEXT:
matchtype = map[curmap].selecteditemtype;
changestate(S_MATCHSIZE);
drawmap();
break;
}
}
}
if (c == 'g') { /* toggle gridsize */
if (grid) {
grid = FALSE;
strcpy(statustext, "Grid mode disabled.");
} else {
grid = TRUE;
strcpy(statustext, "Grid mode enabled.");
}
drawmap();
}
if (c == 'c') { /* copy */
if (map[curmap].selecteditem == -1) {
/* copy entire map */
@ -1391,6 +1557,52 @@ int main (int argc, char **argv) {
copytype = -1;
copymap = -1;
drawmap();
} else if (copytype == T_OBJECT) {
int newtype, newx, newy, n;
int newnum;
newtype = map[copymap].obj[copyfrom].type;
newx = map[copymap].obj[copyfrom].x + 10;
newy = map[copymap].obj[copyfrom].y + 10;
/* TODO: validate new position */
createobject(newtype, newx,newy);
/* match size, colour, etc */
newnum = map[curmap].numobjects-1;
map[curmap].obj[newnum].w = map[copymap].obj[copyfrom].w;
map[curmap].obj[newnum].h = map[copymap].obj[copyfrom].h;
map[curmap].obj[newnum].fillcol = map[copymap].obj[copyfrom].fillcol;
/* copy over all attached text */
for (n = 0; n < map[copymap].numtext; n++) {
if (map[copymap].textob[n].anchor == copyfrom) {
int tnum;
/* duplicate it */
startx = map[copymap].textob[n].x + map[curmap].obj[newnum].x;
starty = map[copymap].textob[n].y + map[curmap].obj[newnum].y;
textanchor = newnum;
strcpy(text, map[copymap].textob[n].text);
endtext();
/* update text size */
tnum = map[curmap].numtext-1;
map[curmap].textob[tnum].h = map[copymap].textob[n].h;
map[curmap].textob[tnum].w = map[copymap].textob[n].w;
map[curmap].textob[tnum].c = map[copymap].textob[n].c;
}
}
/* select new object */
map[curmap].selecteditemtype = T_OBJECT;
map[curmap].selecteditem = newnum;
sprintf(statustext,"Object pasted at %d,%d.",newx,newy);
drawmap();
} else {
sprintf(statustext,"Error: No copy source selected!");
@ -1591,6 +1803,9 @@ void changestate(int newstate) {
case S_ADDOBJ:
sprintf(statustext,"Object creation mode enabled.\n"); fflush(stdout);
break;
case S_CHANGEOBJECT:
sprintf(statustext,"Object type modification mode enabled.\n"); fflush(stdout);
break;
case S_ADDTEXT:
sprintf(statustext,"Text creation mode entered.\n"); fflush(stdout);
break;
@ -1604,10 +1819,10 @@ void changestate(int newstate) {
sprintf(statustext,"Size-matching mode entered - select object to copy size from...\n"); fflush(stdout);
break;
case S_MATCHX:
sprintf(statustext,"X-matching mode entered - select object to align with...\n"); fflush(stdout);
sprintf(statustext,"X-matching mode entered - select item to align with...\n"); fflush(stdout);
break;
case S_MATCHY:
sprintf(statustext,"Y-matching mode entered - select object to align with...\n"); fflush(stdout);
sprintf(statustext,"Y-matching mode entered - select item to align with...\n"); fflush(stdout);
break;
case S_MAPNAMING:
sprintf(statustext,"Map rename mode entered.\n"); fflush(stdout);
@ -1644,6 +1859,13 @@ int createobject(int type, int x, int y) {
if ((y + map[curmap].obj[map[curmap].numobjects].h) >= map[curmap].height) {
y = map[curmap].height - map[curmap].obj[map[curmap].numobjects].h - 1;
}
/* adjust for grid */
if (grid) {
x = x - (x % gridsize);
y = y - (y % gridsize);
}
map[curmap].obj[map[curmap].numobjects].x = x;
map[curmap].obj[map[curmap].numobjects].y = y;
@ -2145,6 +2367,84 @@ void drawbox(SDL_Surface *screen, int x1, int y1, int x2, int y2, SDL_Color c) {
drawline(screen,x2,y1,x2,y2,c,1);
}
void drawfillbox(SDL_Surface *screen, int x1, int y1, int x2, int y2, SDL_Color c) {
int x;
if (x1 < x2) {
for (x = x1; x <= x2; x++) {
drawline(screen, x, y1, x,y2,c,1);
}
} else {
for (x = x1; x >= x2; x--) {
drawline(screen, x, y1, x,y2,c,1);
}
}
}
void drawellipsepoints(SDL_Surface *screen, int x1, int y1, int x, int y, SDL_Color c) {
drawpixel(screen, x1 + x, y1 + y, c);
drawpixel(screen, x1 - x, y1 + y, c);
drawpixel(screen, x1 - x, y1 - y, c);
drawpixel(screen, x1 + x, y1 - y, c);
}
void drawellipse(SDL_Surface *screen, int x1, int y1, int xr, int yr, SDL_Color c) {
double x,y;
double xc,yc;
double ee;
double twoas, twobs;
double stoppingx,stoppingy;
twoas = 2 * xr * xr;
twobs = 2 * yr * yr;
/* first set */
x = xr;
y = 0;
xc = yr * yr * (1 - 2*xr);
yc = xr * xr;
ee = 0;
stoppingx = twobs * xr;
stoppingy = 0;
while (stoppingx >= stoppingy) {
drawellipsepoints(screen, x1, y1, x,y, c);
y++;
stoppingy += twoas;
ee += yc;
yc += twoas;
if ((2*ee + xc) > 0) {
x--;
stoppingx -= twobs;
ee += xc;
xc += twobs;
}
}
/* second set */
x = 0;
y = yr;
xc = yr * yr;
yc = xr * xr * (1 - 2*yr);
ee = 0;
stoppingx = 0;
stoppingy = twoas * yr;
while (stoppingx <= stoppingy) {
drawellipsepoints(screen, x1, y1, x,y, c);
x++;
stoppingx += twobs;
ee += xc;
xc += twobs;
if ((2*ee + yc) > 0) {
y--;
stoppingy -= twoas;
ee += yc;
yc += twoas;
}
}
}
void drawcolorchart(SDL_Surface *dest) {
int x,y;
int i;
@ -2511,6 +2811,16 @@ void drawmap(void) {
fillcol = SDL_MapRGB(buffer->format, map[curmap].bgcol.r,map[curmap].bgcol.g,map[curmap].bgcol.b);
SDL_FillRect(buffer, NULL, fillcol);
/* draw grid if required */
if (grid) {
int x,y;
for (y = 0; y < map[curmap].height; y += gridsize) {
for (x = 0; x < map[curmap].width; x += gridsize) {
drawpixel(buffer, x, y, gridcol);
}
}
}
if (testing) {
printf("DRAWING THINGS \n"); fflush(stdout);
}
@ -2920,6 +3230,8 @@ void drawmapbox(void) {
SDL_Rect ar;
/* off the bottom of the page - replace previous item with an arrow */
printf("showing arrow\n"); fflush(stdout);
y = y - th - 1; /* go back one line */
/* clear previous text */
ar.x = x;
@ -3025,7 +3337,7 @@ void drawobox(void) {
area.x = obox.x;
area.y = obox.y;
area.w = obox.width;
area.h = obox.height+3;
area.h = obox.height+4;
SDL_FillRect(screen, &area, fillcol);
x = obox.x;
@ -3044,14 +3356,14 @@ void drawobox(void) {
if ((y + obox.gridsize) >= (map[curmap].height)) {
break;
}
y += obox.gridsize;
y += obox.gridsize + 3;
}
/* draw box */
outlinecol = obox.gridcol;
drawline(screen, x, y,x+obox.gridsize,y,outlinecol,1); /* top */
drawline(screen, x, y+obox.gridsize,x+obox.gridsize,y+obox.gridsize,outlinecol,1); /* bottom */
drawline(screen, x, y,x,y+obox.gridsize,outlinecol,1); /* left */
drawline(screen, x+obox.gridsize, y,x+obox.gridsize,y+obox.gridsize,outlinecol,1); /* right */
//outlinecol = obox.gridcol;
drawline(screen, x, y,x+obox.gridsize,y,gridhigh,1); /* top */
drawline(screen, x, y+obox.gridsize,x+obox.gridsize,y+obox.gridsize,gridlow,1); /* bottom */
drawline(screen, x, y,x,y+obox.gridsize,gridhigh,1); /* left */
drawline(screen, x+obox.gridsize, y,x+obox.gridsize,y+obox.gridsize,gridlow,1); /* right */
/* fill it */
fillcol = SDL_MapRGB(screen->format, obox.gridbgcol.r,obox.gridbgcol.g,obox.gridbgcol.b);
area.x = x+1;
@ -3070,7 +3382,7 @@ void drawobox(void) {
//SDL_UpdateRect(screen, x, y, obox.gridsize+1,obox.gridsize+1);
x += obox.gridsize;
x += obox.gridsize+3;
}
@ -3079,8 +3391,8 @@ void drawobox(void) {
outlinepos = map[curmap].selectedtype - (obox.pos*3);
if ((outlinepos >= 0) && (outlinepos < fit)) {
y = ((map[curmap].selectedtype - (obox.pos*3)) / obox.gridrowlen) * obox.gridsize + obox.y;
x = ((map[curmap].selectedtype - (obox.pos*3)) % obox.gridrowlen) * obox.gridsize + obox.x;
y = ((map[curmap].selectedtype - (obox.pos*3)) / obox.gridrowlen) * (obox.gridsize+3) + obox.y;
x = ((map[curmap].selectedtype - (obox.pos*3)) % obox.gridrowlen) * (obox.gridsize+3) + obox.x;
drawline(screen, x, y,x+obox.gridsize,y,outlinecol,1); /* top */
drawline(screen, x, y+obox.gridsize,x+obox.gridsize,y+obox.gridsize,outlinecol,1); /* bottom */
@ -3090,7 +3402,7 @@ void drawobox(void) {
//SDL_UpdateRect(screen, x, y, obox.gridsize+1,obox.gridsize+1);
SDL_UpdateRect(screen,obox.x, obox.y, obox.width-1, obox.height+3);
SDL_UpdateRect(screen,obox.x, obox.y, obox.width-1, obox.height+5);
}
void drawscreen(void){
@ -3162,9 +3474,6 @@ void drawtoolbox(void) {
Uint32 fillcol;
Uint32 bcol;
int z;
SDL_Color gridhigh = {255, 255, 255, 0};
SDL_Color gridmiddle = {90, 90, 90, 0};
SDL_Color gridlow = {50, 50, 50, 0};
dontpaste = TRUE;
@ -3252,25 +3561,30 @@ void drawtoolbox(void) {
}
/* draw selectors */
if (state == S_NONE) drawtoolboxselector(TB_POINTER);
if (state == S_ADDOBJ) drawtoolboxselector(TB_ADDOBJ);
if (state == S_ADDTEXT) drawtoolboxselector(TB_ADDTEXT);
if (state == S_SAVING) drawtoolboxselector(TB_SAVE);
if (state == S_LOADING) drawtoolboxselector(TB_LOAD);
if (state == S_MATCHSIZE) drawtoolboxselector(TB_MATCHSIZE);
if (state == S_MATCHX) drawtoolboxselector(TB_MATCHX);
if (state == S_MATCHY) drawtoolboxselector(TB_MATCHY);
if (state == S_CREATETELE) drawtoolboxselector(TB_CREATETELE);
if (state == S_NONE) drawtoolboxselector(TB_POINTER, 0);
if (state == S_ADDOBJ) drawtoolboxselector(TB_ADDOBJ, 0);
if (state == S_CHANGEOBJECT) drawtoolboxselector(TB_ADDOBJ, 1);
if (state == S_ADDTEXT) drawtoolboxselector(TB_ADDTEXT, 0);
if (state == S_SAVING) drawtoolboxselector(TB_SAVE, 0);
if (state == S_LOADING) drawtoolboxselector(TB_LOAD, 0);
if (state == S_MATCHSIZE) drawtoolboxselector(TB_MATCHSIZE, 0);
if (state == S_MATCHX) drawtoolboxselector(TB_MATCHX, 0);
if (state == S_MATCHY) drawtoolboxselector(TB_MATCHY, 0);
if (state == S_CREATETELE) drawtoolboxselector(TB_CREATETELE, 0);
}
void drawtoolboxselector(int buttonid) {
void drawtoolboxselector(int buttonid, int altcolour) {
SDL_Color outlinecol;
int x,y;
/* draw selector */
outlinecol = red;
if (altcolour) {
outlinecol = blue;
} else {
outlinecol = red;
}
y = (buttonid / toolbox.gridrowlen) * (toolbox.gridsize+3) + toolbox.y;
x = (buttonid % toolbox.gridrowlen) * (toolbox.gridsize+3) + toolbox.x;
@ -3336,6 +3650,12 @@ void drawvector(SDL_Surface *dest, vectorimg_t *vimg, int x, int y, int w, int h
case VT_BOX:
drawbox(dest,realx1,realy1, realx2,realy2,linecol);
break;
case VT_FILLBOX:
drawfillbox(dest,realx1,realy1, realx2,realy2, linecol);
break;
case VT_ELLIPSE:
drawellipse(dest,realx1,realy1, realx2,realy2, linecol);
break;
case VT_FILL:
floodfill(dest,realx1,realy1, fillcol);
break;
@ -3378,6 +3698,18 @@ int endtext(void) {
map[curmap].textob[map[curmap].numtext].y = starty - map[curmap].obj[textanchor].y;
}
/* adjust for grid */
if (grid) {
int m;
m = map[curmap].textob[map[curmap].numtext].x;
map[curmap].textob[map[curmap].numtext].x -= (m % gridsize);
m = map[curmap].textob[map[curmap].numtext].y;
map[curmap].textob[map[curmap].numtext].y -= (m % gridsize);
}
/* calculate width */
TTF_SizeText(font[DEFTEXTH], text, &tw,&th);
@ -3465,6 +3797,7 @@ int endtextmove(int x, int y) {
tyoff = map[curmap].obj[map[curmap].textob[map[curmap].curtext].anchor].y;
}
/* check position */
if ((map[curmap].textob[map[curmap].curtext].x + txoff + x - startx) >= (map[curmap].width - map[curmap].textob[map[curmap].curtext].w)) {
return -1;
@ -3479,6 +3812,17 @@ int endtextmove(int x, int y) {
return -1;
}
/* adjust for grid */
if (grid) {
int m;
m = map[curmap].textob[map[curmap].curtext].x + x - startx;
x = x - (m % gridsize);
m = map[curmap].textob[map[curmap].curtext].y + y - starty;
y = y - (m % gridsize);
}
map[curmap].textob[map[curmap].curtext].x += (x - startx);
map[curmap].textob[map[curmap].curtext].y += (y - starty);
@ -4372,6 +4716,60 @@ screen->format->Amask);
printf("Too many vectors on line %d of objects file.\n",line);
exit(1);
}
} else if (!strcmp(p, "fillbox")) {
p = strtok(NULL, " ");
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
x1 = atoi(p);
p = strtok(NULL, " ");
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
y1 = atoi(p);
p = strtok(NULL, " ");
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
x2 = atoi(p); /* x2 is actually the x radius */
p = strtok(NULL, " ");
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
y2 = atoi(p); /* y2 is actually the y radius */
p = strtok(NULL, " ");
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
c.r = atoi(p);
p = strtok(NULL, " ");
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
c.g = atoi(p);
p = strtok(NULL, " ");
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
c.b = atoi(p);
if (addvector(&objtype[numobjtypes].vimg,VT_FILLBOX,x1,y1,x2,y2,&c)) {
printf("Too many vectors on line %d of objects file.\n",line);
exit(1);
}
} else if (!strcmp(p, "circle")) {
p = strtok(NULL, " ");
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
x1 = atoi(p);
p = strtok(NULL, " ");
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
y1 = atoi(p);
p = strtok(NULL, " ");
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
x2 = atoi(p); /* x2 is actually the x radius */
p = strtok(NULL, " ");
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
y2 = atoi(p); /* y2 is actually the y radius */
p = strtok(NULL, " ");
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
c.r = atoi(p);
p = strtok(NULL, " ");
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
c.g = atoi(p);
p = strtok(NULL, " ");
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
c.b = atoi(p);
if (addvector(&objtype[numobjtypes].vimg,VT_ELLIPSE,x1,y1,x2,y2,&c)) {
printf("Too many vectors on line %d of objects file.\n",line);
exit(1);
}
} else if (!strcmp(p, "end")) {
state = 0;
numobjtypes++;
@ -4960,12 +5358,11 @@ void initvars(void) {
curmap = 0;
obox.x = map[curmap].width + 1;
obox.y = (map[curmap].height / 4) * 3;
obox.y = ((map[curmap].height / 4) * 3) - 10;
obox.width = SIDEBARW;
obox.height = map[curmap].height - obox.y;
obox.pos = 0;
obox.bgcol = black;
obox.gridbgcol = grey4;
obox.gridbgcol = grey;
obox.gridcol = grey;
obox.gridsize = 30;
obox.gridrowlen = SIDEBARW / obox.gridsize;
@ -4975,7 +5372,6 @@ void initvars(void) {
toolbox.width = SIDEBARW;
toolbox.height = map[curmap].height / 3;
toolbox.bgcol = black;
//toolbox.gridcol = grey3;
toolbox.gridsize = 30;
toolbox.gridrowlen = SIDEBARW / toolbox.gridsize;
@ -5719,6 +6115,12 @@ int updatelinkpointshadow(int x, int y) {
SDL_UpdateRect(screen, area.x, area.y, area.w, area.h);
/* adjust for grid */
if (grid) {
x = x - (x % gridsize);
y = y - (y % gridsize);
}
/* copy background */
linex1 = x - (LINESELHANDLESIZE / 2);
liney1 = y - (LINESELHANDLESIZE / 2);
@ -5762,6 +6164,12 @@ int updatemoveshadow(int x, int y) {
y += yoff;
/* adjust for grid */
if (grid) {
x = x - (x % gridsize);
y = y - (y % gridsize);
}
/* replace old bg */
area.x = bgx;
area.y = bgy;
@ -5769,6 +6177,8 @@ int updatemoveshadow(int x, int y) {
area.h = bgh;
SDL_BlitSurface(bg, 0, screen, &area);
SDL_UpdateRect(screen, area.x, area.y, area.w, area.h);
/* copy current bg */
area.x = x;
area.y = y;
@ -5779,6 +6189,8 @@ int updatemoveshadow(int x, int y) {
bgy = area.y;
bgw = area.w;
bgh = area.h;
/* draw box */
if ((x > 0) && (y > 0) && (x+map[curmap].obj[map[curmap].curobj].w-1 < map[curmap].width) && (y+map[curmap].obj[map[curmap].curobj].h-1 < map[curmap].height)) {
drawline(screen,x,y,x+map[curmap].obj[map[curmap].curobj].w-1,y, map[curmap].boxcol,1);
@ -5794,10 +6206,21 @@ int updateresizeshadow(int x, int y) {
SDL_Rect sarea;
SDL_Rect area;
int xdiff,ydiff;
xdiff = x - startx;
ydiff = y - starty;
/* adjust for grid */
if (grid) {
int m;
m = map[curmap].obj[map[curmap].curobj].x + map[curmap].obj[map[curmap].curobj].w + xdiff;
xdiff -= (m % gridsize);
m = map[curmap].obj[map[curmap].curobj].y + map[curmap].obj[map[curmap].curobj].h + ydiff;
ydiff -= (m % gridsize);
}
/* check for maximum object sizes */
if ((map[curmap].obj[map[curmap].curobj].w + xdiff) > MAXOBJWIDTH) xdiff = MAXOBJWIDTH - map[curmap].obj[map[curmap].curobj].w;
if ((map[curmap].obj[map[curmap].curobj].h + ydiff) > MAXOBJHEIGHT) ydiff = MAXOBJHEIGHT - map[curmap].obj[map[curmap].curobj].h;
@ -6104,6 +6527,12 @@ int endlinkpointmove(int x, int y) {
if (bg) free(bg);
/* adjust for grid */
if (grid) {
x = x - (x % gridsize);
y = y - (y % gridsize);
}
map[curmap].olink[map[curmap].curlink].point[map[curmap].curlinkpoint].x = x;
map[curmap].olink[map[curmap].curlink].point[map[curmap].curlinkpoint].y = y;
@ -6213,6 +6642,7 @@ printf("drilling to: %d\n",mapnum);
int endobjmove(int x, int y) {
SDL_FreeSurface(bg);
int newx, newy;
/* check position */
if ((map[curmap].obj[map[curmap].curobj].x + x - startx) >= (map[curmap].width - map[curmap].obj[map[curmap].curobj].w)) {
@ -6228,9 +6658,21 @@ int endobjmove(int x, int y) {
return -1;
}
modified = TRUE;
map[curmap].obj[map[curmap].curobj].x += (x - startx);
map[curmap].obj[map[curmap].curobj].y += (y - starty);
newx = map[curmap].obj[map[curmap].curobj].x + (x - startx);
newy = map[curmap].obj[map[curmap].curobj].y + (y - starty);
/* adjust for grid */
if (grid) {
newx = newx - (newx % gridsize);
newy = newy - (newy % gridsize);
}
map[curmap].obj[map[curmap].curobj].x = newx;
map[curmap].obj[map[curmap].curobj].y = newy;
return 0;
}
@ -6268,6 +6710,17 @@ int endresize(int x, int y) {
newh = map[curmap].height - map[curmap].obj[map[curmap].curobj].y-1;
}
/* adjust for grid */
if (grid) {
int m;
m = map[curmap].obj[map[curmap].curobj].x + map[curmap].obj[map[curmap].curobj].w + neww;
neww -= (m % gridsize);
m = map[curmap].obj[map[curmap].curobj].y + map[curmap].obj[map[curmap].curobj].h + newh;
newh -= (m % gridsize);
}
map[curmap].obj[map[curmap].curobj].w = neww;
map[curmap].obj[map[curmap].curobj].h = newh;
@ -6367,6 +6820,13 @@ int updatetextshadow(int x, int y) {
area.h = bgh;
SDL_BlitSurface(bg, 0, screen, &area);
SDL_UpdateRect(screen, area.x, area.y, area.w, area.h);
/* adjust for grid */
if (grid) {
x = x - (x % gridsize);
y = y - (y % gridsize);
}
/* copy current bg */
area.x = x;
area.y = y;

Binary file not shown.

View File

@ -178,6 +178,9 @@ void deleteobject(int oid );
void deletetext(int textid);
void drawarrowhead(SDL_Surface *screen, double x1, double y1, double x2, double y2, SDL_Color c, int arrowstyle, int arrowpos);
void drawbox(SDL_Surface *screen, int x1, int y1, int x2, int y2, SDL_Color c);
void drawfillbox(SDL_Surface *screen, int x1, int y1, int x2, int y2, SDL_Color c);
void drawellipsepoints(SDL_Surface *screen, int x1, int y1, int x, int y, SDL_Color c);
void drawellipse(SDL_Surface *screen, int x1, int y1, int x2, int y2, SDL_Color c);
void drawcolorchart(SDL_Surface *dest);
void drawmaplist(SDL_Surface *dest);
int drawletter(SDL_Surface *dest,int x, int y, int w, int h, char let, SDL_Color col);
@ -193,7 +196,7 @@ void drawscreen(void);
void drawstatusbar(void);
void drawtext(SDL_Surface *dest, text_t *t);
void drawtoolbox(void);
void drawtoolboxselector(int buttonid);
void drawtoolboxselector(int buttonid, int altcolour);
void drawvector(SDL_Surface *dest, vectorimg_t *vimg, int x, int y, int w, int h,SDL_Color *overridefg, SDL_Color *overridebg );
void drillto(int mapnum);
int endobjmove(int x, int y);

View File

@ -561,9 +561,9 @@ line 95 260 95 255 250 250 250
# fill
fill 85 250 252 252 252
end
object bluebox 120 120
box 0 0 119 119 0 0 0
fill 50 50 0 0 255
object genericcircle 120 120
circle 60 60 55 55 0 0 0 0
fill 60 60 255 0 0
end
object pda 100 210
# outline
@ -684,3 +684,314 @@ line 300 249 399 190 170 230 255
line 399 150 399 190 170 230 255
fill 350 200 0 90 128
end
object truck 300 223
# CABIN (starts bottom left)
line 0 160 0 100 0 0 0
line 0 100 35 90 0 0 0
line 35 90 50 50 0 0 0
line 50 50 100 50 0 0 0
line 100 50 100 160 0 0 0
line 100 160 0 160 0 0 0
# WINDOW (from top left)
line 60 60 90 60 0 0 0
line 90 60 90 90 0 0 0
line 90 90 50 90 0 0 0
line 50 90 60 60 0 0 0
# JOINER
box 85 160 100 190 0 0 0
#box 100 160 299 175 0 0 0
line 100 175 100 160 0 0 0
line 100 160 299 160 0 0 0
line 299 160 299 175 0 0 0
# conenctions to tyres
line 299 175 275 175 0 0 0
line 235 175 210 175 0 0 0
line 170 175 100 175 0 0 0
# BACK
box 100 0 290 160 0 0 0
# front wheel
circle 50 190 30 30 0 0 0
circle 50 190 15 15 0 0 0
fill 50 190 250 250 250
fill 25 190 0 0 0
# back wheels
circle 255 190 30 30 0 0 0
circle 255 190 15 15 0 0 0
fill 255 190 250 250 250
fill 235 190 0 0 0
#
circle 190 190 30 30 0 0 0
circle 190 190 15 15 0 0 0
fill 190 190 250 250 250
fill 170 190 0 0 0
# fill cabin
fill 60 100 190 0 0
# fill window
fill 70 80 0 0 190
# fill joiner (front)
fill 90 180 200 0 0
# fill joiner (back)
fill 150 167 190 0 0
fill 220 167 195 0 0
fill 290 167 190 0 0
# fill back
fill 250 100 190 190 210
end
object man 100 200
# left shoulder
line 50 50 20 50 0 0 0
# left arm
line 20 50 0 110 0 0 0
line 0 110 10 110 0 0 0
line 10 110 30 60 0 0 0
# left body
line 30 60 30 120 0 0 0
# left leg
line 30 120 10 190 0 0 0
line 10 190 20 190 0 0 0
line 20 190 50 130 0 0 0
# right shoulder
line 50 50 80 50 0 0 0
# right arm
line 80 50 100 110 0 0 0
line 100 110 90 110 0 0 0
line 90 110 70 60 0 0 0
# right body
line 70 60 70 120 0 0 0
# right leg
line 70 120 90 190 0 0 0
line 90 190 80 190 0 0 0
line 80 190 50 130 0 0 0
# belt
line 30 110 70 110 0 0 0
line 30 115 70 115 0 0 0
# head
circle 50 29 18 20 0 0 0
fill 50 29 255 219 198
# fill belt
fill 50 112 0 0 0
# fill shirt
fill 50 80 150 90 100
# fill trousers
fill 40 130 0 0 90
# tie
box 48 50 52 54 0 0 0
#fill 50 52 255 0 0
line 48 54 45 90 0 0 0
line 45 90 50 95 0 0 0
#
line 50 95 55 90 0 0 0
line 55 90 52 54 0 0 0
fill 50 90 255 0 0
end
object camera 200 100
box 0 10 199 99 0 0 0
# fill base
fill 50 50 60 60 60
# lens
circle 100 55 40 40 0 0 0
fill 100 50 190 190 190
circle 100 55 35 35 0 0 0
fill 100 50 0 0 255
line 50 10 60 0 0 0 0
line 60 0 140 0 0 0 0
line 140 0 150 10 0 0 0
# switch
box 180 0 190 10 0 0 0
fill 185 5 190 190 190
# fill top middle bit
fill 100 5 190 190 190
end
object webcam 100 120
# top bit
circle 50 50 45 45 0 0 0
fill 50 50 200 200 200
# base
line 30 90 0 119 0 0 0
line 0 119 99 119 0 0 0
line 70 90 99 119 0 0 0
fill 40 105 176 176 176
# lens
circle 35 35 15 15 0 0 0
fill 35 35 240 240 240
circle 35 35 10 10 0 0 0
fill 35 35 0 0 255
end
object wirelessrouter 200 300
# top left
line 0 150 0 138 170 230 255
line 0 138 10 126 170 230 255
line 10 126 30 114 170 230 255
line 30 114 60 100 170 230 255
line 60 100 100 100 170 230 255
# bottom left
line 0 150 0 162 170 230 255
line 0 162 10 174 170 230 255
line 10 174 30 186 170 230 255
line 30 186 60 199 170 230 255
line 60 199 100 199 170 230 255
# top right
line 199 150 199 138 170 230 255
line 199 138 190 126 170 230 255
line 190 126 170 114 170 230 255
line 170 114 140 100 170 230 255
line 140 100 100 100 170 230 255
# bottom right
line 199 150 199 162 170 230 255
line 199 162 190 174 170 230 255
line 190 174 170 186 170 230 255
line 170 186 140 199 170 230 255
line 140 199 100 199 170 230 255
# fill top
fill 100 150 0 180 255
# bottom half - sides
line 0 150 0 262 170 230 255
line 199 150 199 262 170 230 255
# bottom half - bottom left
# next line not being drawn on windows??
line 0 250 0 212 170 230 255
line 0 262 10 274 170 230 255
line 10 274 30 286 170 230 255
line 30 286 60 299 170 230 255
line 60 299 100 299 170 230 255
# bottom half - bottom right
line 199 250 199 262 170 230 255
line 199 262 190 274 170 230 255
line 190 274 170 286 170 230 255
line 170 286 140 299 170 230 255
line 140 299 100 299 170 230 255
# fill bottom half
fill 100 262 0 120 170
# arrows
# top left arrow
line 35 125 65 140 0 0 0
line 55 115 85 130 0 0 0
line 35 125 55 115 0 0 0
# arrowhead /____
line 55 147 65 140 0 0 0
line 55 147 90 147 0 0 0
# arrowhead /|
line 95 120 90 147 0 0 0
line 95 120 85 130 0 0 0
# fill it
fill 60 130 250 250 250
#
#
# bottom left arrow
line 95 165 65 180 0 0 0
line 75 155 45 170 0 0 0
line 95 165 75 155 0 0 0
# arrowhead /____
line 75 187 65 180 0 0 0
line 75 187 40 187 0 0 0
# arrowhead /|
line 45 160 40 187 0 0 0
line 45 160 45 170 0 0 0
# fill it
fill 70 170 250 250 250
# top right arrow
line 110 140 140 125 0 0 0
line 130 150 160 135 0 0 0
line 110 140 130 150 0 0 0
# arrowhead /____
line 130 118 140 125 0 0 0
line 130 118 165 118 0 0 0
# arrowhead /|
line 160 145 165 118 0 0 0
line 160 145 160 135 0 0 0
# fill it
fill 135 135 250 250 250
# bottom right arrow
line 165 180 135 165 0 0 0
line 145 190 115 175 0 0 0
# joining
line 165 180 145 190 0 0 0
# arrowhead /____
line 145 158 135 165 0 0 0
line 145 158 110 158 0 0 0
# arrowhead /|
line 115 185 110 158 0 0 0
line 115 185 115 175 0 0 0
# fill it
fill 140 175 250 250 250
# WIRELESS ANTENNAE
fillbox 46 20 54 150 0 150 213
line 46 20 46 150 170 230 255
line 54 20 54 150 170 230 255
fillbox 146 20 154 150 0 150 213
line 146 20 146 150 170 230 255
line 154 20 154 150 170 230 255
end
object dish 250 161
# front of dish
circle 130 80 30 50 0 0 0
fill 130 80 190 190 190
# back of dish
line 130 30 90 30 0 0 0
line 90 30 80 35 0 0 0
line 80 35 55 55 0 0 0
line 55 55 40 75 0 0 0
line 40 75 40 85 0 0 0
#
line 130 130 90 130 0 0 0
line 90 130 80 125 0 0 0
line 80 125 55 105 0 0 0
line 55 105 40 85 0 0 0
fill 100 50 210 210 210
#
# base
line 100 130 70 160 0 0 0
line 70 160 150 160 0 0 0
line 150 160 120 130 0 0 0
fill 125 150 200 200 200
# end of antenna
fillbox 227 77 234 83 0 0 0
# antenna wires
line 130 80 230 80 0 0 0
line 130 30 230 80 0 0 0
line 130 130 230 80 0 0 0
end
object satellite 300 150
# top of cylinder
line 125 40 140 40 0 0 0
line 140 40 153 35 0 0 0
line 153 35 137 33 0 0 0
line 137 33 125 40 0 0 0
fill 140 35 0 90 128
# antenna
line 140 36 135 20 0 0 0
fillbox 133 18 136 21 0 0 0
# sides of cylinder
line 125 40 155 130 0 0 0
line 153 35 182 125 0 0 0
# rounded bottom of cylinder
line 155 130 165 133 0 0 0
line 165 133 175 130 0 0 0
line 175 130 182 125 0 0 0
# left wing connector
line 140 80 125 85 0 0 0
# left wing - RHS
line 125 85 130 95 0 0 0
line 125 85 120 75 0 0 0
# left wing - TOP + BOTTOM
line 120 75 20 110 0 0 0
line 130 95 30 130 0 0 0
# left wing - LHS
line 20 110 30 130 0 0 0
# right wing connector
line 165 75 180 70 0 0 0
# right wing - RHS
line 278 35 283 45 0 0 0
line 278 35 273 25 0 0 0
# right wing - TOP + BOTTOM
line 273 25 173 60 0 0 0
line 283 45 183 80 0 0 0
# right wing - LHS
line 173 60 183 80 0 0 0
# fill front
fill 150 80 0 150 213
# fill left wing
fill 100 90 0 180 255
# fill right wing
fill 200 60 0 110 148
end