diff --git a/CHANGELOG b/CHANGELOG
index 832196a..cc0d0e9 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,24 +2,53 @@ Ideas for future versions:
- Fix the bug where netmapr crashes on my 24-bit Truecolour display under
Solaris (and possibly other platforms)
- Perhaps change to SVG for objects
-- Add more objects:
- House
- Phone
+
+
+Version 1.6:
+- Traffic flows are now always drawn last - this should speed up diagram
+ creation by avoiding lots of object draw order adjustments.
+- Endpoints on arrowheads are now only adjusted to be outside objects
+ when the link is NOT a traffic flow - ie. traffic flows can terminate
+ INSIDE objects as opposed to next to them.
+- Newly created links are now placed one place below their start/end objects
+ in the "thing" stack, rather than always at the very bottom.
+- Added { / } commands (or shift+mouse wheel) to raise/lower map items by
+ a large amount at once (10% of total number of items) rather than one
+ position at a time.
+- Added new object: Phone
+- Status bar modifications:
+ - Added more statusbar text feedback for common actions
+ - Status bar now flashes red when errors are displayed.
+ - Status bar now flashes green when important information is displayed.
+- Bug Fixes:
+ - Fixed yet another bug with AP_END arrowheads being drawn
+ underneath objects.
+ - Fixed bug where changing the colour of a line/text object
+ would remove the ISFLOW attribute.
+ - Fixed a number of bugs and graphical glitches with the "shadow" when
+ moving or resizing things.
Version 1.5:
-- Now handles spaces in filenames under Windows
-- Disabled Delete Map and New Map functions in readonly mode
-- Preparation for SVG exports:
+- Can now export to SVG files (save with ".SVG" extension)
+- Modifications to allow SVG exports:
- Added vector types: Subobj/obj (to draw filled objects), Poly
- Modified vector type "box" to take a "fill colour" argument
- Removed vector types Fill and Fillbox
+- Fix bug where traffic flows could be selected without flow mode being on
+- Added new objects: House, Building, IDS Sensor
+- Better handling for spaces in filenames under Windows
+- Delete Map and New Map functions are now disabled in readonly mode
- Rewrote entire objects.dat file to avoid use of "fill" command
-- Can now export to SVG files (same with ".SVG" extension)
+- Many improvements to mapbox:
+ - Current map name is now centred and highlighted
+ - Long map names are now displayed with "..." if they won't fit
+ - Map names are now sorted
- Improved behaviour of grid with respect to link endpoints when
moving & resizing objects
-- Grid lines now look more visio-like
-- Removed grid size of '5' as this was too small to be useful
-- Changed default grid size from 10 to 15.
+- Modifications to grid settings:
+ - Grid lines now look more visio-like and are now always visible
+ - Removed grid size of '5' as this was too small to be useful
+ - Changed default grid size from 10 to 15.
Version 1.4:
- Rewrote Command Reference document (simplified and now includes screenshots)
diff --git a/constants.h b/constants.h
index 54f057b..5d9e31f 100644
--- a/constants.h
+++ b/constants.h
@@ -1,63 +1,71 @@
-#define VERSION "1.5"
+#define VERSION "1.7a"
-#define SMALLBUFLEN 64
-#define BUFLEN 512
+/* variable sizes */
+#define SMALLBUFLEN 64 /* small text buffer */
+#define BUFLEN 512 /* large text buffer */
-#define DOUBLECLICKTHRES 250
+/* user interface settings elements */
+#define DOUBLECLICKTHRES 250 /* how fast a double click needs to be (in ticks) */
+#define CURSORWIDTH 6 /* width of text cursor */
+#define FIRSTLET 33 /* first ASCII value for letters */
+#define LASTLET 122 /* last ASCII value for letters */
+#define OBOXPAGESIZE (4) /* how many lines a pageup/down will scroll the object box */
+#define MULTIRAISENUM (10) /* this many presses of { or } will raise/lower a thing to the very bottom/top */
+#define LINESELTHRESHOLD (4) /* how close to a link you need to click to select it */
-#define DEFTEXTW 8
-#define DEFTEXTH 10
+/* graphical elements */
+#define SHORTCUTSIZE (10) /* font size (points) for shortcut numbers on buttons */
+#define BEZIERQUALITY 50 /* how many sub=lines to use when drawing bezier curves */
+#define MAPBOXTEXTHEIGHT 10 /* size of text in mapbox (points) */
+#define LINESELHANDLESIZE (5) /* how large the boxes on the ends of a selected link are */
+#define OBJSELHANDLEPCT (15) /* what percentage of the selected object's size the selection boxes are */
+#define SIDEBARW 100 /* how width the toolbox/mapbox/objectbox are */
+#define ERRORFLASHSPEED 5 /* how fast to fade out the statusbar error highlight */
+#define INFOFLASHSPEED 2 /* how fast to fade out the statusbar information highlight */
-#define MAXPOINTS 20
-#define MAXBUTTONS 40
+/* defaults */
+#define DEFTEXTW 8 /* default text width (in pixels) for new text items */
+#define DEFTEXTH 10 /* default text height (in POINTS) for new text items */
-#define MAXMAPS 60
+/* maximum/minimum values */
+#define MAXBUTTONS 18 /* maximum number of toolbox buttons from buttons.dat */
+#define MAXOBJTYPES 50 /* maximum amount of different types from objects.dat */
-#define MAXHISTORY 50
-#define MAXCHILDREN 30
+#define MAXCHILDREN 30 /* maximum amount of submaps for any one given map */
+#define MAXHISTORY 50 /* maximum amount that we can drill down into a map */
+#define MAXLINKS 512 /* maximum number of links between objects each map can contain */
+#define MAXMAPS 60 /* maximum number of (sub)maps in a project */
+#define MAXOBJECTS 512 /* maximum number of objects each map can contain */
+#define MAXPOINTS 20 /* maximum number of points on a line */
+#define MAXTEXT 512 /* maximum number of text objects per map */
-#define MAXOBJTYPES 30
-#define MAXOBJECTS 512
-#define MAXLINKS 512
-#define MAXLETTERVECTS 95
-#define MAXTEXT 512
+#define MINLETTERWIDTH 6 /* minimum letter width (pixels) */
+#define MINLETTERHEIGHT 6 /* minimum letter width (points) */
+#define MAXLETTERWIDTH 100 /* maximum letter width (pixels) */
+#define MAXLETTERHEIGHT 100 /* maximum letter width (points) */
-#define CURSORWIDTH 6
+#define MAXOBJWIDTH 500 /* maximum object width */
+#define MAXOBJHEIGHT 500 /* maximum object height */
+#define MINOBJWIDTH 20 /* minimum object width */
+#define MINOBJHEIGHT 20 /* minimum object height */
-#define FIRSTLET 33
-#define LASTLET 122
+#define MAXFILLSTACK 500000 /* used for flood fill function */
-#define MINLETTERWIDTH 6
-#define MINLETTERHEIGHT 6
-#define MAXLETTERWIDTH 100
-#define MAXLETTERHEIGHT 100
+#define OLDMAXVECTORSPERIMAGE (60) /* maximum vectors per image in old version map files */
+#define MAXVECTORSPERIMAGE (120) /* maximum vectors per image in current map files */
-#define MAXOBJWIDTH 300
-#define MAXOBJHEIGHT 300
-#define MINOBJWIDTH 20
-#define MINOBJHEIGHT 20
-
-#define MAPBOXTEXTHEIGHT 10
-
-#define MAXFILLSTACK 500000
-
-#define BEZIERQUALITY 50
-
-#define SHORTCUTSIZE (10)
-
-#define OLDMAXVECTORSPERIMAGE (60)
-#define MAXVECTORSPERIMAGE (120)
-
-#define LINESELTHRESHOLD (4)
-#define LINESELHANDLESIZE (5)
-#define OBJSELHANDLEPCT (15)
+#define MAXLINESTYLE (4) /* Types of lines (dotted, dashed, etc) */
+#define LINESTYLESIZE (10) /* How big each line style array is */
+/*************************************
+ * Constants
+ */
+/* The SDL_Color.unused item is ORed with the following */
#define USECOLOUR (0x01) /* used as a NULL value for colours */
#define ISFLOW (0x02) /* used to show whether things are traffic flows */
-#define GRIDBRIGHTNESS 100
-
+/* map element ("thing") types */
#define T_EMPTY (0)
#define T_OBJECT (1)
#define T_LINK (2)
@@ -65,12 +73,7 @@
#define T_LINKPOINT (4)
#define T_MAP (5)
-#define O_ROUTER (0)
-#define O_SWITCH (1)
-#define O_FIREWALL (2)
-#define O_SERVER (3)
-#define O_PC (4)
-
+/* vector types */
#define VT_LINE (0)
#define VT_BOX (1)
#define VT_DOT (2)
@@ -81,9 +84,11 @@
#define VT_ENDPOLY (7)
#define VT_SUBOBJ (8)
+/* boolean flags */
#define TRUE (-1)
#define FALSE (0)
+/* states */
#define S_NONE (0)
#define S_OBJMOVING (1)
#define S_RESIZING (2)
@@ -110,8 +115,9 @@
#define S_EDITTEXT (23)
#define S_CHANGEOBJECT (24)
#define S_DRAWFLOW (25)
+#define S_SEARCH (26)
-
+/* toolbox buttons */
#define TB_POINTER (0)
#define TB_ADDOBJ (1)
#define TB_ADDTEXT (2)
@@ -131,27 +137,22 @@
#define TB_LOAD (16)
#define TB_SAVE (17)
-#define SIDEBARW 100
-
-#define NUMSTYLES (7)
+/* selection screen values */
#define YES (1)
#define NO (0)
#define MAYBE (-1)
-/* line styles etc */
+/* Line styles are a 32-bit int split up as follows: */
/*
* Unused Arrow Style Thickness (max 5?)
* 00000000 00000000 00000000 00000000
*/
-
#define LS_SOLID (0)
#define LS_DOTTED (1)
#define LS_BIGDASH (2)
#define LS_DASHDOT (3)
-#define MAXLINESTYLE (4)
-#define LINESTYLESIZE (10)
/* arrow positions */
#define AP_NONE (0)
@@ -159,14 +160,14 @@
#define AP_END (2)
#define AP_BOTH (3)
+/* Special mapbox child values for scroll buttons */
#define C_NONE (-1)
#define C_SCROLLUP (-2)
#define C_SCROLLDOWN (-3)
-/* mouse positions */
+/* Mouse positions */
#define MP_NONE (0)
#define MP_TOOLBOX (1)
#define MP_MAPBOXNAME (2)
#define MP_MAPBOXCHILDREN (3)
#define MP_OBJECTBOX (4)
-
diff --git a/doc/reference.html b/doc/reference.html
index 3a606f5..b2720ca 100644
--- a/doc/reference.html
+++ b/doc/reference.html
@@ -214,7 +214,7 @@
- |
+ |
Left mouse button |
|
Select new object type. |
@@ -223,7 +223,13 @@
Mouse Wheel |
'q' and 'w' keys ',' and '.' keys |
-Scroll the object selection box up and down. |
+Scroll the object selection box up/down by one line. |
+
+
+
+SHIFT + Mouse Wheel |
+PgUp and PgDown Keys |
+Scroll the object selection box up/down by one page. |
diff --git a/netmapr-small.jpg b/netmapr-small.jpg
index 2aed78c..be9ae03 100644
Binary files a/netmapr-small.jpg and b/netmapr-small.jpg differ
diff --git a/netmapr.c b/netmapr.c
index 3eebd70..d86130d 100644
--- a/netmapr.c
+++ b/netmapr.c
@@ -39,6 +39,18 @@ SDL_Color grey2 = { 70, 70, 70, USECOLOUR};
SDL_Color grey3 = { 50, 50, 50, USECOLOUR};
SDL_Color grey4 = { 30, 30, 30, USECOLOUR};
+SDL_Color statusbarcolour = { 255, 255, 255, 0 };
+
+int errorflash = 0;
+int errorcounter = 0;
+int errorticks = 0;
+int olderrorticks = 0;
+
+int infoflash = 0;
+int infocounter = 0;
+int infoticks = 0;
+int oldinfoticks = 0;
+
SDL_Color gridhigh = {255, 255, 255, 0};
SDL_Color gridmiddle = {90, 90, 90, 0};
SDL_Color gridlow = {50, 50, 50, 0};
@@ -53,6 +65,10 @@ int linemask[MAXLINESTYLE][LINESTYLESIZE];
xy_t fillstack[MAXFILLSTACK];
int fillstackptr = 0;
+
+
+int thingdrawn[MAXOBJECTS + MAXLINKS];
+
SDL_Color fgcol;
SDL_Color objfillcol;
Uint8 defthickness = 1;
@@ -66,6 +82,11 @@ int copyfrom = -1;
int copymap = -1;
int copytype = T_MAP;
+int searchmap = 0;
+int searchtob = 0;
+int searchwrap = FALSE;
+char searchtext[BUFLEN];
+
int grid = TRUE;
int gridsize = 15;
int gridsizelist[] = {10, 15, 20};
@@ -95,6 +116,7 @@ int numchildren = 0;
char currentfilename[BUFLEN];
int state = S_NONE;
+SDL_Surface *shadow; /* for object moves */
SDL_Surface *bg; /* background for temp images*/
int *linebg; /* background for temp lines */
int bgx,bgy;
@@ -123,6 +145,7 @@ int updateheight;
char progdir[BUFLEN];
int shift;
+int autoload = FALSE;
int main (int argc, char **argv) {
int done;
@@ -133,7 +156,6 @@ int main (int argc, char **argv) {
Uint32 oldticks = 0;
Uint32 ticks;
int doubleclick = FALSE;
- int autoload = FALSE;
int n,found,delmap;
if (argc >= 2) {
@@ -177,6 +199,7 @@ int main (int argc, char **argv) {
strcpy(text, "");
}
+
if (readonly) {
sprintf(statustext, "Welcome to netmapr viewer v%s. Author: rob@nethack.net", VERSION);
} else {
@@ -189,6 +212,39 @@ int main (int argc, char **argv) {
done = 0;
while (!done) {
+ /* fade error panel */
+ if (errorflash > 0) {
+ errorticks = SDL_GetTicks();
+ if (errorticks - olderrorticks >= ERRORFLASHSPEED) {
+ errorflash--;
+ drawstatusbar();
+
+ olderrorticks = errorticks;
+ }
+ }
+ /* fade info panel */
+ if (infoflash > 0) {
+ infoticks = SDL_GetTicks();
+ if (infoticks - oldinfoticks >= INFOFLASHSPEED) {
+ /* don't fade this if we're in a mode where the user
+ has to do something special */
+ switch (state) {
+ case S_MATCHX:
+ case S_MATCHY:
+ case S_MATCHSIZE:
+ case S_CREATETELE:
+ case S_CHANGEOBJECT:
+ case S_DRAWFLOW:
+ break;
+ default:
+ infoflash--;
+ break;
+ }
+ drawstatusbar();
+
+ oldinfoticks = infoticks;
+ }
+ }
/* check for input */
while (SDL_PollEvent(&event)) {
switch (event.type) {
@@ -231,6 +287,10 @@ int main (int argc, char **argv) {
starttextmove(event.button.x, event.button.y);
break;
}
+ } else {
+ /* just clear the status text */
+ sprintf(statustext, "Ready.");
+ drawstatusbar();
}
}
} else if ((event.button.button == SDL_BUTTON_MIDDLE) ||
@@ -273,22 +333,43 @@ int main (int argc, char **argv) {
}
*/
} else if (event.button.button == SDL_BUTTON_WHEELUP) {
+ int amt;
+
+ tmod = SDL_GetModState();
+ if ((mod & KMOD_SHIFT)) {
+ amt = (map[curmap].numthings / MULTIRAISENUM);
+ } else amt = 1;
+
if (map[curmap].selecteditem != -1) {
/* raise the selected object */
- raiseselected();
+ raiseselected(amt);
}
} else if (event.button.button == SDL_BUTTON_WHEELDOWN) {
+ int amt;
+
+ tmod = SDL_GetModState();
+ if ((mod & KMOD_SHIFT)) {
+ amt = (map[curmap].numthings / MULTIRAISENUM);
+ } else amt = 1;
+
if (map[curmap].selecteditem != -1) {
/* lower the selected object */
- lowerselected();
+ lowerselected(amt);
}
}
}
} else if (isonobox(event.button.x, event.button.y)) {
+ int amt = 1;
+
+ tmod = SDL_GetModState();
+ if ((mod & KMOD_SHIFT)) {
+ amt = 4;
+ }
+
if (event.button.button == SDL_BUTTON_WHEELUP) {
- scrollobox(-1);
+ scrollobox(-amt);
} else if (event.button.button == SDL_BUTTON_WHEELDOWN) {
- scrollobox(1);
+ scrollobox(amt);
}
}
break;
@@ -316,6 +397,7 @@ int main (int argc, char **argv) {
changestate(S_NONE);
drillto(map[curmap].obj[o].child);
} else {
+ seterror(255);
sprintf(statustext, "Cannot drill down - object has no children (use drill tool to create one).");
map[curmap].selecteditem = -1;
changestate(S_NONE);
@@ -359,8 +441,10 @@ int main (int argc, char **argv) {
} else {
toggleflow(o, clickedtype);
if (isflow(o, clickedtype)) {
+ setinfo(255);
sprintf(statustext, "%s #%d traffic flow status = TRUE.", typedesc[clickedtype], o);
} else {
+ setinfo(255);
sprintf(statustext, "%s #%d traffic flow status = FALSE.", typedesc[clickedtype], o);
}
drawmap();
@@ -551,7 +635,6 @@ int main (int argc, char **argv) {
// actually move the link
endlinkpointmove(event.button.x, event.button.y);
changestate(S_NONE);
- sprintf(statustext,"Link #%d moved to (%d,%d).\n",map[curmap].curlink,event.button.x, event.button.y);
drawmap();
}
} else if (state == S_TEXTMOVING) {
@@ -623,11 +706,18 @@ int main (int argc, char **argv) {
} else if (state == S_FGCOL) {
getcolor(screen, event.button.x, event.button.y, &fgcol);
if (map[curmap].selecteditem != -1) {
+ int flow = isflow(map[curmap].selecteditem, map[curmap].selecteditemtype);
if (map[curmap].selecteditemtype == T_LINK) {
map[curmap].olink[map[curmap].selecteditem].col = fgcol;
+ if (flow) {
+ map[curmap].olink[map[curmap].selecteditem].col.unused |= ISFLOW;
+ }
sprintf(statustext, "Colour of link #%d changed to R=%d,G=%d,B=%d",map[curmap].selecteditem, fgcol.r,fgcol.g,fgcol.b);
} else if (map[curmap].selecteditemtype == T_TEXT) {
map[curmap].textob[map[curmap].selecteditem].c = fgcol;
+ if (flow) {
+ map[curmap].textob[map[curmap].selecteditem].c.unused |= ISFLOW;
+ }
sprintf(statustext, "Colour of text item #%d changed to R=%d,G=%d,B=%d",map[curmap].selecteditem, fgcol.r,fgcol.g,fgcol.b);
} else {
sprintf(statustext, "Foreground colour selected: R=%d,G=%d,B=%d",fgcol.r,fgcol.g,fgcol.b);
@@ -646,7 +736,8 @@ int main (int argc, char **argv) {
if (pos == -1) {
map[curmap].obj[map[curmap].selecteditem].child = pos;
sprintf(statustext, "Map link removed.");
- modified = TRUE;
+ strcpy(oldstatustext, statustext);
+ setmod(TRUE);
changestate(S_NONE);
drawmap();
} else if (pos <= (nummaps-1)) {
@@ -654,10 +745,12 @@ int main (int argc, char **argv) {
if (pos != curmap) {
map[curmap].obj[map[curmap].selecteditem].child = pos;
sprintf(statustext, "Map link created.");
- modified = TRUE;
+ strcpy(oldstatustext, statustext);
+ setmod(TRUE);
changestate(S_NONE);
drawmap();
} else {
+ seterror(255);
sprintf(statustext, "ERROR: Cannot link to current map!");
drawstatusbar();
}
@@ -684,10 +777,12 @@ int main (int argc, char **argv) {
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!");
+ seterror(255);
+ sprintf(statustext, "ERROR: 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!");
+ seterror(255);
+ sprintf(statustext, "ERROR: 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);
@@ -727,6 +822,7 @@ int main (int argc, char **argv) {
/* adjust for offset if not a special value */
pos += mapbox.offset;
if (pos >= numchildren) {
+ seterror(255);
sprintf(statustext, "ERROR: Invalid child map %d (max is %d).",pos,numchildren);
drawstatusbar();
} else {
@@ -744,6 +840,9 @@ int main (int argc, char **argv) {
/* are we in a colour selection state? */
if (state == S_FGCOL) {
+ /* set fgcol to black */
+ fgcol = black;
+ sprintf(statustext, "Foreground colour selected: R=0,G=0,B=0");
changestate(S_NONE);
drawmap();
break;
@@ -788,9 +887,11 @@ int main (int argc, char **argv) {
break;
case TB_FLOW:
if (showflows) {
+ setinfo(255);
showflows = FALSE;
sprintf(statustext, "Traffic flows hidden.");
} else {
+ setinfo(255);
sprintf(statustext, "Traffic flows displayed.");
showflows = TRUE;
}
@@ -803,6 +904,7 @@ int main (int argc, char **argv) {
break;
case TB_NEW:
if (readonly) {
+ seterror(255);
sprintf(statustext, "Cannot delete maps in read-only mode.");
drawstatusbar();
break;
@@ -810,12 +912,14 @@ int main (int argc, char **argv) {
}
tmod = SDL_GetModState();
if (!(mod & KMOD_SHIFT)) {
+ seterror(255);
sprintf(statustext, "Must hold down SHIFT to start new project (avoids accidental loss of data)!");
drawstatusbar();
break;
}
initvars();
changestate(S_NONE);
+ setinfo(255);
sprintf(statustext, "All maps cleared.");
sprintf(oldstatustext, statustext);
@@ -846,9 +950,11 @@ int main (int argc, char **argv) {
setmod(TRUE);
drawmap();
} else {
+ seterror(255);
sprintf(statustext, "No link selected!");
}
} else {
+ seterror(255);
sprintf(statustext, "No link selected!");
}
drawstatusbar();
@@ -883,19 +989,30 @@ int main (int argc, char **argv) {
case TB_FGCOL:
/* change selected item to match fgcol */
if (map[curmap].selecteditem != -1) {
+ int flow = isflow(map[curmap].selecteditem, map[curmap].selecteditemtype);
if (map[curmap].selecteditemtype == T_LINK) {
map[curmap].olink[map[curmap].selecteditem].col = fgcol;
+ /* maintain flow attribute */
+ if (flow) {
+ map[curmap].olink[map[curmap].selecteditem].col.unused |= ISFLOW;
+ }
setmod(TRUE);
sprintf(statustext, "Colour of link #%d changed to R=%d,G=%d,B=%d",map[curmap].selecteditem, fgcol.r,fgcol.g,fgcol.b);
} else if (map[curmap].selecteditemtype == T_TEXT) {
map[curmap].textob[map[curmap].selecteditem].c = fgcol;
+ /* maintain flow attribute */
+ if (flow) {
+ map[curmap].textob[map[curmap].selecteditem].c.unused |= ISFLOW;
+ }
setmod(TRUE);
sprintf(statustext, "Colour of text item #%d changed to R=%d,G=%d,B=%d",map[curmap].selecteditem, fgcol.r,fgcol.g,fgcol.b);
} else {
+ seterror(255);
sprintf(statustext, "No object selected! (use RMB to select new foreground colour)");
}
} else {
- sprintf(statustext, "No object selected! (use RMB to select new foreground colour)");
+ seterror(255);
+ sprintf(statustext, "No object selected! (use RMB to select new foreground colour)");
}
drawmap();
break;
@@ -911,9 +1028,11 @@ int main (int argc, char **argv) {
sprintf(statustext, "Fill colour of object #%d removed.",map[curmap].selecteditem);
}
} else {
+ seterror(255);
sprintf(statustext, "No object selected! (use RMB to select new fill colour)");
}
} else {
+ seterror(255);
sprintf(statustext, "No object selected! (use RMB to select new fill colour)");
}
drawmap();
@@ -922,6 +1041,7 @@ int main (int argc, char **argv) {
/* safety - must hold down SHIFT to delete maps */
if (readonly) {
+ seterror(255);
sprintf(statustext, "Cannot delete maps in read-only mode.");
drawstatusbar();
break;
@@ -929,11 +1049,13 @@ int main (int argc, char **argv) {
}
tmod = SDL_GetModState();
if (!(mod & KMOD_SHIFT)) {
+ seterror(255);
sprintf(statustext, "Must hold down SHIFT to delete maps (avoids accidental loss of data)!");
drawstatusbar();
break;
}
if (curmap == 0) {
+ seterror(255);
sprintf(statustext, "Cannot delete toplevel map!");
drawstatusbar();
break;
@@ -948,6 +1070,7 @@ int main (int argc, char **argv) {
}
}
if (found) {
+ seterror(255);
sprintf(statustext, "Cannot delete a map with children.");
drawstatusbar();
break;
@@ -984,6 +1107,7 @@ int main (int argc, char **argv) {
}
if (!found) {
goback();
+ setinfo(255);
sprintf(statustext, "Deleted map #%d.\n",delmap);
}
/* fix history array */
@@ -996,9 +1120,12 @@ int main (int argc, char **argv) {
break;
case TB_CREATETELE:
if ((map[curmap].selecteditemtype == T_OBJECT) && (map[curmap].selecteditem != -1)) {
+ setinfo(255);
+ sprintf(statustext,"Select destination map to link to...");
changestate(S_CREATETELE);
drawmap();
} else {
+ seterror(255);
sprintf(statustext,"Cannot create map link - no object selected!");
drawstatusbar();
}
@@ -1008,6 +1135,7 @@ int main (int argc, char **argv) {
if ((map[curmap].selecteditemtype == T_OBJECT) && (map[curmap].selecteditem != -1)) {
drillto(map[curmap].obj[map[curmap].selecteditem].child);
} else {
+ seterror(255);
sprintf(statustext,"Cannot drill down - no object selected!");
drawstatusbar();
}
@@ -1067,6 +1195,7 @@ int main (int argc, char **argv) {
// end resize
endresize(event.button.x, event.button.y);
changestate(S_NONE);
+ drawmap();
} else if (state == S_TEXTRESIZING) {
// end text resize
endtextresize(event.button.x, event.button.y);
@@ -1083,9 +1212,11 @@ int main (int argc, char **argv) {
switch (selection) {
case TB_ADDOBJ:
if (map[curmap].selecteditemtype != T_OBJECT) {
+ seterror(255);
sprintf(statustext, "Must select an object to change the type of first!");
drawstatusbar();
} else if (map[curmap].selecteditem == -1) {
+ seterror(255);
sprintf(statustext, "Must select an object to change the type of first!");
drawstatusbar();
} else {
@@ -1098,6 +1229,7 @@ int main (int argc, char **argv) {
(map[curmap].selecteditem != -1) ){
startedittext(map[curmap].selecteditem);
} else {
+ seterror(255);
sprintf(statustext, "Cannot edit text - no text item selected!");
drawstatusbar();
}
@@ -1211,7 +1343,7 @@ int main (int argc, char **argv) {
}
/* copy background of this button */
if (selection <= TB_SAVE) {
- toolbg = SDL_CreateRGBSurface(SDL_SWSURFACE,toolbox.gridsize+3, toolbox.gridsize+3,
+ toolbg = SDL_CreateRGBSurface(SDL_HWSURFACE,toolbox.gridsize+3, toolbox.gridsize+3,
screen->format->BitsPerPixel, screen->format->Rmask,
screen->format->Gmask,screen->format->Bmask,
screen->format->Amask);
@@ -1343,12 +1475,12 @@ int main (int argc, char **argv) {
} else if (mousepos == MP_MAPBOXNAME) {
if (!rollover) strcpy(oldstatustext, statustext);
rollover = TRUE;
- sprintf(statustext, "LMB = Change the name of the current map.");
+ sprintf(statustext, "LMB = Rename the current map.");
drawstatusbar();
} else if (mousepos == MP_MAPBOXCHILDREN) {
if (!rollover) strcpy(oldstatustext, statustext);
rollover = TRUE;
- sprintf(statustext, "LMB = Drill down into a submap.");
+ sprintf(statustext, "LMB = Drill down into a submap (blue text indicates maps already in the map history).");
drawstatusbar();
} else if (mousepos == MP_OBJECTBOX) {
if (!rollover) strcpy(oldstatustext, statustext);
@@ -1426,7 +1558,7 @@ int main (int argc, char **argv) {
}
}
/* state dependant */
- if ((state == S_TYPETEXT) || (state == S_SAVING) || (state == S_LOADING) || (state == S_MAPNAMING) || (state == S_EDITTEXT)) {
+ if ((state == S_TYPETEXT) || (state == S_SAVING) || (state == S_LOADING) || (state == S_MAPNAMING) || (state == S_EDITTEXT) || (state == S_SEARCH)) {
if ((c >= FIRSTLET) && (c <= LASTLET)) {
char temptext[2];
sprintf(temptext, "%c", c);
@@ -1455,10 +1587,21 @@ int main (int argc, char **argv) {
loadmap();
changestate(S_NONE);
drawmap();
+ } else if (state == S_SEARCH) {
+ changestate(S_NONE);
+ if (dosearch()) {
+ seterror(255);
+ sprintf(statustext, "Not found: '%s'",searchtext);
+ } else {
+ setinfo(255);
+ sprintf(statustext, "Found '%s' in text object #%d (map '%s')",searchtext, map[curmap].selecteditem, map[curmap].name);
+ }
+ drawmap();
} else if (state == S_MAPNAMING) {
/* rename map */
strcpy(map[curmap].name,text);
changestate(S_NONE);
+ setinfo(255);
sprintf(statustext, "Map #%d renamed to '%s'.",curmap,map[curmap].name);
drawmap();
}
@@ -1469,6 +1612,27 @@ int main (int argc, char **argv) {
changestate(S_ADDOBJ);
}
}
+ if (c == '/') { /* search/find */
+ if (state == S_NONE) {
+ startx = 1;
+ starty = (map[curmap].height/2)-2;
+ bg = NULL;
+ strcpy(text, "");
+ changestate(S_SEARCH);
+ drawmap();
+ }
+ }
+ if (c == 'n') { /* find next */
+ changestate(S_NONE);
+ if (dosearchnext()) {
+ seterror(255);
+ sprintf(statustext, "Not foundnext: '%s'",searchtext);
+ } else {
+ setinfo(255);
+ sprintf(statustext, "Foundnext %s'%s' in text object #%d (map '%s')",searchwrap ? "(wrapped) " : "",searchtext, map[curmap].selecteditem, map[curmap].name);
+ }
+ drawmap();
+ }
if (c == 'm') { /* modify object type */
if (state == S_NONE) {
changestate(S_CHANGEOBJECT);
@@ -1485,6 +1649,7 @@ int main (int argc, char **argv) {
(map[curmap].selecteditem != -1) ){
startedittext(map[curmap].selecteditem);
} else {
+ seterror(255);
sprintf(statustext, "Cannot edit text - no text item selected!");
drawstatusbar();
}
@@ -1512,6 +1677,12 @@ int main (int argc, char **argv) {
if ((c == '.') || (c == 'w')) { /* scroll object box down */
scrollobox(1);
}
+ if ((c == '<') || (c == 'Q')) { /* scroll object box up */
+ scrollobox(-OBOXPAGESIZE);
+ }
+ if ((c == '>') || (c == 'W')) { /* scroll object box down */
+ scrollobox(OBOXPAGESIZE);
+ }
if (c == 'x') {
if (map[curmap].selecteditem != -1) {
switch (map[curmap].selecteditemtype) {
@@ -1550,7 +1721,7 @@ int main (int argc, char **argv) {
}
if (c == 'g') { /* toggle snap-to-grid */
togglegrid();
- drawmap();
+ drawtoolbox();
}
if (c == ';') { /* change gridsize */
changegridsize();
@@ -1564,10 +1735,12 @@ int main (int argc, char **argv) {
if ((map[curmap].selecteditemtype == T_OBJECT) && (map[curmap].selecteditem != -1)) {
drillto(map[curmap].obj[map[curmap].selecteditem].child);
} else {
+ seterror(255);
sprintf(statustext,"Cannot drill down - no object selected!");
drawstatusbar();
}
} else {
+ seterror(255);
sprintf(statustext,"Cannot drill down in state %d.",state);
drawstatusbar();
}
@@ -1575,8 +1748,10 @@ int main (int argc, char **argv) {
if (c == 'f') {
if (showflows) {
showflows = FALSE;
+ setinfo(255);
sprintf(statustext, "Traffic flows hidden.");
} else {
+ setinfo(255);
sprintf(statustext, "Traffic flows displayed.");
showflows = TRUE;
}
@@ -1602,6 +1777,7 @@ int main (int argc, char **argv) {
seltype = tempy*obox.gridrowlen + tempx + (obox.pos*3);
shortcut[onum] = seltype;
+ setinfo(255);
sprintf(statustext,"Shortcut key '%c' set to '%s'.\n",c, objtype[seltype].name);
drawstatusbar();
drawobox();
@@ -1634,6 +1810,12 @@ int main (int argc, char **argv) {
if (c == SDLK_BACKSPACE) {
goback();
}
+ if (c == SDLK_PAGEUP) {
+ scrollobox(-OBOXPAGESIZE);
+ }
+ if (c == SDLK_PAGEDOWN) {
+ scrollobox(OBOXPAGESIZE);
+ }
if (c == SDLK_DELETE) {
if (map[curmap].selecteditem != -1) {
if (map[curmap].selecteditemtype == T_LINKPOINT) {
@@ -1662,16 +1844,28 @@ int main (int argc, char **argv) {
}
}
}
- if (c == ']') { /* raise */
- if (map[curmap].selecteditem != -1) {
+ if (map[curmap].selecteditem != -1) {
+ if (c == ']') { /* raise */
+ int amt;
+
+ tmod = SDL_GetModState();
+ if ((mod & KMOD_SHIFT)) {
+ amt = (map[curmap].numthings / MULTIRAISENUM);
+ } else amt = 1;
+
/* raise the selected map[curmap].object */
- raiseselected();
+ raiseselected(amt);
}
- }
- if (c == '[') { /* lower */
- if (map[curmap].selecteditem != -1) {
+ if (c == '[') { /* lower */
+ int amt;
+
+ tmod = SDL_GetModState();
+ if ((mod & KMOD_SHIFT)) {
+ amt = (map[curmap].numthings / MULTIRAISENUM);
+ } else amt = 1;
+
/* lower the selected map[curmap].object */
- lowerselected();
+ lowerselected(amt);
}
}
}
@@ -1701,7 +1895,7 @@ void addlinkpoint(int linkid, int x, int y) {
map[curmap].olink[linkid].point[pos].y = y;
setmod(TRUE);
- sprintf(statustext, "Point added to link #%d",linkid);
+ sprintf(statustext, "Point added to link #%d at position %d,%d.",linkid, x, y);
}
int addvector(vectorimg_t *vimg, int type, int x1, int y1, int x2, int y2, SDL_Color *c, SDL_Color *fc) {
@@ -1737,6 +1931,7 @@ void changegridsize(void) {
gridsizeindex = 0;
}
gridsize = gridsizelist[gridsizeindex];
+ setinfo(255);
sprintf(statustext, "Grid size set to %d.", gridsize);
}
@@ -1811,7 +2006,7 @@ void changelinethickness(int changeby) {
void changemap(int newmap) {
map[newmap].selecteditem = -1;
map[newmap].selecteditemtype = -1;
- map[newmap].selectedtype = map[curmap].selectedtype;
+ /*map[newmap].selectedtype = map[curmap].selectedtype; */
curmap = newmap;
}
@@ -1858,7 +2053,8 @@ void changestate(int newstate) {
sprintf(statustext,"Object creation mode enabled.\n");
break;
case S_CHANGEOBJECT:
- sprintf(statustext,"Object type modification mode enabled.\n");
+ setinfo(255);
+ sprintf(statustext,"Object type modification mode enabled - select new object type...\n");
break;
case S_ADDTEXT:
sprintf(statustext,"Text creation mode entered.\n");
@@ -1870,20 +2066,27 @@ void changestate(int newstate) {
sprintf(statustext,"Text edit mode entered.\n");
break;
case S_MATCHSIZE:
+ setinfo(255);
sprintf(statustext,"Size-matching mode entered - select object to copy size from...\n");
break;
case S_MATCHX:
+ setinfo(255);
sprintf(statustext,"X-matching mode entered - select item to align with...\n");
break;
case S_MATCHY:
+ setinfo(255);
sprintf(statustext,"Y-matching mode entered - select item to align with...\n");
break;
case S_DRAWFLOW:
+ setinfo(255);
sprintf(statustext,"Traffic flow definition mode entered - select items...\n");
break;
case S_MAPNAMING:
sprintf(statustext,"Map rename mode entered.\n");
break;
+ case S_SEARCH:
+ sprintf(statustext,"Search mode entered.\n");
+ break;
case S_SAVING:
sprintf(statustext,"Save mode entered.\n");
break;
@@ -2139,6 +2342,7 @@ void deletelink(int linkid) {
}
map[curmap].numthings--;
} else {
+ seterror(255);
sprintf(statustext,"Can't find matching thing for link #%d!\n",linkid);
}
@@ -2182,6 +2386,7 @@ void deleteobject(int oid) {
}
map[curmap].numthings--;
} else {
+ seterror(255);
sprintf(statustext,"Can't find matching thing for object #%d!\n",oid);
}
@@ -2228,6 +2433,7 @@ void deletetext(int textid) {
}
map[curmap].numthings--;
} else {
+ seterror(255);
sprintf(statustext,"Can't find matching thing for text item #%d!\n",textid);
}
@@ -2237,21 +2443,18 @@ void deletetext(int textid) {
}
-void drawarrowhead(SDL_Surface *screen, double x1, double y1, double x2, double y2, SDL_Color c, int arrowstyle, int arrowpos) {
- double angle;
- int arrowpointx,arrowpointy;
- int arrowend1x,arrowend1y;
- int arrowend2x,arrowend2y;
+
+
+void adjustendpoint(SDL_Surface *screen, int *adjx, int *adjy, double x1, double y1, double x2, double y2, int arrowstyle, int arrowpos ) {
int middlex, middley;
int deltax, deltay;
int numpixels;
int d;
int dinc1,dinc2,xinc1,xinc2,yinc1,yinc2;
- int i;
+ int i,n;
int x;
int y;
int tempx,tempy;
- int arrowlength = 5;
int o,oldo;
SDL_Surface *temps;
int arrowthickness;
@@ -2308,27 +2511,18 @@ void drawarrowhead(SDL_Surface *screen, double x1, double y1, double x2, double
x = x1; y = y1;
- /* calculate arrow length based on line length
- line length > 40 means arrow length is 5,
- otherwise it's 3 */
- if (numpixels > 40) {
- arrowlength = 5;
- } else {
- arrowlength = 3;
- }
- /* adjust for line thickness */
- arrowlength = arrowlength + arrowthickness - 1;
-
-
middlex = -1;
middley = -1;
- temps = SDL_CreateRGBSurface(SDL_SWSURFACE,10,10,
+ /*
+ temps = SDL_CreateRGBSurface(SDL_HWSURFACE,10,10,
screen->format->BitsPerPixel, screen->format->Rmask,
screen->format->Gmask,screen->format->Bmask,
screen->format->Amask);
+ */
+ temps = NULL;
o = -1;
oldo = -99;
@@ -2343,17 +2537,54 @@ void drawarrowhead(SDL_Surface *screen, double x1, double y1, double x2, double
SDL_Color tempc;
if (o != oldo) {
- /* free temporary surface */
- SDL_FreeSurface(temps);
- /* create temp surface */
- temps = SDL_CreateRGBSurface(SDL_SWSURFACE,map[curmap].obj[o].w+3, map[curmap].obj[o].h+3,
- screen->format->BitsPerPixel, screen->format->Rmask,
- screen->format->Gmask,screen->format->Bmask,
- screen->format->Amask);
- /* draw into temporary surface */
- drawobject(temps, &map[curmap].obj[o], FALSE);
+ if (oldo == -99) {
+ SDL_Rect area;
+ int tid;
- oldo = o;
+ temps = SDL_CreateRGBSurface(SDL_HWSURFACE,map[curmap].obj[o].w+3, map[curmap].obj[o].h+3,
+ screen->format->BitsPerPixel, screen->format->Rmask,
+ screen->format->Gmask,screen->format->Bmask,
+ screen->format->Amask);
+ area.x = map[curmap].obj[o].x;
+ area.y = map[curmap].obj[o].y;
+ area.w = map[curmap].obj[o].w;
+ area.h = map[curmap].obj[o].h;
+
+ /* have we already drawn the object? */
+ /* get thingid of this object */
+ tid = -1;
+ for (n = 0; n < map[curmap].numthings; n++) {
+ if ( (map[curmap].thing[n].id == o) &&
+ (map[curmap].thing[n].type == T_OBJECT) ) {
+ tid = n;
+ break;
+ }
+ }
+
+ /* FIXME: drawobject is too slow here!!! */
+ /* but we can't just blit from the screen, in case
+ the object hasn't been drawn yet */
+
+
+ drawobject(temps, &map[curmap].obj[o], FALSE);
+
+
+/*
+ if (tid == -1) {
+ drawobject(temps, &map[curmap].obj[o], FALSE);
+ } else if (thingdrawn[tid] == FALSE) {
+ drawobject(temps, &map[curmap].obj[o], FALSE);
+ } else {
+ SDL_BlitSurface(screen, &area, temps, NULL);
+ }
+*/
+ oldo = o;
+ } else {
+ if (temps != NULL) SDL_FreeSurface(temps);
+ middlex = x;
+ middley = y;
+ break;
+ }
}
/* we can start drawing if we're on the object but on a transparent bit */
ox = x - map[curmap].obj[o].x;
@@ -2383,25 +2614,124 @@ void drawarrowhead(SDL_Surface *screen, double x1, double y1, double x2, double
}
}
- if ((middlex == -1) || (middley == -1)) {
- printf("no place for arrowhead, quitting\n");
- exit(1);
+ *adjx = middlex;
+ *adjy = middley;
+}
+
+int dosearch(void) {
+ int i;
+ int m;
+
+ /* fill in search text */
+ strcpy(searchtext, text);
+
+ /* reset search point */
+ searchmap = 0;
+ searchtob = 0;
+ searchwrap = FALSE;
+
+ /* go through each text object until we find what we're looking for */
+ for (m = 0; m < nummaps; m++) { /* for each map */
+ for (i = 0; i < map[m].numtext; i++) { /* for each text object */
+ /* does it contain the search string? */
+ if (strstr(map[m].textob[i].text, searchtext)) {
+ drillto(m);
+
+ map[m].selecteditemtype = T_TEXT;
+ map[m].selecteditem = i;
+
+ searchmap = m;
+ searchtob = i;
+ return FALSE;
+ }
+ }
}
- if (arrowpos == AP_END) {
- /* put endpoints back */
- tempx = x1;
- tempy = y1;
- x1 = x2;
- y1 = y2;
- x2 = tempx;
- y2 = tempy;
- }
+ return TRUE;
+}
+
+int dosearchnext(void) {
+ int i = -1;
+ int firsttime = TRUE;
+ int m;
+ /* go through each text object until we find what we're looking for */
+ for (m = searchmap; ; m++) { /* for each map */
+ if (m >= nummaps) {
+printf("wrapped\n");
+fflush(stdout);
+ m = 0;
+ searchwrap = TRUE;
+ }
+
+ if ((firsttime) && (m == searchmap)) {
+ i = searchtob+1;
+ firsttime = FALSE;
+ } else {
+ i = 0;
+ }
+
+ for (; i < map[m].numtext; i++) { /* for each text object */
+
+ /* back to start - not found */
+ if ((m == searchmap) && (i == searchtob)) {
+ searchwrap = FALSE;
+ return TRUE;
+ }
+
+printf("searching map %d text %d\n",m,i);
+fflush(stdout);
+ /* does it contain the search string? */
+ if (strstr(map[m].textob[i].text, searchtext)) {
+ drillto(m);
+ map[m].selecteditemtype = T_TEXT;
+ map[m].selecteditem = i;
+
+ searchmap = m;
+ searchtob = i;
+ searchwrap = FALSE;
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+void drawarrowhead(SDL_Surface *screen, double x1, double y1, double x2, double y2, SDL_Color c, int arrowstyle, int arrowpos) {
+ double angle;
+ int arrowpointx,arrowpointy;
+ int arrowend1x,arrowend1y;
+ int arrowend2x,arrowend2y;
+ int middlex, middley;
+ int numpixels;
+ int arrowlength = 5;
+ int arrowthickness;
+
+ arrowthickness = (arrowstyle & 0x0000ff);
+
+ /* calculate arrow length based on line length
+ line length > 40 means arrow length is 5,
+ otherwise it's 3 */
+ if (numpixels > 40) {
+ arrowlength = 5;
+ } else {
+ arrowlength = 3;
+ }
+ /* adjust for line thickness */
+ arrowlength = arrowlength + arrowthickness - 1;
/* calculate angle of line */
angle = atan2(y2-y1,x2-x1);
+ if (arrowpos == AP_START) {
+ middlex = x1;
+ middley = y1;
+ } else {
+ middlex = x2;
+ middley = y2;
+ }
+
if (arrowpos == AP_END) {
angle += M_PI;
//if (angle > 360) angle -= 360;
@@ -2443,6 +2773,85 @@ void drawarrowhead(SDL_Surface *screen, double x1, double y1, double x2, double
drawline(screen, arrowpointx, arrowpointy, arrowend2x, arrowend2y, c, arrowstyle);
}
+void drawarrowheadSVG(double x1, double y1, double x2, double y2, SDL_Color c, int arrowstyle, int arrowpos) {
+ double angle;
+ int arrowpointx,arrowpointy;
+ int arrowend1x,arrowend1y;
+ int arrowend2x,arrowend2y;
+ int middlex, middley;
+ int numpixels;
+ int arrowlength = 5;
+ int arrowthickness;
+
+ arrowthickness = (arrowstyle & 0x0000ff);
+
+
+ /* calculate arrow length based on line length
+ line length > 40 means arrow length is 5,
+ otherwise it's 3 */
+ if (numpixels > 40) {
+ arrowlength = 5;
+ } else {
+ arrowlength = 3;
+ }
+ /* adjust for line thickness */
+ arrowlength = arrowlength + arrowthickness - 1;
+
+ /* calculate angle of line */
+ angle = atan2(y2-y1,x2-x1);
+
+ if (arrowpos == AP_START) {
+ middlex = x1;
+ middley = y1;
+ } else {
+ middlex = x2;
+ middley = y2;
+ }
+
+
+ if (arrowpos == AP_END) {
+ angle += M_PI;
+ //if (angle > 360) angle -= 360;
+ }
+ angle = -angle;
+
+ /* original arrowhead is:
+ *
+ * / (5,-5)
+ * /
+ * (0,0) <
+ * \
+ * \ (5,5)
+ */
+
+ /* rotate arrowhead */
+ arrowpointx = 0;
+ arrowpointy = 0;
+ arrowend1x = (arrowlength * cos(angle)) + (-arrowlength * sin(angle));
+ arrowend1y = (-arrowlength * sin(angle)) + (-arrowlength * cos(angle));
+ arrowend2x = (arrowlength * cos(angle)) + (arrowlength * sin(angle));
+ arrowend2y = (-arrowlength * sin(angle)) + (arrowlength * cos(angle));
+
+
+ /* translate arrowhead into position */
+ arrowpointx = middlex;
+ arrowpointy = middley;
+ arrowend1x += middlex;
+ arrowend1y += middley;
+ arrowend2x += middlex;
+ arrowend2y += middley;
+
+ /* get rid of the 'linestyle' and 'arrow' parts of arrowstyle to
+ * (respectively) make sure the arrow looks okay and
+ * avoid an infinite loop! */
+ arrowstyle &= 0x000000ff;
+
+ sprintf(svgbuf,"\n", arrowpointx, arrowpointy, arrowend1x, arrowend1y,c.r,c.g,c.b, arrowstyle );
+ fprintf(svgfile, svgbuf);
+ sprintf(svgbuf,"\n", arrowpointx, arrowpointy, arrowend2x, arrowend2y,c.r,c.g,c.b, arrowstyle );
+ fprintf(svgfile, svgbuf);
+}
+
void lerp(int *newx, int *newy, int ax, int ay, int bx, int by, float t) {
*newx = ax + (bx - ax) * t;
*newy = ay + (by - ay) * t;
@@ -2663,16 +3072,6 @@ void drawcolorchart(SDL_Surface *dest) {
SDL_Flip(screen);
}
-int drawletter(SDL_Surface *dest,int x, int y, int w, int h, char let, SDL_Color col) {
- if ((let < FIRSTLET) || (let > LASTLET)) {
- return TRUE;
- }
-
- drawvector(dest, &letter[let-FIRSTLET].vect, x, y, w,h, &col, NULL);
-
- return FALSE;
-}
-
int findpointpos(link_t *l, int px, int py) {
int i;
int x,y,x2,y2;
@@ -2807,17 +3206,44 @@ void drawline(SDL_Surface *screen, int x1, int y1, int x2, int y2, SDL_Color c,
void drawlink(SDL_Surface *dest, link_t *l) {
int i;
int x,y,x2,y2;
+ int arrow;
+ int adjx,adjy;
+ int flow;
+
+ flow = l->col.unused & ISFLOW;
x = map[curmap].obj[l->srcobj].x + l->srcxoff;
y = map[curmap].obj[l->srcobj].y + l->srcyoff;
+ arrow = (l->style & 0x00ff0000) >> 16;
for (i = 0; i < l->npoints; i++) {
x2 = l->point[i].x;
y2 = l->point[i].y;
+
+ /* if this is the first point and the line is of
+ type "arrowhead at start" then draw an arrow */
+
+ if ( (i == 0) &&
+ ((arrow == AP_START) || (arrow == AP_BOTH))
+ ) {
+ int tempstyle;
+ tempstyle = l->style & (0xff00ffff);
+ tempstyle |= (AP_START << 16);
- /* clear the "arrowhead" part of these */
- //drawline(dest, x,y,x2,y2, l->col,l->style & 0xff00ffff);
- drawline(dest, x,y,x2,y2, l->col,l->style);
+ /* adjust start point */
+ if (flow) {
+ adjx = x;
+ adjy = y;
+ } else {
+ adjustendpoint(dest, &adjx, &adjy, x,y,x2,y2,l->style, AP_START);
+ }
+ drawline(dest, adjx,adjy,x2,y2, l->col,tempstyle);
+ } else {
+ /* clear the "arrowhead" part of these */
+ adjx = x;
+ adjy = y;
+ drawline(dest, adjx,adjy,x2,y2, l->col,l->style & 0xff00ffff);
+ }
x = x2;
y = y2;
@@ -2827,7 +3253,40 @@ void drawlink(SDL_Surface *dest, link_t *l) {
x2 = map[curmap].obj[l->dstobj].x + l->dstxoff;
y2 = map[curmap].obj[l->dstobj].y + l->dstyoff;
- drawline(dest, x,y,x2,y2, l->col,l->style);
+ /* adjust end */
+ if (l->npoints >= 1) {
+ if ( (arrow == AP_END) || (arrow == AP_BOTH)) {
+ int tempstyle;
+ tempstyle = l->style & (0xff00ffff);
+ tempstyle |= (AP_END << 16);
+
+ if (!flow) {
+ adjustendpoint(dest, &adjx, &adjy, x,y,x2,y2,l->style & 0xff00ffff, AP_END);
+ x2 = adjx ; y2 = adjy;
+ }
+
+ drawline(dest, x,y,x2,y2, l->col,tempstyle);
+ } else {
+ /* clear the "arrowhead" part of these */
+ drawline(dest, x,y,x2,y2, l->col,l->style & 0xff00ffff);
+ }
+ } else {
+ /* adjust start */
+ if (!flow) {
+ if ((arrow == AP_START) || (arrow == AP_BOTH)) {
+ adjustendpoint(dest, &adjx, &adjy, x,y,x2,y2,l->style & 0xff00ffff, AP_START);
+ x = adjx ; y = adjy;
+ }
+ }
+ /* adjust end */
+ if (!flow) {
+ if ((arrow == AP_END) || (arrow == AP_BOTH)) {
+ adjustendpoint(dest, &adjx, &adjy, x,y,x2,y2,l->style & 0xff00ffff, AP_END);
+ x2 = adjx ; y2 = adjy;
+ }
+ }
+ drawline(dest, x,y,x2,y2, l->col,l->style);
+ }
}
void drawlinkSVG(link_t *l) {
@@ -2840,15 +3299,19 @@ void drawlinkSVG(link_t *l) {
int cur,old;
int count;
int first;
-
+ int arrow;
+ int adjx,adjy;
+ int flow;
x = map[curmap].obj[l->srcobj].x + l->srcxoff;
y = map[curmap].obj[l->srcobj].y + l->srcyoff;
+ flow = l->col.unused & ISFLOW;
/* get attributes */
- width = l->style & 0x000000ff;
+ width = l->style & 0x000000ff;
linestyle = (l->style & 0x0000ff00) >> 8;
+ arrow = (l->style & 0x00ff0000) >> 16;
old = linemask[linestyle][0];
count = 1;
@@ -2886,12 +3349,29 @@ void drawlinkSVG(link_t *l) {
for (i = 0; i < l->npoints; i++) {
x2 = l->point[i].x;
y2 = l->point[i].y;
-
- /* TODO: add arrowheads and dotted lines */
+
sprintf(svgbuf,"\n", x, y, x2, y2,l->col.r,l->col.g,l->col.b, width ,dasharray);
fprintf(svgfile, svgbuf);
+ /* draw arrowhead if required */
+ if ( (i == 0) &&
+ ((arrow == AP_START) || (arrow == AP_BOTH))
+ ) {
+ int tempstyle;
+ tempstyle = l->style & (0xff00ffff);
+ tempstyle |= (AP_START << 16);
+
+ if (flow) {
+ adjx = x;
+ adjy = y;
+ } else {
+ adjustendpoint(screen, &adjx, &adjy, x,y,x2,y2,l->style, AP_START);
+ }
+
+ drawarrowheadSVG(adjx,adjy,x2,y2, l->col,tempstyle, arrow);
+ }
+
x = x2;
y = y2;
}
@@ -2900,6 +3380,53 @@ void drawlinkSVG(link_t *l) {
x2 = map[curmap].obj[l->dstobj].x + l->dstxoff;
y2 = map[curmap].obj[l->dstobj].y + l->dstyoff;
+ /* draw arrow if required */
+ if (l->npoints >= 1) {
+ if ( (arrow == AP_END) || (arrow == AP_BOTH)) {
+ int tempstyle;
+ tempstyle = l->style & (0xff00ffff);
+ tempstyle |= (AP_END << 16);
+
+ if (!flow) {
+ adjustendpoint(screen, &adjx, &adjy, x,y,x2,y2,l->style, AP_END);
+ x2 = adjx;
+ y2 = adjy;
+ }
+ drawarrowheadSVG(x,y,x2,y2, l->col,tempstyle, AP_END);
+ }
+ } else {
+ /* adjust start point too */
+
+ if ( (arrow == AP_START) || (arrow == AP_BOTH)) {
+ int tempstyle;
+ tempstyle = l->style & (0xff00ffff);
+ tempstyle |= (AP_START << 16);
+
+ if (!flow) {
+ adjustendpoint(screen, &adjx, &adjy, x,y,x2,y2,l->style, AP_START);
+ x = adjx;
+ y = adjy;
+ }
+
+ drawarrowheadSVG(x,y,x2,y2, l->col,tempstyle, AP_START);
+ }
+ if ( (arrow == AP_END) || (arrow == AP_BOTH)) {
+ int tempstyle;
+ tempstyle = l->style & (0xff00ffff);
+ tempstyle |= (AP_END << 16);
+
+ if (!flow) {
+ adjustendpoint(screen, &adjx, &adjy, x,y,x2,y2,l->style, AP_END);
+ x2 = adjx;
+ y2 = adjy;
+ }
+
+ drawarrowheadSVG(x,y,x2,y2, l->col,tempstyle, AP_END);
+ }
+ }
+
+
+
sprintf(svgbuf,"\n", x, y, x2, y2,l->col.r,l->col.g,l->col.b, width ,dasharray);
fprintf(svgfile, svgbuf);
}
@@ -2917,7 +3444,7 @@ void drawobject(SDL_Surface *dest, mapobject_t *o, int doublebuffer) {
fflush(stdout);
}
if (doublebuffer) {
- temps = SDL_CreateRGBSurface(SDL_SWSURFACE,o->w+3, o->h+3,
+ temps = SDL_CreateRGBSurface(SDL_HWSURFACE,o->w+3, o->h+3,
screen->format->BitsPerPixel, screen->format->Rmask,
screen->format->Gmask,screen->format->Bmask,
screen->format->Amask);
@@ -3053,9 +3580,12 @@ void drawmap(void) {
int anchoreditem;
int x,y;
+ for (i = 0; i < map[curmap].numthings; i++) {
+ thingdrawn[i] = FALSE;
+ }
- if ((state == S_SAVING) || (state == S_LOADING) || (state == S_MAPNAMING)) {
- /* show file dialog */
+ if ((state == S_SAVING) || (state == S_LOADING) || (state == S_MAPNAMING) || (state == S_SEARCH)) {
+ /* show text entry screen */
showfiledialog();
return;
}
@@ -3101,58 +3631,55 @@ void drawmap(void) {
if (testing) {
printf("DRAWING THINGS \n"); fflush(stdout);
}
+
+
/* draw all map[curmap].objects links etc*/
for (i = 0; i < map[curmap].numthings; i++) {
if (map[curmap].thing[i].type == T_OBJECT) {
if (testing) { printf("Drawing thing #%d (%d, %s)\n",i,map[curmap].thing[i].id,objtype[map[curmap].obj[map[curmap].thing[i].id].type].name); fflush(stdout); }
- if (!isflow(map[curmap].thing[i].id, T_OBJECT) || (showflows == TRUE)) {
+ if (!isflow(map[curmap].thing[i].id, T_OBJECT)) {
drawobject(buffer, &map[curmap].obj[map[curmap].thing[i].id], TRUE);
+ thingdrawn[i] = TRUE;
}
- if (isflow(map[curmap].thing[i].id, T_OBJECT)) {
- if (state == S_DRAWFLOW) {
- drawflowbox(buffer, map[curmap].thing[i].id, T_OBJECT);
- }
- }
} else if (map[curmap].thing[i].type == T_LINK) {
if (testing) { printf ("Drawing thing #%d (%d, link)\n",i,map[curmap].thing[i].id); fflush(stdout); }
- if (!isflow(map[curmap].thing[i].id, T_LINK) || (showflows == TRUE)) {
+ if (!isflow(map[curmap].thing[i].id, T_LINK)) {
drawlink(buffer, &map[curmap].olink[map[curmap].thing[i].id]);
- }
- if (isflow(map[curmap].thing[i].id, T_LINK)) {
- if (state == S_DRAWFLOW) {
- drawflowbox(buffer, map[curmap].thing[i].id, T_LINK);
- }
+ thingdrawn[i] = TRUE;
}
} else if (map[curmap].thing[i].type == T_TEXT) {
if (testing) { printf ("Drawing thing #%d (%d, text)\n",i,map[curmap].thing[i].id); fflush(stdout); }
- if (!isflow(map[curmap].thing[i].id, T_TEXT) || (showflows == TRUE)) {
+ if (!isflow(map[curmap].thing[i].id, T_TEXT)) {
drawtext(buffer, &map[curmap].textob[map[curmap].thing[i].id]);
- }
- if (isflow(map[curmap].thing[i].id, T_TEXT)) {
- if (state == S_DRAWFLOW) {
- drawflowbox(buffer, map[curmap].thing[i].id, T_TEXT);
- }
+ thingdrawn[i] = TRUE;
}
} else {
printf("WARNING: Thing #%d has unknown type %d!\n",i,map[curmap].thing[i].type);
+ thingdrawn[i] = TRUE;
}
}
/* show traffic flows (these should be on top of everything else) */
- if (state == S_DRAWFLOW) {
+ if (showflows) {
for (i = 0; i < map[curmap].numthings; i++) {
if (map[curmap].thing[i].type == T_OBJECT) {
if (isflow(map[curmap].thing[i].id, T_OBJECT)) {
- drawflowbox(buffer, map[curmap].thing[i].id, T_OBJECT);
+ drawobject(buffer, &map[curmap].obj[map[curmap].thing[i].id], TRUE);
+ if (state == S_DRAWFLOW) drawflowbox(buffer, map[curmap].thing[i].id, T_OBJECT);
+ thingdrawn[i] = TRUE;
}
} else if (map[curmap].thing[i].type == T_LINK) {
if (isflow(map[curmap].thing[i].id, T_LINK)) {
- drawflowbox(buffer, map[curmap].thing[i].id, T_LINK);
+ drawlink(buffer, &map[curmap].olink[map[curmap].thing[i].id]);
+ if (state == S_DRAWFLOW) drawflowbox(buffer, map[curmap].thing[i].id, T_LINK);
+ thingdrawn[i] = TRUE;
}
} else if (map[curmap].thing[i].type == T_TEXT) {
if (isflow(map[curmap].thing[i].id, T_TEXT)) {
- drawflowbox(buffer, map[curmap].thing[i].id, T_TEXT);
+ drawtext(buffer, &map[curmap].textob[map[curmap].thing[i].id]);
+ if (state == S_DRAWFLOW) drawflowbox(buffer, map[curmap].thing[i].id, T_TEXT);
+ thingdrawn[i] = TRUE;
}
}
}
@@ -3369,15 +3896,32 @@ void drawmap(void) {
void drawstatusbar(void) {
Uint32 col;
SDL_Rect area;
-
- col = SDL_MapRGB(screen->format, map[curmap].bgcol.r, map[curmap].bgcol.g, map[curmap].bgcol.b);
+ if (errorflash) {
+ statusbarcolour.r = 255;
+ statusbarcolour.g = 255 - errorflash;
+ statusbarcolour.b = 255 - errorflash;
+ } else if (infoflash) {
+ statusbarcolour.r = 255 - infoflash;
+ statusbarcolour.g = 255;
+ statusbarcolour.b = 255 - infoflash;
+ }
+
+ /* clear it */
+ /*col = SDL_MapRGB(screen->format, map[curmap].bgcol.r, map[curmap].bgcol.g, map[curmap].bgcol.b);*/
+ col = SDL_MapRGB(screen->format, statusbarcolour.r, statusbarcolour.g, statusbarcolour.b);
area.x = 0;
area.y = map[curmap].height;
area.w = map[curmap].width;
area.h = map[curmap].height + DEFTEXTH + 3;
-
SDL_FillRect(screen, &area, col);
+
+ if ((errorflash) || (infoflash)) {
+ statusbarcolour.r = 255;
+ statusbarcolour.g = 255;
+ statusbarcolour.b = 255;
+ }
+
drawline(screen, 0, map[curmap].height, map[curmap].width, map[curmap].height, blue,1);
/* strip newlines from text */
@@ -3419,20 +3963,43 @@ int drawSVG(char *svgfilename) {
return TRUE;
}
+
/* draw all map[curmap].objects links etc*/
for (i = 0; i < map[curmap].numthings; i++) {
if (map[curmap].thing[i].type == T_OBJECT) {
- if (!isflow(map[curmap].thing[i].id, T_OBJECT) || (showflows == TRUE)) {
+ if (!isflow(map[curmap].thing[i].id, T_OBJECT)) {
drawobjectSVG(buffer, &map[curmap].obj[map[curmap].thing[i].id], TRUE);
}
} else if (map[curmap].thing[i].type == T_LINK) {
- if (!isflow(map[curmap].thing[i].id, T_LINK) || (showflows == TRUE)) {
- drawlinkSVG( &map[curmap].olink[map[curmap].thing[i].id]);
+ if (!isflow(map[curmap].thing[i].id, T_LINK)) {
+ drawlinkSVG(&map[curmap].olink[map[curmap].thing[i].id]);
}
} else if (map[curmap].thing[i].type == T_TEXT) {
- if (!isflow(map[curmap].thing[i].id, T_TEXT) || (showflows == TRUE)) {
+ if (!isflow(map[curmap].thing[i].id, T_TEXT)) {
drawtextSVG(&map[curmap].textob[map[curmap].thing[i].id]);
}
+ } else {
+ printf("WARNING: Thing #%d has unknown type %d!\n",i,map[curmap].thing[i].type);
+ }
+ }
+
+
+ /* show traffic flows (these should be on top of everything else) */
+ if (showflows) {
+ for (i = 0; i < map[curmap].numthings; i++) {
+ if (map[curmap].thing[i].type == T_OBJECT) {
+ if (isflow(map[curmap].thing[i].id, T_OBJECT)) {
+ drawobjectSVG(buffer, &map[curmap].obj[map[curmap].thing[i].id], TRUE);
+ }
+ } else if (map[curmap].thing[i].type == T_LINK) {
+ if (isflow(map[curmap].thing[i].id, T_LINK)) {
+ drawlinkSVG(&map[curmap].olink[map[curmap].thing[i].id]);
+ }
+ } else if (map[curmap].thing[i].type == T_TEXT) {
+ if (isflow(map[curmap].thing[i].id, T_TEXT)) {
+ drawtextSVG(&map[curmap].textob[map[curmap].thing[i].id]);
+ }
+ }
}
}
@@ -3452,6 +4019,10 @@ void drawmapbox(void) {
Uint32 fillcol;
SDL_Rect area;
int tw,th;
+ char temptext[BUFLEN];
+ int changed;
+ int donesomething;
+ char name1[BUFLEN], name2[BUFLEN];
x = mapbox.x+1;
@@ -3468,13 +4039,34 @@ void drawmapbox(void) {
SDL_FillRect(screen, &area, fillcol);
SDL_UpdateRect(screen, area.x, area.y, area.w, area.h);
+ /* determine size of each row in pixels (and the width of the title) */
+ strcpy(temptext, map[curmap].name);
+ TTF_SizeText(font[lh], temptext, &tw,&th);
+
+ /* truncate name until it will fit */
+ changed = FALSE;
+ while (tw >= mapbox.width) {
+ if (changed) {
+ /* change last char to ".." */
+ temptext[strlen(temptext)-1] = '\0';
+ strcat(temptext, "..");
+ changed = TRUE;
+ } else {
+ /* change 3rd last char to '.', and lose 1 char off end */
+ temptext[strlen(temptext)-3] = '.';
+ temptext[strlen(temptext)-1] = '\0';
+ }
+ TTF_SizeText(font[lh], temptext, &tw,&th);
+ }
+
/* box around edge */
drawbox(screen, mapbox.x, mapbox.y, mapbox.x + mapbox.width-2,mapbox.y + mapbox.height,white, NULL);
- /* current map */
+ drawbox(screen, mapbox.x+1, mapbox.y+1, mapbox.x + mapbox.width-3,mapbox.y + th,white, &white);
- drawtextat(screen, x, y, map[curmap].name, lh, white);
- TTF_SizeText(font[lh], map[curmap].name, &tw,&th);
+ /* current map */
+ /* centre this inside the map box */
+ drawtextat(screen, (x+((mapbox.width-3)/2) - (tw/2)), y, temptext, lh, black);
y += th;
@@ -3493,7 +4085,6 @@ void drawmapbox(void) {
y += th;
/* children ... */
-
/* first generate list of children */
numchildren = 0;
@@ -3515,6 +4106,39 @@ void drawmapbox(void) {
}
}
+ /* sort the list */
+ donesomething = TRUE;
+ while (donesomething) {
+ donesomething = FALSE;
+ for (i = 0; i < (numchildren-1); i++) {
+ /* get name of this one */
+ strcpy(name1, "");
+ strcpy(name2, "");
+ for (n = 0; n < map[curmap].numobjects; n++) {
+ if (!strcmp(name1, "")) {
+ if (map[curmap].obj[n].child == children[i]) {
+ sprintf(name1, map[map[curmap].obj[n].child].name);
+ }
+ }
+ if (!strcmp(name2, "")) {
+ if (map[curmap].obj[n].child == children[i+1]) {
+ sprintf(name2, map[map[curmap].obj[n].child].name);
+ }
+ }
+ }
+
+
+ if (strcmp(name1, name2) > 0) {
+ int tempnum;
+ /* swap them */
+ tempnum = children[i];
+ children[i] = children[i+1];
+ children[i+1] = tempnum;
+ donesomething = TRUE;
+ }
+ }
+ }
+
/* now draw all children, starting at mapbox.offset */
for (i = mapbox.offset; i < numchildren; i++) {
if ((i == mapbox.offset) && (mapbox.offset > 0)) {
@@ -3538,13 +4162,37 @@ void drawmapbox(void) {
}
}
+ TTF_SizeText(font[lh], temp.text, &tw,&th);
+
+ /* truncate name until it will fit */
+ changed = FALSE;
+ while (tw >= mapbox.width) {
+ if (changed) {
+ /* change last char to ".." */
+ temp.text[strlen(temp.text)-1] = '\0';
+ strcat(temp.text, "..");
+ changed = TRUE;
+ } else {
+ /* change 3rd last char to '.', and lose 1 char off end */
+ temp.text[strlen(temp.text)-3] = '.';
+ temp.text[strlen(temp.text)-1] = '\0';
+ }
+ TTF_SizeText(font[lh], temp.text, &tw,&th);
+ }
+
temp.x = x;
temp.y = y;
temp.h = lh;
TTF_SizeText(font[lh], temp.text, &tw,&th);
temp.w = tw;
temp.anchor = -1;
- temp.c = white;
+
+ /* is this map already in our history? if so show it in a different colour */
+ if (isinhistory(children[i]) != -1) {
+ temp.c = cyan;
+ } else {
+ temp.c = white;
+ }
if (temp.y + temp.h >= (mapbox.y + mapbox.height)) {
SDL_Rect ar;
@@ -3758,7 +4406,6 @@ void drawtext(SDL_Surface *dest, text_t *t) {
/* calculate letter width, letter height */
tw = t->w / strlen(t->text);
- //tw = DEFTEXTW;
th = t->h;
if (t->anchor == -1) {
@@ -4099,7 +4746,7 @@ void drawvector(SDL_Surface *dest, vectorimg_t *vimg, int x, int y, int w, int h
if ((vimg->vector[i].type == VT_POLY) || (vimg->vector[i].type == VT_SUBOBJ)) {
if (temp == NULL) {
- temp = SDL_CreateRGBSurface(SDL_SWSURFACE,w+3, h+3,
+ temp = SDL_CreateRGBSurface(SDL_HWSURFACE,w+3, h+3,
screen->format->BitsPerPixel, screen->format->Rmask,
screen->format->Gmask,screen->format->Bmask, screen->format->Amask);
// clear temp surface to bg colour
@@ -4117,7 +4764,7 @@ void drawvector(SDL_Surface *dest, vectorimg_t *vimg, int x, int y, int w, int h
}
} else if (vimg->vector[i].type != VT_ENDPOLY) {
if (!insubobj) {
- temp = SDL_CreateRGBSurface(SDL_SWSURFACE,w+3, h+3,
+ temp = SDL_CreateRGBSurface(SDL_HWSURFACE,w+3, h+3,
screen->format->BitsPerPixel, screen->format->Rmask,
screen->format->Gmask,screen->format->Bmask, screen->format->Amask);
// clear temp surface to bg colour
@@ -4607,6 +5254,7 @@ int endtextedit(void) {
int endtextmove(int x, int y) {
int txoff,tyoff;
+ SDL_FreeSurface(shadow);
SDL_FreeSurface(bg);
if (map[curmap].textob[map[curmap].curtext].anchor == -1) {
@@ -4807,9 +5455,10 @@ void goback(void) {
if (numhistory >= 1) {
changemap(history[numhistory-1]);
numhistory--;
- sprintf(statustext, "Changed map to map #%d (%s).",curmap,map[curmap].name);
+ sprintf(statustext, "Drilled back to #%d (%s) - current depth is %d.",curmap,map[curmap].name, numhistory);
drawmap();
} else {
+ seterror(255);
sprintf(statustext, "Already at top level!");
drawstatusbar();
}
@@ -4883,6 +5532,7 @@ int loadmap(void) {
f = fopen(filename, "rb");
if (!f) {
+ seterror(255);
sprintf(statustext,"ERROR: Cannot open '%s'.\n",filename);
return TRUE;
}
@@ -5035,7 +5685,12 @@ int loadmap(void) {
curmap = 0;
+ grid = FALSE;
+
setmod(FALSE);
+ if (!autoload) {
+ setinfo(255);
+ }
sprintf(statustext,"Successfully loaded map from '%s' (%d maps). [file version: '%s']\n",filename,nummaps, vers);
strcpy(currentfilename, filename);
@@ -5046,35 +5701,42 @@ int loadmap(void) {
return FALSE;
}
-void lowerselected(void) {
- int i;
+void lowerselected(int amt) {
+ int i,n;
int temptype,tempid;
int target;
- /* find map[curmap].object */
- for (i = 0; i < map[curmap].numthings; i++) {
- if ((map[curmap].thing[i].id == map[curmap].selecteditem) && (map[curmap].thing[i].type == map[curmap].selecteditemtype)) {
- /* swap with one below */
- if (i == 0) {
+
+ for (n = 0; n < amt; n++) {
+ /* find map[curmap].object */
+ for (i = 0; i < map[curmap].numthings; i++) {
+ if ((map[curmap].thing[i].id == map[curmap].selecteditem) && (map[curmap].thing[i].type == map[curmap].selecteditemtype)) {
+ /* swap with one below */
+ if (i == 0) {
+ target = i;
+ break;
+ } else {
+ target = i-1;
+ }
+ tempid = map[curmap].thing[target].id;
+ temptype = map[curmap].thing[target].type;
+ map[curmap].thing[target].id = map[curmap].thing[i].id;
+ map[curmap].thing[target].type = map[curmap].thing[i].type;
+ map[curmap].thing[i].id = tempid;
+ map[curmap].thing[i].type = temptype;
break;
- } else {
- target = i-1;
}
- tempid = map[curmap].thing[target].id;
- temptype = map[curmap].thing[target].type;
- map[curmap].thing[target].id = map[curmap].thing[i].id;
- map[curmap].thing[target].type = map[curmap].thing[i].type;
- map[curmap].thing[i].id = tempid;
- map[curmap].thing[i].type = temptype;
- break;
}
+ if (i == 0) break;
}
setmod(TRUE);
+ sprintf(statustext, "Selected item position lowered by %d (now %d of %d).", n, target+1, map[curmap].numthings);
/* redraw map */
drawmap();
}
int objat(int x, int y) {
int i;
+/*
for (i = 0; i < map[curmap].numobjects; i++) {
if ( (x >= map[curmap].obj[i].x ) && (x <= (map[curmap].obj[i].x + map[curmap].obj[i].w)) &&
(y >= map[curmap].obj[i].y ) && (y <= (map[curmap].obj[i].y + map[curmap].obj[i].h)) ) {
@@ -5085,6 +5747,21 @@ int objat(int x, int y) {
}
}
+*/
+ /* traverse thing list backwards so we hit "higher" objects first */
+ for (i = (map[curmap].numthings-1); i >= 0; i--) {
+ if (map[curmap].thing[i].type == T_OBJECT) {
+ int oid = map[curmap].thing[i].id;
+
+ if ( (x >= map[curmap].obj[oid].x ) && (x <= (map[curmap].obj[oid].x + map[curmap].obj[oid].w)) &&
+ (y >= map[curmap].obj[oid].y ) && (y <= (map[curmap].obj[oid].y + map[curmap].obj[oid].h)) ) {
+
+ if (!isflow(oid, T_OBJECT) || (showflows == TRUE)) {
+ return oid;
+ }
+ }
+ }
+ }
return -1;
}
@@ -5092,10 +5769,12 @@ int objat(int x, int y) {
void paste(void) {
if (copytype == T_MAP) {
if (copymap == curmap) {
- sprintf(statustext,"Error: copy source and destination are the same!");
+ seterror(255);
+ sprintf(statustext,"ERROR: copy source and destination maps are the same!");
drawstatusbar();
} else if (copymap < 0) {
- sprintf(statustext,"Error: No copy source selected!");
+ seterror(255);
+ sprintf(statustext,"ERROR: No copy source selected!");
drawstatusbar();
} else {
map[curmap] = map[copymap];
@@ -5198,6 +5877,7 @@ void paste(void) {
sprintf(statustext,"Object pasted at %d,%d.",newx,newy);
drawmap();
} else {
+ seterror(255);
sprintf(statustext,"Error: No copy source selected!");
drawstatusbar();
}
@@ -5391,7 +6071,9 @@ int initgraphics(void) {
linemask[LS_DOTTED][0] = 1;
linemask[LS_DOTTED][1] = 0;
- linemask[LS_DOTTED][2] = -1;
+ linemask[LS_DOTTED][2] = 1;
+ linemask[LS_DOTTED][3] = 0;
+ linemask[LS_DOTTED][4] = -1;
linemask[LS_BIGDASH][0] = 1;
linemask[LS_BIGDASH][1] = 1;
@@ -5488,7 +6170,7 @@ int initgraphics(void) {
printf("SDL_SetVideoMode: %s\n", SDL_GetError());
return -1;
}
- if (screen->flags & SDL_SWSURFACE) {
+ if (screen->flags & SDL_HWSURFACE) {
printf("SWSurface set ok.\n"); fflush(stdout);
}
if (screen->flags & SDL_HWSURFACE) {
@@ -5501,7 +6183,7 @@ int initgraphics(void) {
updatewm();
/* set up toolbox highlight image */
- toolhilite = SDL_CreateRGBSurface(SDL_SWSURFACE,toolbox.gridsize+3, toolbox.gridsize+3,
+ toolhilite = SDL_CreateRGBSurface(SDL_HWSURFACE,toolbox.gridsize+3, toolbox.gridsize+3,
screen->format->BitsPerPixel, screen->format->Rmask,
screen->format->Gmask,screen->format->Bmask,
screen->format->Amask);
@@ -5515,7 +6197,7 @@ screen->format->Amask);
SDL_SetAlpha(toolhilite, SDL_SRCALPHA, 128);
/* initialise buffer */
- buffer = SDL_CreateRGBSurface(SDL_SWSURFACE,map[curmap].width,map[curmap].height,
+ buffer = SDL_CreateRGBSurface(SDL_HWSURFACE,map[curmap].width,map[curmap].height,
screen->format->BitsPerPixel, screen->format->Rmask,
screen->format->Gmask,screen->format->Bmask,
screen->format->Amask);
@@ -5942,7 +6624,7 @@ screen->format->Amask);
/* allocate mem */
- button[numbuttons].img = SDL_CreateRGBSurface(SDL_SWSURFACE,toolbox.gridsize-2,toolbox.gridsize-2,
+ button[numbuttons].img = SDL_CreateRGBSurface(SDL_HWSURFACE,toolbox.gridsize-2,toolbox.gridsize-2,
screen->format->BitsPerPixel, screen->format->Rmask,
screen->format->Gmask,screen->format->Bmask,
screen->format->Amask);
@@ -6094,141 +6776,20 @@ screen->format->Amask);
}
-#if 0
-int readletters() {
- printf("Reading letters...\n");
- f = fopen("letters.dat","rt");
- if (!f) {
- sprintf(file, "/usr/local/share/netmapr/letters.dat");
- f = fopen(file,"rt");
- }
- if (!f) {
- sprintf(file, "%s/letters.dat",progdir);
- f = fopen(file,"rt");
- }
- if (!f) {
- printf("Cannot open letters file!\n");
- exit(1);
- }
+int isinhistory (int mapid) {
+ int i;
+ int found;
- state = 0;
- line = 0;
- numletters = 0;
- n = 0;
- fgets(buf, BUFLEN, f);
- buf[strlen(buf)-1] = '\0';
- line++;
- while (!feof(f)) {
- // ignore comments
- if (buf[0] != '#') {
- if (state == 0) {
- p = strtok(buf, " ");
- if (p == NULL) { printf("Missing token on line #%d of letters file.\n",line); exit(1); }
- if (strcmp(p, "letter")) {
- printf("Expecting 'letter' on line #%d of letters file (got '%s').\n",line,p);
- exit(1);
- }
- // name
- p = strtok(NULL, " ");
- if (p == NULL) { printf("Missing token on line #%d of letters file.\n",line); exit(1); }
- letter[numletters].name = p[0];
- // width
- p = strtok(NULL, " ");
- if (p == NULL) { printf("Missing token on line #%d of letters file.\n",line); exit(1); }
- letter[numletters].vect.w = atoi(p);
- // height
- p = strtok(NULL, " ");
- if (p == NULL) { printf("Missing token on line #%d of letters file.\n",line); exit(1); }
- letter[numletters].vect.h = atoi(p);
-
-
- letter[numletters].vect.vnum = 0;
-
-
- state = 1;
- } else if (state == 1) {
- p = strtok(buf, " ");
- if (p == NULL) { printf("Missing token on line #%d of letters file.\n",line); exit(1); }
- if (!strcmp(p, "line")) {
- p = strtok(NULL, " ");
- if (p == NULL) { printf("Missing token on line #%d of letters file.\n",line); exit(1); }
- x1 = atoi(p);
- p = strtok(NULL, " ");
- if (p == NULL) { printf("Missing token on line #%d of letters file.\n",line); exit(1); }
- y1 = atoi(p);
- p = strtok(NULL, " ");
- if (p == NULL) { printf("Missing token on line #%d of letters file.\n",line); exit(1); }
- x2 = atoi(p);
- p = strtok(NULL, " ");
- if (p == NULL) { printf("Missing token on line #%d of letters file.\n",line); exit(1); }
- y2 = atoi(p);
-
- c = fgcol;
-
- if (addvector(&letter[numletters].vect,VT_LINE,x1,y1,x2,y2,&c, NULL)) {
- printf("Too many vectors on line %d of letters file.\n",line);
- exit(1);
- }
- } else if (!strcmp(p, "fill")) {
- p = strtok(NULL, " ");
- if (p == NULL) { printf("Missing token on line #%d of letters file.\n",line); exit(1); }
- x1 = atoi(p);
- p = strtok(NULL, " ");
- if (p == NULL) { printf("Missing token on line #%d of letters file.\n",line); exit(1); }
- y1 = atoi(p);
-
- c = fgcol;
-
- if (addvector(&letter[numletters].vect,VT_FILL,x1,y1,0,0,&c, NULL)) {
- printf("Too many vectors on line %d of letters file.\n",line);
- exit(1);
- }
- } else if (!strcmp(p, "box")) {
- p = strtok(NULL, " ");
- if (p == NULL) { printf("Missing token on line #%d of letters file.\n",line); exit(1); }
- x1 = atoi(p);
- p = strtok(NULL, " ");
- if (p == NULL) { printf("Missing token on line #%d of letters file.\n",line); exit(1); }
- y1 = atoi(p);
- p = strtok(NULL, " ");
- if (p == NULL) { printf("Missing token on line #%d of letters file.\n",line); exit(1); }
- x2 = atoi(p);
- p = strtok(NULL, " ");
- if (p == NULL) { printf("Missing token on line #%d of letters file.\n",line); exit(1); }
- y2 = atoi(p);
-
- c = fgcol;
-
- if (addvector(&letter[numletters].vect,VT_BOX,x1,y1,x2,y2,&c, NULL)) {
- printf("Too many vectors on line %d of letters file.\n",line);
- exit(1);
- }
- } else if (!strcmp(p, "end")) {
-
- //printf("Adding letter %d: '%c' (vnum = %d).\n",numletters,letter[numletters].name,letter[numletters].vect.vnum);
- state = 0;
- numletters++;
- if (numletters >= MAXLETTERVECTS) {
- printf("FATAL: Too many letters found (max is %d).\n",MAXLETTERVECTS);
- exit(1);
- }
- } else {
- printf("Invalid command '%s' on line #%d of letters file.\n",p,line);
- exit(1);
- }
-
- }
+ found = -1;
+ for (i = 0; i < numhistory; i++) {
+ if (history[i] == mapid) {
+ found = i;
}
-
- fgets(buf, BUFLEN, f);
- buf[strlen(buf)-1] = '\0';
- line++;
}
- fclose(f);
+
+ return found;
}
-#endif
-
int isflow(int oid, int otype) {
switch (otype) {
case T_OBJECT:
@@ -6489,7 +7050,22 @@ void initvars(void) {
grid = TRUE;
gridsize = 15;
- /* set globals */
+ statusbarcolour.r = 255;
+ statusbarcolour.g = 255;
+ statusbarcolour.b = 255;
+
+ /* shortcuts */
+ shortcut[1] = 0;
+ shortcut[2] = 1;
+ shortcut[3] = 2;
+ shortcut[4] = 3;
+ shortcut[5] = 4;
+ shortcut[6] = 5;
+ shortcut[7] = 6;
+ shortcut[8] = 12;
+ shortcut[9] = 13;
+ shortcut[0] = 14;
+
initmap(0);
curmap = 0;
@@ -6525,33 +7101,53 @@ void initvars(void) {
}
-void raiseselected(void) {
- int i;
+void raiseselected(int amt) {
+ int i,n;
int temptype,tempid;
int target;
- /* find map[curmap].object */
- for (i = 0; i < map[curmap].numthings; i++) {
- if ((map[curmap].thing[i].id == map[curmap].selecteditem) && (map[curmap].thing[i].type == map[curmap].selecteditemtype)) {
- /* swap with one above */
- if (i == (map[curmap].numthings-1)) {
+
+ for (n = 0; n < amt; n++) {
+ /* find map[curmap].object */
+ for (i = 0; i < map[curmap].numthings; i++) {
+ if ((map[curmap].thing[i].id == map[curmap].selecteditem) && (map[curmap].thing[i].type == map[curmap].selecteditemtype)) {
+ /* swap with one above */
+ if (i == (map[curmap].numthings-1)) {
+ target = i;
+ break;
+ } else {
+ target = i+1;
+ }
+ tempid = map[curmap].thing[target].id;
+ temptype = map[curmap].thing[target].type;
+ map[curmap].thing[target].id = map[curmap].thing[i].id;
+ map[curmap].thing[target].type = map[curmap].thing[i].type;
+ map[curmap].thing[i].id = tempid;
+ map[curmap].thing[i].type = temptype;
break;
- } else {
- target = i+1;
}
- tempid = map[curmap].thing[target].id;
- temptype = map[curmap].thing[target].type;
- map[curmap].thing[target].id = map[curmap].thing[i].id;
- map[curmap].thing[target].type = map[curmap].thing[i].type;
- map[curmap].thing[i].id = tempid;
- map[curmap].thing[i].type = temptype;
- break;
}
+ if (i == (map[curmap].numthings-1)) break;
}
setmod(TRUE);
+ sprintf(statustext, "Selected item position raised by %d (now %d of %d).", n, target+1, map[curmap].numthings);
/* redraw map */
drawmap();
}
+void seterror (int errnum) {
+ infoflash = 0;
+ errorflash = errnum;
+
+ olderrorticks = SDL_GetTicks();
+}
+
+void setinfo (int infonum) {
+ infoflash = infonum;
+ errorflash = 0;
+
+ oldinfoticks = SDL_GetTicks();
+}
+
void setmod(int tf) {
modified = tf;
updatewm();
@@ -6585,7 +7181,7 @@ int savemap(void) {
((filename[eoff+2] == 'm') || (filename[eoff+2] == 'M')) &&
((filename[eoff+3] == 'p') || (filename[eoff+3] == 'P'))
) {
- exportmap = SDL_CreateRGBSurface(SDL_SWSURFACE,map[curmap].width, map[curmap].height,
+ exportmap = SDL_CreateRGBSurface(SDL_HWSURFACE,map[curmap].width, map[curmap].height,
buffer->format->BitsPerPixel, buffer->format->Rmask,
buffer->format->Gmask,buffer->format->Bmask,
buffer->format->Amask);
@@ -6598,11 +7194,14 @@ int savemap(void) {
area.h = map[curmap].height;
SDL_BlitSurface(screen,&area,exportmap, 0);
if (SDL_SaveBMP(exportmap, filename)) {
+ seterror(255);
sprintf(statustext,"ERROR: Could not export to BMP file '%s'.\n",filename);
drawstatusbar();
return TRUE;
}
+ setinfo(255);
sprintf(statustext,"Successfully exported map to Microsoft BMP file '%s'.\n",filename);
+ drawtoolbox();
drawstatusbar();
return FALSE;
}
@@ -6613,18 +7212,22 @@ int savemap(void) {
((filename[eoff+3] == 'g') || (filename[eoff+3] == 'G'))
) {
if (drawSVG(filename)) {
+ seterror(255);
sprintf(statustext,"ERROR: Could not export to SVG file '%s'.\n",filename);
drawstatusbar();
return TRUE;
}
state = S_NONE;
+ setinfo(255);
sprintf(statustext,"Successfully exported map to Scalable Vector Graphics file '%s'.\n",filename);
+ drawtoolbox();
drawstatusbar();
return FALSE;
}
}
if ((f = fopen(filename, "wb")) == NULL) {
+ seterror(255);
sprintf(statustext,"ERROR: Could not open '%s'.\n",filename);
drawstatusbar();
return TRUE;
@@ -6673,6 +7276,7 @@ int savemap(void) {
setmod(FALSE);
+ setinfo(255);
sprintf(statustext,"Successfully saved map to '%s'.\n",filename);
/* save filename */
@@ -6687,10 +7291,11 @@ void scrollobox(int amt) {
int fitx,fity,fit;
if (amt < 0) {
- if ((obox.pos + amt) >= 0 ) {
- obox.pos += amt;
- drawobox();
+ while ((obox.pos + amt) < 0 ) {
+ amt++;
}
+ obox.pos += amt;
+ drawobox();
} else if (amt > 0) {
/* figure out how many objects we can fit in the box */
fitx = (obox.width / obox.gridsize);
@@ -6698,10 +7303,12 @@ void scrollobox(int amt) {
fit = fitx * fity;
/* check if incrementing position is okay or not */
- if (((obox.pos+amt)*3 + fit) <= (numobjtypes+2)) {
- obox.pos+= amt;
- drawobox();
+ //if (((obox.pos+amt)*3 + fit) <= (numobjtypes+2)) {
+ while (((obox.pos+amt)*3 + fit) > (numobjtypes+2)) {
+ amt--;
}
+ obox.pos+= amt;
+ drawobox();
}
}
@@ -6731,6 +7338,9 @@ int showfiledialog(void) {
case S_MAPNAMING:
strcpy(t,"Enter new map name:");
break;
+ case S_SEARCH:
+ strcpy(t,"Enter search string:");
+ break;
default:
strcpy(t,"Enter filename:");
break;
@@ -6767,7 +7377,7 @@ int showfiledialog(void) {
sarea.y = starty;
sarea.w = tw + CURSORWIDTH; // include space for cursor
sarea.h = DEFTEXTH*2;
- bg = SDL_CreateRGBSurface(SDL_SWSURFACE,sarea.w, sarea.h,
+ bg = SDL_CreateRGBSurface(SDL_HWSURFACE,sarea.w, sarea.h,
buffer->format->BitsPerPixel, buffer->format->Rmask,
buffer->format->Gmask,buffer->format->Bmask,
buffer->format->Amask);
@@ -6902,7 +7512,7 @@ int startlinkpointmove(int x, int y) {
linex2 = map[curmap].olink[map[curmap].curlink].point[map[curmap].curlinkpoint].x + (LINESELHANDLESIZE / 2)+2;
liney2 = map[curmap].olink[map[curmap].curlink].point[map[curmap].curlinkpoint].y + (LINESELHANDLESIZE / 2)+2;
- bg = SDL_CreateRGBSurface(SDL_SWSURFACE, LINESELHANDLESIZE, LINESELHANDLESIZE,
+ bg = SDL_CreateRGBSurface(SDL_HWSURFACE, LINESELHANDLESIZE, LINESELHANDLESIZE,
screen->format->BitsPerPixel, screen->format->Rmask,
screen->format->Gmask,screen->format->Bmask,
screen->format->Amask);
@@ -6916,7 +7526,7 @@ int startlinkpointmove(int x, int y) {
area.h = LINESELHANDLESIZE+4;
SDL_BlitSurface(screen, &area, bg,0);
- sprintf(statustext,"Starting link point move for link #%d poinrt #%d...\n", map[curmap].curlink,map[curmap].curlinkpoint);
+ sprintf(statustext,"Moving link point #%d of link #%d... (%d,%d)\n", map[curmap].curlinkpoint,map[curmap].curlink, x, y);
drawstatusbar();
return 0;
@@ -7001,7 +7611,7 @@ int startobjmove (int x, int y) {
starty = y;
changestate(S_OBJMOVING);
/* copy background */
- bg = SDL_CreateRGBSurface(SDL_SWSURFACE,map[curmap].obj[map[curmap].curobj].w,map[curmap].obj[map[curmap].curobj].h,
+ bg = SDL_CreateRGBSurface(SDL_HWSURFACE,map[curmap].obj[map[curmap].curobj].w,map[curmap].obj[map[curmap].curobj].h,
screen->format->BitsPerPixel, screen->format->Rmask,
screen->format->Gmask,screen->format->Bmask,
screen->format->Amask);
@@ -7014,6 +7624,19 @@ int startobjmove (int x, int y) {
bgy = area.y;
bgw = area.w;
bgh = area.h;
+
+ /* take a copy of the object itself */
+ shadow = SDL_CreateRGBSurface(SDL_HWSURFACE,map[curmap].obj[map[curmap].curobj].w+3, map[curmap].obj[map[curmap].curobj].h+3,
+ screen->format->BitsPerPixel, screen->format->Rmask,
+ screen->format->Gmask,screen->format->Bmask,
+ screen->format->Amask);
+ drawobject(shadow, &map[curmap].obj[map[curmap].curobj], FALSE);
+ /* make it transparent */
+ SDL_SetAlpha(shadow, SDL_SRCALPHA, 128);
+
+ sprintf(statustext,"Moving object #%d... (%d,%d)\n", map[curmap].curobj, x, y);
+ drawstatusbar();
+
return 0;
}
@@ -7025,7 +7648,7 @@ int startresize (int x, int y) {
changestate(S_RESIZING);
/* copy background */
- bg = SDL_CreateRGBSurface(SDL_SWSURFACE,MAXOBJWIDTH+2,MAXOBJHEIGHT+2,
+ bg = SDL_CreateRGBSurface(SDL_HWSURFACE,MAXOBJWIDTH+2,MAXOBJHEIGHT+2,
screen->format->BitsPerPixel, screen->format->Rmask,
screen->format->Gmask,screen->format->Bmask,
screen->format->Amask);
@@ -7038,34 +7661,53 @@ int startresize (int x, int y) {
bgy = area.y;
bgw = area.w;
bgh = area.h;
+
+
+ sprintf(statustext, "Resizing object #%d... (%dx%d)", map[curmap].curobj,
+ map[curmap].obj[map[curmap].curobj].w,
+ map[curmap].obj[map[curmap].curobj].h);
+ drawstatusbar();
+
return 0;
}
int startresizetext(int x, int y) {
SDL_Rect area;
int txoff,tyoff;
+ int tw,th;
+ int ct;
+
+ ct = map[curmap].curtext;
- if (map[curmap].textob[map[curmap].curtext].anchor == -1) {
+ if (map[curmap].textob[ct].anchor == -1) {
txoff = 0;
tyoff = 0;
} else {
- txoff = map[curmap].obj[map[curmap].textob[map[curmap].curtext].anchor].x;
- tyoff = map[curmap].obj[map[curmap].textob[map[curmap].curtext].anchor].y;
+ txoff = map[curmap].obj[map[curmap].textob[ct].anchor].x;
+ tyoff = map[curmap].obj[map[curmap].textob[ct].anchor].y;
}
startx = x;
starty = y;
changestate(S_TEXTRESIZING);
+ /* get size */
+ TTF_SizeText(font[map[curmap].textob[ct].h],
+ map[curmap].textob[ct].text,
+ &tw, &th);
+
+ sprintf(statustext, "Resizing text item #%d... (%dx%d)", ct,tw,th);
+ drawstatusbar();
+
/* copy background */
- bg = SDL_CreateRGBSurface(SDL_SWSURFACE,map[curmap].width,map[curmap].height,
+ bg = SDL_CreateRGBSurface(SDL_HWSURFACE,map[curmap].width,map[curmap].height,
screen->format->BitsPerPixel, screen->format->Rmask,
screen->format->Gmask,screen->format->Bmask,
screen->format->Amask);
- area.x = map[curmap].textob[map[curmap].curtext].x + txoff;
- area.y = map[curmap].textob[map[curmap].curtext].y + tyoff;
- area.w = map[curmap].textob[map[curmap].curtext].w+2;
- area.h = map[curmap].textob[map[curmap].curtext].h+2;
+ area.x = map[curmap].textob[ct].x + txoff;
+ area.y = map[curmap].textob[ct].y + tyoff;
+ area.w = map[curmap].textob[ct].x + txoff + tw;
+ area.h = map[curmap].textob[ct].y + tyoff + th;
SDL_BlitSurface(screen,&area,bg,0);
bgx = area.x;
bgy = area.y;
@@ -7095,6 +7737,7 @@ void endSVG(void) {
int starttextmove (int x, int y) {
SDL_Rect area;
int txoff,tyoff;
+ int th;
if (map[curmap].textob[map[curmap].curtext].anchor == -1) {
txoff = 0;
@@ -7107,23 +7750,42 @@ int starttextmove (int x, int y) {
xoff = map[curmap].textob[map[curmap].curtext].x - x + txoff;
yoff = map[curmap].textob[map[curmap].curtext].y - y + tyoff;
+ th = TTF_FontHeight(font[map[curmap].textob[map[curmap].curtext].h]);
+
startx = x ;
starty = y ;
changestate(S_TEXTMOVING);
/* copy background */
- bg = SDL_CreateRGBSurface(SDL_SWSURFACE,map[curmap].textob[map[curmap].curtext].w,map[curmap].textob[map[curmap].curtext].h,
+ bg = SDL_CreateRGBSurface(SDL_HWSURFACE,map[curmap].textob[map[curmap].curtext].w,th+5,
screen->format->BitsPerPixel, screen->format->Rmask,
screen->format->Gmask,screen->format->Bmask,
screen->format->Amask);
area.x = map[curmap].textob[map[curmap].curtext].x + txoff;
area.y = map[curmap].textob[map[curmap].curtext].y + tyoff;
area.w = map[curmap].textob[map[curmap].curtext].w;
- area.h = map[curmap].textob[map[curmap].curtext].h;
+ area.h = th+5;
SDL_BlitSurface(screen,&area,bg,0);
bgx = area.x;
bgy = area.y;
bgw = area.w;
bgh = area.h;
+
+ /* take a copy of the text itself */
+ shadow = SDL_CreateRGBSurface(SDL_SWSURFACE,map[curmap].textob[map[curmap].curtext].w+3, th + 3,
+ screen->format->BitsPerPixel, screen->format->Rmask,
+ screen->format->Gmask,screen->format->Bmask,
+ screen->format->Amask);
+
+ SDL_FillRect(shadow, NULL,
+ SDL_MapRGB(shadow->format,255,255,255)
+ );
+
+ drawtextat(shadow, 0, 0, map[curmap].textob[map[curmap].curtext].text,
+ map[curmap].textob[map[curmap].curtext].h,
+ map[curmap].textob[map[curmap].curtext].c );
+ SDL_SetColorKey(shadow, SDL_SRCCOLORKEY|SDL_RLEACCEL, SDL_MapRGB(shadow->format,255,255,255));
+
+ SDL_SetAlpha(shadow, SDL_SRCALPHA, 128);
return 0;
}
@@ -7170,9 +7832,11 @@ void toggleflow(int oid, int otype) {
void togglegrid(void) {
if (grid) {
grid = FALSE;
+ setinfo(255);
strcpy(statustext, "Snap-To-Grid mode disabled.");
} else {
grid = TRUE;
+ setinfo(255);
strcpy(statustext, "Snap-To-Grid mode enabled.");
}
}
@@ -7187,14 +7851,14 @@ int thingat(int x, int y) {
(x <= (map[curmap].obj[map[curmap].thing[i].id].x + map[curmap].obj[map[curmap].thing[i].id].w)) &&
(y >= map[curmap].obj[map[curmap].thing[i].id].y ) &&
(y <= (map[curmap].obj[map[curmap].thing[i].id].y + map[curmap].obj[map[curmap].thing[i].id].h)) ) {
- if (!isflow(i, T_OBJECT) || (showflows == TRUE)) {
+ if (!isflow(map[curmap].thing[i].id, T_OBJECT) || (showflows == TRUE)) {
return i;
}
}
break;
case T_LINK:
if (isonlink(map[curmap].thing[i].id, x, y)) {
- if (!isflow(i, T_LINK) || (showflows == TRUE)) {
+ if (!isflow(map[curmap].thing[i].id, T_LINK) || (showflows == TRUE)) {
return i;
}
}
@@ -7204,14 +7868,14 @@ int thingat(int x, int y) {
if (anchor == -1) {
if ( (x >= map[curmap].textob[map[curmap].thing[i].id].x ) && (x <= (map[curmap].textob[map[curmap].thing[i].id].x + map[curmap].textob[map[curmap].thing[i].id].w)) &&
(y >= map[curmap].textob[map[curmap].thing[i].id].y ) && (y <= (map[curmap].textob[map[curmap].thing[i].id].y + map[curmap].textob[map[curmap].thing[i].id].h)) ) {
- if (!isflow(i, T_TEXT) || (showflows == TRUE)) {
+ if (!isflow(map[curmap].thing[i].id, T_TEXT) || (showflows == TRUE)) {
return i;
}
}
} else {
if ( (x >= map[curmap].textob[map[curmap].thing[i].id].x + map[curmap].obj[anchor].x ) && (x <= (map[curmap].textob[map[curmap].thing[i].id].x + map[curmap].obj[anchor].x + map[curmap].textob[map[curmap].thing[i].id].w)) &&
(y >= map[curmap].textob[map[curmap].thing[i].id].y + map[curmap].obj[anchor].y ) && (y <= (map[curmap].textob[map[curmap].thing[i].id].y + map[curmap].obj[anchor].y + map[curmap].textob[map[curmap].thing[i].id].h)) ) {
- if (!isflow(i, T_TEXT) || (showflows == TRUE)) {
+ if (!isflow(map[curmap].thing[i].id, T_TEXT) || (showflows == TRUE)) {
return i;
}
}
@@ -7248,7 +7912,7 @@ int updatefilename(void) {
sarea.y = starty;
sarea.w = ((strlen(text)+1) * (DEFTEXTW*2)) +2; // include space for cursor
sarea.h = DEFTEXTH*2;
- bg = SDL_CreateRGBSurface(SDL_SWSURFACE,sarea.w, sarea.h,
+ bg = SDL_CreateRGBSurface(SDL_HWSURFACE,sarea.w, sarea.h,
screen->format->BitsPerPixel, screen->format->Rmask,
screen->format->Gmask,screen->format->Bmask,
screen->format->Amask);
@@ -7327,9 +7991,8 @@ int updatelinkshadow(int x, int y) {
}
int updatelinkpointshadow(int x, int y) {
- int linex1,liney1,linex2,liney2;
+ int linex1,liney1;
SDL_Rect area;
- int ty;
/* paste old bg */
area.x = bgx;
@@ -7349,10 +8012,8 @@ int updatelinkpointshadow(int x, int y) {
/* copy background */
linex1 = x - (LINESELHANDLESIZE / 2);
liney1 = y - (LINESELHANDLESIZE / 2);
- linex2 = x + (LINESELHANDLESIZE / 2)+4;
- liney2 = y + (LINESELHANDLESIZE / 2)+4;
- bg = SDL_CreateRGBSurface(SDL_SWSURFACE, LINESELHANDLESIZE, LINESELHANDLESIZE,
+ bg = SDL_CreateRGBSurface(SDL_HWSURFACE, LINESELHANDLESIZE, LINESELHANDLESIZE,
screen->format->BitsPerPixel, screen->format->Rmask,
screen->format->Gmask,screen->format->Bmask,
screen->format->Amask);
@@ -7369,11 +8030,12 @@ int updatelinkpointshadow(int x, int y) {
SDL_BlitSurface(screen, &area, bg,0);
/* draw link point */
- for (ty = liney1; ty < (liney1+LINESELHANDLESIZE-1); ty++) {
- drawline(screen, linex1, ty, linex1+LINESELHANDLESIZE-1, ty, black,1);
- }
- //SDL_UpdateRect(screen, linex1, liney1, linex2, liney2);
- SDL_Flip(screen);
+ drawbox(screen, linex1, liney1,linex1+LINESELHANDLESIZE-1,liney1+LINESELHANDLESIZE-1,black,&black);
+ SDL_UpdateRect(screen, linex1, liney1, LINESELHANDLESIZE-1, LINESELHANDLESIZE-1);
+ //SDL_Flip(screen);
+
+ sprintf(statustext,"Moving link point #%d of link #%d... (%d,%d)\n", map[curmap].curlinkpoint,map[curmap].curlink, x, y);
+ drawstatusbar();
return FALSE;
}
@@ -7418,12 +8080,17 @@ int updatemoveshadow(int x, int y) {
/* 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);
- drawline(screen,x,y,x,y+map[curmap].obj[map[curmap].curobj].h-1, map[curmap].boxcol,1);
- drawline(screen,x,y+map[curmap].obj[map[curmap].curobj].h-1,x+map[curmap].obj[map[curmap].curobj].w-1,y+map[curmap].obj[map[curmap].curobj].h-1, map[curmap].boxcol,1);
- drawline(screen,x+map[curmap].obj[map[curmap].curobj].w-1,y,x+map[curmap].obj[map[curmap].curobj].w-1,y+map[curmap].obj[map[curmap].curobj].h-1, map[curmap].boxcol,1);
+ drawbox(screen, x, y,
+ x+map[curmap].obj[map[curmap].curobj].w-1,
+ y+map[curmap].obj[map[curmap].curobj].h-1,
+ map[curmap].boxcol, NULL );
+
+ SDL_BlitSurface(shadow, 0, screen, &area);
}
+
SDL_UpdateRect(screen, area.x, area.y, area.w, area.h);
+ sprintf(statustext,"Moving object #%d... (%d,%d)\n", map[curmap].curobj, x, y);
+ drawstatusbar();
return 0;
}
@@ -7487,17 +8154,23 @@ int updateresizeshadow(int x, int y) {
bgy = area.y;
bgw = area.w;
bgh = area.h;
+
/* draw box */
- drawline(screen,map[curmap].obj[map[curmap].curobj].x, map[curmap].obj[map[curmap].curobj].y,
- map[curmap].obj[map[curmap].curobj].x+map[curmap].obj[map[curmap].curobj].w+xdiff, map[curmap].obj[map[curmap].curobj].y , map[curmap].boxcol,1);
- drawline(screen,map[curmap].obj[map[curmap].curobj].x, map[curmap].obj[map[curmap].curobj].y,
- map[curmap].obj[map[curmap].curobj].x, map[curmap].obj[map[curmap].curobj].y+map[curmap].obj[map[curmap].curobj].h+ydiff , map[curmap].boxcol,1);
- drawline(screen,map[curmap].obj[map[curmap].curobj].x+map[curmap].obj[map[curmap].curobj].w+xdiff, map[curmap].obj[map[curmap].curobj].y,
- map[curmap].obj[map[curmap].curobj].x+map[curmap].obj[map[curmap].curobj].w+xdiff, map[curmap].obj[map[curmap].curobj].y+map[curmap].obj[map[curmap].curobj].h+ydiff , map[curmap].boxcol,1);
- drawline(screen,map[curmap].obj[map[curmap].curobj].x, map[curmap].obj[map[curmap].curobj].y+map[curmap].obj[map[curmap].curobj].h+ydiff,
- map[curmap].obj[map[curmap].curobj].x+map[curmap].obj[map[curmap].curobj].w+xdiff, map[curmap].obj[map[curmap].curobj].y+map[curmap].obj[map[curmap].curobj].h+ydiff , map[curmap].boxcol,1);
+
+ drawbox(screen, map[curmap].obj[map[curmap].curobj].x,
+ map[curmap].obj[map[curmap].curobj].y,
+ map[curmap].obj[map[curmap].curobj].x+map[curmap].obj[map[curmap].curobj].w + xdiff,
+ map[curmap].obj[map[curmap].curobj].y+map[curmap].obj[map[curmap].curobj].h + ydiff,
+ map[curmap].boxcol, NULL);
+
SDL_UpdateRect(screen, area.x, area.y, area.w, area.h);
+
+ sprintf(statustext, "Resizing object #%d... (%dx%d)", map[curmap].curobj,
+ map[curmap].obj[map[curmap].curobj].w + xdiff,
+ map[curmap].obj[map[curmap].curobj].h + ydiff);
+ drawstatusbar();
+
return 0;
}
@@ -7510,28 +8183,33 @@ int updateresizetextshadow(int x, int y) {
int textsize;
char *tp;
int tw,th;
+ int ct;
- if (map[curmap].textob[map[curmap].curtext].anchor == -1) {
+ int x1,y1,x2,y2;
+
+ ct = map[curmap].curtext;
+
+ if (map[curmap].textob[ct].anchor == -1) {
txoff = 0;
tyoff = 0;
} else {
- txoff = map[curmap].obj[map[curmap].textob[map[curmap].curtext].anchor].x;
- tyoff = map[curmap].obj[map[curmap].textob[map[curmap].curtext].anchor].y;
+ txoff = map[curmap].obj[map[curmap].textob[ct].anchor].x;
+ tyoff = map[curmap].obj[map[curmap].textob[ct].anchor].y;
}
- //
ydiff = y - starty;
- //if ((map[curmap].textob[map[curmap].curtext].w + xdiff) > strlen(map[curmap].textob[map[curmap].curtext].text) * MAXLETTERWIDTH) xdiff = (strlen(map[curmap].textob[map[curmap].curtext].text) * MAXLETTERWIDTH)-map[curmap].textob[map[curmap].curtext].w;
- if ((map[curmap].textob[map[curmap].curtext].h + ydiff) >= MAXLETTERHEIGHT) ydiff = MAXLETTERHEIGHT - map[curmap].textob[map[curmap].curtext].h - 1;
- //if ((map[curmap].textob[map[curmap].curtext].w + xdiff) < strlen(map[curmap].textob[map[curmap].curtext].text) * MINLETTERWIDTH)
- // xdiff = (strlen(map[curmap].textob[map[curmap].curtext].text) * MINLETTERWIDTH) - map[curmap].textob[map[curmap].curtext].w ;
- if ((map[curmap].textob[map[curmap].curtext].h + ydiff) < MINLETTERHEIGHT) ydiff = MINLETTERHEIGHT - map[curmap].textob[map[curmap].curtext].h ;
+ /* get text height */
+ th = TTF_FontHeight(font[map[curmap].textob[map[curmap].curtext].h]);
+
+ if ((map[curmap].textob[ct].h + ydiff) >= MAXLETTERHEIGHT) ydiff = MAXLETTERHEIGHT - map[curmap].textob[ct].h - 1;
+ if ((map[curmap].textob[ct].h + ydiff) < MINLETTERHEIGHT) ydiff = MINLETTERHEIGHT - map[curmap].textob[ct].h;
/* calculate x based on text height and length */
textsize = map[curmap].textob[map[curmap].curtext].h + ydiff;
+
tp = map[curmap].textob[map[curmap].curtext].text;
TTF_SizeText(font[textsize], tp, &tw, &th);
x = startx + tw;
@@ -7539,7 +8217,6 @@ int updateresizetextshadow(int x, int y) {
/* replace old bg */
-
area.x = bgx;
area.y = bgy;
area.w = bgw;
@@ -7553,34 +8230,36 @@ int updateresizetextshadow(int x, int y) {
SDL_BlitSurface(bg, &sarea, screen, &area);
SDL_UpdateRect(screen, area.x, area.y, area.w, area.h);
/* copy current bg */
- area.x = map[curmap].textob[map[curmap].curtext].x + txoff;
- area.y = map[curmap].textob[map[curmap].curtext].y + tyoff;
- area.w = map[curmap].textob[map[curmap].curtext].w + xdiff + 2;
- area.h = map[curmap].textob[map[curmap].curtext].h + ydiff + 2;
+ area.x = map[curmap].textob[ct].x + txoff;
+ area.y = map[curmap].textob[ct].y + tyoff;
+ area.w = tw+2;
+ area.h = th+4;
if (area.w < strlen(map[curmap].textob[map[curmap].curtext].text) * MINLETTERWIDTH) area.w = strlen(map[curmap].textob[map[curmap].curtext].text) * MINLETTERWIDTH;
if (area.h < MINLETTERHEIGHT) area.h = MINLETTERHEIGHT;
if (area.w > strlen(map[curmap].textob[map[curmap].curtext].text) * MAXLETTERWIDTH ) area.w = strlen(map[curmap].textob[map[curmap].curtext].text) * MAXLETTERWIDTH;
- if (area.h > MAXLETTERHEIGHT) area.h = MAXLETTERHEIGHT;
SDL_BlitSurface(screen,&area,bg,0);
bgx = area.x;
bgy = area.y;
bgw = area.w;
bgh = area.h;
- /* draw box */
- drawline(screen,map[curmap].textob[map[curmap].curtext].x+txoff, map[curmap].textob[map[curmap].curtext].y+tyoff,
- map[curmap].textob[map[curmap].curtext].x+txoff+map[curmap].textob[map[curmap].curtext].w+xdiff, map[curmap].textob[map[curmap].curtext].y+tyoff , map[curmap].boxcol,1);
- drawline(screen,map[curmap].textob[map[curmap].curtext].x+txoff, map[curmap].textob[map[curmap].curtext].y+tyoff,
- map[curmap].textob[map[curmap].curtext].x+txoff, map[curmap].textob[map[curmap].curtext].y+tyoff+map[curmap].textob[map[curmap].curtext].h+ydiff , map[curmap].boxcol,1);
- drawline(screen,map[curmap].textob[map[curmap].curtext].x+txoff+map[curmap].textob[map[curmap].curtext].w+xdiff, map[curmap].textob[map[curmap].curtext].y+tyoff,
- map[curmap].textob[map[curmap].curtext].x+txoff+map[curmap].textob[map[curmap].curtext].w+xdiff, map[curmap].textob[map[curmap].curtext].y+tyoff+map[curmap].textob[map[curmap].curtext].h+ydiff , map[curmap].boxcol,1);
- drawline(screen,map[curmap].textob[map[curmap].curtext].x+txoff, map[curmap].textob[map[curmap].curtext].y+tyoff+map[curmap].textob[map[curmap].curtext].h+ydiff,
- map[curmap].textob[map[curmap].curtext].x+txoff+map[curmap].textob[map[curmap].curtext].w+xdiff, map[curmap].textob[map[curmap].curtext].y+tyoff+map[curmap].textob[map[curmap].curtext].h+ydiff , map[curmap].boxcol,1);
- SDL_UpdateRect(screen, area.x, area.y, area.w, area.h);
+ /* draw box */
+
+ x1 = map[curmap].textob[ct].x + txoff;
+ y1 = map[curmap].textob[ct].y + tyoff;
+ x2 = map[curmap].textob[ct].x + txoff + tw;
+ y2 = map[curmap].textob[ct].y + tyoff + th;
+
+ drawbox(screen, x1, y1, x2, y2, map[curmap].boxcol, NULL);
+
+ SDL_UpdateRect(screen, x1, y1, x2-x1+1, y2-y1+1);
+
+ sprintf(statustext, "Resizing text item #%d... (%dx%d)", ct,tw,th);
+ drawstatusbar();
return 0;
}
@@ -7591,7 +8270,7 @@ int updatetextcursor(void) {
SDL_Color ccol = blue;
int tw,th;
- if ((state == S_SAVING) || (state == S_LOADING) || (state == S_MAPNAMING)) {
+ if ((state == S_SAVING) || (state == S_LOADING) || (state == S_MAPNAMING) || (state == S_SEARCH)) {
showfiledialog();
return 0;
}
@@ -7617,7 +8296,7 @@ int updatetextcursor(void) {
sarea.h = th;
//sarea.h = DEFTEXTH;
//sarea.w = ((strlen(text)+1) * (DEFTEXTW)) +2; // include space for cursor
- bg = SDL_CreateRGBSurface(SDL_SWSURFACE,sarea.w, sarea.h,
+ bg = SDL_CreateRGBSurface(SDL_HWSURFACE,sarea.w, sarea.h,
screen->format->BitsPerPixel, screen->format->Rmask,
screen->format->Gmask,screen->format->Bmask,
screen->format->Amask);
@@ -7643,12 +8322,14 @@ int endlink(int x, int y) {
int endxoff,endyoff;
int i;
Uint8 style, arrow, thickness;
+ int insertpoint;
/* replace old bg */
pasteline(screen,linebg);
/* check if we've exceeded the max number of links */
if ((map[curmap].numlinks+1) >= MAXLINKS) {
+ seterror(255);
sprintf(statustext,"ERROR: Maximum link count (%d) exceeded.", MAXLINKS);
return TRUE;
}
@@ -7692,18 +8373,34 @@ int endlink(int x, int y) {
map[curmap].olink[map[curmap].numlinks].style = (arrow << 16) | (style << 8) | (thickness);
/* add to 'thing' list */
- /* links start at the bottom of the thing list */
+ /* links start below their endpoints but above other things */
/* shuffle all things up */
- for (i = (map[curmap].numthings-1); i >= 0 ; i--) {
+
+ /* find lowest of endpoint ids */
+ insertpoint = 9999; /* default to 0 */
+ for (i = 0; i < (map[curmap].numthings-1); i++) {
+ if (map[curmap].thing[i].type == T_OBJECT) {
+ if ((map[curmap].thing[i].id == startobj) ||
+ (map[curmap].thing[i].id == endobj)) {
+ insertpoint = i;
+ break;
+ }
+ }
+ }
+ if (insertpoint == 9999) {
+ insertpoint = 0;
+ }
+
+
+ for (i = (map[curmap].numthings-1); i >= insertpoint ; i--) {
map[curmap].thing[i+1].type = map[curmap].thing[i].type;
map[curmap].thing[i+1].id = map[curmap].thing[i].id;
}
- map[curmap].thing[0].type = T_LINK;
- map[curmap].thing[0].id = map[curmap].numlinks;
-
+ map[curmap].thing[insertpoint].type = T_LINK;
+ map[curmap].thing[insertpoint].id = map[curmap].numlinks;
setmod(TRUE);
- sprintf(statustext,"Link #%d created (from obj #%d to obj #%d).\n", map[curmap].numlinks, startobj, endobj);
+ sprintf(statustext,"Link #%d created (from object #%d to object #%d).\n", map[curmap].numlinks, startobj, endobj);
map[curmap].numlinks++;
map[curmap].numthings++;
drawstatusbar();
@@ -7763,7 +8460,7 @@ int endlinkpointmove(int x, int y) {
map[curmap].olink[map[curmap].curlink].point[map[curmap].curlinkpoint].y = y;
setmod(TRUE);
- sprintf(statustext,"Link #%d point #%d moved to (%d,%d).\n",map[curmap].curlink, map[curmap].curlinkpoint, map[curmap].olink[map[curmap].curlink].point[map[curmap].curlinkpoint].x,map[curmap].olink[map[curmap].curlink].point[map[curmap].curlinkpoint].y);
+ sprintf(statustext,"Point #%d of link #%d moved to (%d,%d).\n",map[curmap].curlinkpoint, map[curmap].curlink, map[curmap].olink[map[curmap].curlink].point[map[curmap].curlinkpoint].x,map[curmap].olink[map[curmap].curlink].point[map[curmap].curlinkpoint].y);
drawstatusbar();
return 0;
@@ -7834,6 +8531,7 @@ void drillto(int mapnum) {
changemap(nummaps);
nummaps++;
+ setinfo(255);
sprintf(statustext,"Drilled down (new map created).");
startx = 1;
@@ -7844,6 +8542,7 @@ void drillto(int mapnum) {
drawmap();
} else {
+ seterror(255);
sprintf(statustext, "ERROR: Maximum number of maps reached.");
drawstatusbar();
}
@@ -7854,21 +8553,38 @@ void drillto(int mapnum) {
mapbox.offset++;
drawmapbox();
} else {
- /* push current map */
- history[numhistory] = curmap;
- numhistory++;
+ int found;
+
+ /* is map already in history? */
+ found = isinhistory(mapnum);
+
+ if (found >= 0) {
+ /* jump back up to that point on the "stack" */
+ numhistory = found;
+
+ } else {
+ /* push current map */
+ history[numhistory] = curmap;
+ numhistory++;
+ }
changemap(mapnum);
- sprintf(statustext,"Drilled down into map #%d (%s).",curmap,map[curmap].name);
+ if (found >= 0) {
+ sprintf(statustext,"Drilled back to map #%d (%s) - current depth is %d.",curmap,map[curmap].name, numhistory);
+ } else {
+ sprintf(statustext,"Drilled down into map #%d (%s) - current depth is %d.",curmap,map[curmap].name, numhistory);
+ }
drawmap();
}
}
int endobjmove(int x, int y) {
- SDL_FreeSurface(bg);
int newx, newy;
+ SDL_FreeSurface(bg);
+ SDL_FreeSurface(shadow);
+
/* check position */
if ((map[curmap].obj[map[curmap].curobj].x + x - startx) >= (map[curmap].width - map[curmap].obj[map[curmap].curobj].w)) {
return -1;
@@ -7898,24 +8614,6 @@ int endobjmove(int x, int y) {
map[curmap].obj[map[curmap].curobj].x = newx;
map[curmap].obj[map[curmap].curobj].y = newy;
- /* adjust links for grid */
- if (grid) {
- int thisobj = map[curmap].curobj;
- int i;
-
- for (i = 0; i < map[curmap].numlinks; i++) {
- if (map[curmap].olink[i].srcobj == thisobj) {
- map[curmap].olink[i].srcxoff = map[curmap].olink[i].srcxoff - ((map[curmap].obj[thisobj].x + map[curmap].olink[i].srcxoff) % gridsize);
- map[curmap].olink[i].srcyoff = map[curmap].olink[i].srcyoff - ((map[curmap].obj[thisobj].y + map[curmap].olink[i].srcyoff) % gridsize);
-
- }
- if (map[curmap].olink[i].dstobj == thisobj) {
- map[curmap].olink[i].dstxoff = map[curmap].olink[i].dstxoff - ((map[curmap].obj[thisobj].x + map[curmap].olink[i].dstxoff) % gridsize);
- map[curmap].olink[i].dstyoff = map[curmap].olink[i].dstyoff - ((map[curmap].obj[thisobj].y + map[curmap].olink[i].dstyoff) % gridsize);
- }
- }
- }
-
return 0;
}
@@ -7957,65 +8655,38 @@ int endresize(int x, int y) {
if (grid) {
int m;
- m = map[curmap].obj[map[curmap].curobj].x + map[curmap].obj[map[curmap].curobj].w + neww;
+ m = map[curmap].obj[map[curmap].curobj].x + neww;
neww -= (m % gridsize);
- m = map[curmap].obj[map[curmap].curobj].y + map[curmap].obj[map[curmap].curobj].h + newh;
+ m = map[curmap].obj[map[curmap].curobj].y + newh;
newh -= (m % gridsize);
}
map[curmap].obj[map[curmap].curobj].w = neww;
map[curmap].obj[map[curmap].curobj].h = newh;
+ sprintf(statustext, "Object #%d resized to %dx%d.",map[curmap].curobj,map[curmap].obj[map[curmap].curobj].w, map[curmap].obj[map[curmap].curobj].h);
+
/* update default map[curmap].object size */
objtype[map[curmap].obj[map[curmap].curobj].type].defw = neww;
objtype[map[curmap].obj[map[curmap].curobj].type].defh = newh;
/* adjust links for grid */
- if (grid) {
- int thisobj = map[curmap].curobj;
-
- /* adjust for grid */
- if (grid) {
- xoff = xoff - ((map[curmap].obj[startobj].x + xoff) % gridsize);
- yoff = yoff - ((map[curmap].obj[startobj].y + yoff) % gridsize);
+ /* scale all link endpoints in this map[curmap].object */
+ xscale = (float)neww / (float)origw;
+ yscale = (float)newh / (float)origh;
+ for (i = 0; i < map[curmap].numlinks; i++) {
+ if (map[curmap].olink[i].srcobj == map[curmap].curobj) {
+ map[curmap].olink[i].srcxoff = map[curmap].olink[i].srcxoff * xscale;
+ map[curmap].olink[i].srcyoff = map[curmap].olink[i].srcyoff * yscale;
}
-
- for (i = 0; i < map[curmap].numlinks; i++) {
- if (map[curmap].olink[i].srcobj == thisobj) {
- map[curmap].olink[i].srcxoff = (map[curmap].obj[thisobj].w / 2);
- map[curmap].olink[i].srcyoff = (map[curmap].obj[thisobj].h / 2);
-
- map[curmap].olink[i].srcxoff = map[curmap].olink[i].srcxoff - ((map[curmap].obj[thisobj].x + map[curmap].olink[i].srcxoff) % gridsize);
- map[curmap].olink[i].srcyoff = map[curmap].olink[i].srcyoff - ((map[curmap].obj[thisobj].y + map[curmap].olink[i].srcyoff) % gridsize);
-
- }
- if (map[curmap].olink[i].dstobj == thisobj) {
- map[curmap].olink[i].dstxoff = (map[curmap].obj[thisobj].w / 2);
- map[curmap].olink[i].dstyoff = (map[curmap].obj[thisobj].h / 2);
- }
- }
-
-
-
- } else {
- /* scale all link endpoints in this map[curmap].object */
- xscale = (float)neww / (float)origw;
- yscale = (float)newh / (float)origh;
- for (i = 0; i < map[curmap].numlinks; i++) {
- if (map[curmap].olink[i].srcobj == map[curmap].curobj) {
- map[curmap].olink[i].srcxoff = map[curmap].olink[i].srcxoff * xscale;
- map[curmap].olink[i].srcyoff = map[curmap].olink[i].srcyoff * yscale;
- }
- if (map[curmap].olink[i].dstobj == map[curmap].curobj) {
- map[curmap].olink[i].dstxoff = map[curmap].olink[i].dstxoff * xscale;
- map[curmap].olink[i].dstyoff = map[curmap].olink[i].dstyoff * yscale;
- }
+ if (map[curmap].olink[i].dstobj == map[curmap].curobj) {
+ map[curmap].olink[i].dstxoff = map[curmap].olink[i].dstxoff * xscale;
+ map[curmap].olink[i].dstyoff = map[curmap].olink[i].dstyoff * yscale;
}
}
-
/* scale x,y of any text anchored to this map[curmap].object */
for (i = 0; i < map[curmap].numtext; i++) {
if (map[curmap].textob[i].anchor == map[curmap].curobj) {
@@ -8073,12 +8744,14 @@ int endtextresize(int x, int y) {
*/
setmod(TRUE);
+ sprintf(statustext, "Text item #%d resized to %d points (%dx%d).",map[curmap].curtext,map[curmap].textob[map[curmap].curtext].h, tw, th);
drawmap();
return 0;
}
int updatetextshadow(int x, int y) {
+ int th;
SDL_Rect area;
@@ -8102,11 +8775,13 @@ int updatetextshadow(int x, int y) {
y = y - (y % gridsize);
}
+ th = TTF_FontHeight(font[map[curmap].textob[map[curmap].curtext].h]);
+
/* copy current bg */
area.x = x;
area.y = y;
area.w = map[curmap].textob[map[curmap].curtext].w;
- area.h = map[curmap].textob[map[curmap].curtext].h;
+ area.h = th+5;
SDL_BlitSurface(screen,&area,bg,0);
bgx = area.x;
bgy = area.y;
@@ -8114,10 +8789,17 @@ int updatetextshadow(int x, int y) {
bgh = area.h;
/* draw box */
if ((x > 0) && (y > 0) && (x+map[curmap].textob[map[curmap].curtext].w-1 < map[curmap].width) && (y+map[curmap].textob[map[curmap].curtext].h-1 < map[curmap].height)) {
+ /*
drawline(screen,x,y,x+map[curmap].textob[map[curmap].curtext].w-1,y, map[curmap].boxcol,1);
drawline(screen,x,y,x,y+map[curmap].textob[map[curmap].curtext].h-1, map[curmap].boxcol,1);
drawline(screen,x,y+map[curmap].textob[map[curmap].curtext].h-1,x+map[curmap].textob[map[curmap].curtext].w-1,y+map[curmap].textob[map[curmap].curtext].h-1, map[curmap].boxcol,1);
drawline(screen,x+map[curmap].textob[map[curmap].curtext].w-1,y,x+map[curmap].textob[map[curmap].curtext].w-1,y+map[curmap].textob[map[curmap].curtext].h-1, map[curmap].boxcol,1);
+ */
+ drawbox(screen, x, y, x+area.w-1, y+th+2, map[curmap].boxcol, NULL);
+ SDL_BlitSurface(shadow, 0, screen, &area);
+
+
+
}
SDL_UpdateRect(screen, area.x, area.y, area.w, area.h);
return 0;
diff --git a/netmapr.exe b/netmapr.exe
index c0f1a15..c55f27d 100755
Binary files a/netmapr.exe and b/netmapr.exe differ
diff --git a/netmapr.h b/netmapr.h
index 9c01759..aa888f6 100644
--- a/netmapr.h
+++ b/netmapr.h
@@ -89,10 +89,11 @@ typedef struct {
} object_t;
-struct {
- vectorimg_t vect;
- char name;
-} letter[MAXLETTERVECTS];
+
+//struct {
+// vectorimg_t vect;
+// char name;
+//} letter[MAXLETTERVECTS];
typedef struct {
int id;
@@ -167,6 +168,8 @@ map_t map[MAXMAPS];
char typedesc[6][BUFLEN];
+
+void adjustendpoint(SDL_Surface *screen, int *adjx, int *adjy, double x1, double y1, double x2, double y2, int arrowstyle, int arrowpos );
void addlinkpoint(int linkid, int x, int y);
int addvector(vectorimg_t *vimg, int type, int x1, int y1, int x2, int y2, SDL_Color *c, SDL_Color *fc);
void changegridsize(void);
@@ -183,7 +186,10 @@ void deletething(int id, int type);
void deletelink(int linkid);
void deleteobject(int oid );
void deletetext(int textid);
+int dosearch(void);
+int dosearchnext(void);
void drawarrowhead(SDL_Surface *screen, double x1, double y1, double x2, double y2, SDL_Color c, int arrowstyle, int arrowpos);
+void drawarrowheadSVG(double x1, double y1, double x2, double y2, SDL_Color c, int arrowstyle, int arrowpos);
void lerp(int *newx, int *newy, int ax, int ay, int bx, int by, float t);
void drawbezier(SDL_Surface *screen, int x1, int y1, int x2,int y2, int x3,int y3, int x4,int y4, SDL_Color c);
void drawbox(SDL_Surface *screen, int x1, int y1, int x2, int y2, SDL_Color c, SDL_Color *fc);
@@ -192,7 +198,6 @@ void drawellipse(SDL_Surface *screen, int x1, int y1, int x2, int y2, SDL_Color
void drawflowbox(SDL_Surface *dest, int oid, int otype);
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);
void drawline(SDL_Surface *screen, int x1, int y1, int x2, int y2, SDL_Color c, int linestyle);
void drawlinebehind(SDL_Surface *screen, int x1, int y1, int x2, int y2, SDL_Color c);
void drawlink(SDL_Surface *dest, link_t *l);
@@ -239,7 +244,7 @@ void goback(void);
int linelen(int x1,int y1,int x2,int y2);
int linkat(int x, int y);
int loadmap(void);
-void lowerselected(void);
+void lowerselected(int amt);
int objat(int x, int y);
void paste(void);
void pasteline(SDL_Surface *screen, int *lbuf);
@@ -248,6 +253,7 @@ void push(int x, int y);
int initgraphics(void);
void initmap(int mapnum);
int initobject(int onum);
+int isinhistory(int mapid);
int isflow(int oid, int otype);
int isonline (int fx, int fy, int x1, int y1, int x2, int y2);
int isonlink(int linkid, int mx, int my);
@@ -262,7 +268,9 @@ int isonmapboxchildren (int x, int y);
int isonmapname (int x, int y);
int isongoback (int x, int y);
void initvars(void);
-void raiseselected(void);
+void raiseselected(int amt);
+void seterror(int errnum);
+void setinfo(int infonum);
void setmod(int tf);
int savemap(void);
void scrollobox(int amt);
diff --git a/netmapr.jpg b/netmapr.jpg
index 73c03fb..bf2a66b 100755
Binary files a/netmapr.jpg and b/netmapr.jpg differ
diff --git a/objects.dat b/objects.dat
index f9b2a08..5a317f6 100644
--- a/objects.dat
+++ b/objects.dat
@@ -488,3 +488,117 @@ line 165 75 180 70 0 0 0
# right wing
poly 0 0 0 p 278 35 283 45 183 80 173 60 273 25 278 35 f 0 110 148
end
+object house 200 200
+# roof
+poly 0 0 0 p 0 100 100 0 199 100 0 100 f 200 0 0
+# base
+box 25 100 175 199 0 0 0 255 146 143
+# door
+box 60 125 100 199 0 0 0 173 97 0
+# window
+box 115 115 160 150 0 0 0 0 0 255
+line 137 115 137 150 0 0 0
+line 115 132 160 132 0 0 0
+# chimney
+box 137 25 150 60 210 0 0 210 0 0
+line 137 60 137 25 0 0 0
+line 137 25 150 25 0 0 0
+line 150 25 150 60 0 0 0
+# chimney top
+box 134 20 153 25 0 0 0 173 97 0
+end
+object building 150 200
+# front
+box 0 25 102 199 240 240 240 150 150 150
+# side
+poly 240 240 240 p 102 25 149 0 149 175 102 199 102 25 f 90 90 90
+# top
+poly 240 240 240 p 0 25 47 0 149 0 102 25 0 25 f 200 200 200
+# windows - top row
+box 14 40 24 50 0 0 0 0 0 255
+box 30 40 40 50 0 0 0 0 0 255
+box 46 40 56 50 0 0 0 0 0 255
+box 62 40 72 50 0 0 0 0 0 255
+box 78 40 88 50 0 0 0 0 0 255
+# windows - top row
+box 14 56 24 66 0 0 0 0 0 255
+box 30 56 40 66 0 0 0 0 0 255
+box 46 56 56 66 0 0 0 0 0 255
+box 62 56 72 66 0 0 0 0 0 255
+box 78 56 88 66 0 0 0 0 0 255
+# windows - top row
+box 14 72 24 82 0 0 0 0 0 255
+box 30 72 40 82 0 0 0 0 0 255
+box 46 72 56 82 0 0 0 0 0 255
+box 62 72 72 82 0 0 0 0 0 255
+box 78 72 88 82 0 0 0 0 0 255
+# windows - top row
+box 14 88 24 98 0 0 0 0 0 255
+box 30 88 40 98 0 0 0 0 0 255
+box 46 88 56 98 0 0 0 0 0 255
+box 62 88 72 98 0 0 0 0 0 255
+box 78 88 88 98 0 0 0 0 0 255
+# windows - top row
+box 14 104 24 114 0 0 0 0 0 255
+box 30 104 40 114 0 0 0 0 0 255
+box 46 104 56 114 0 0 0 0 0 255
+box 62 104 72 114 0 0 0 0 0 255
+box 78 104 88 114 0 0 0 0 0 255
+# windows - top row
+box 14 120 24 130 0 0 0 0 0 255
+box 30 120 40 130 0 0 0 0 0 255
+box 46 120 56 130 0 0 0 0 0 255
+box 62 120 72 130 0 0 0 0 0 255
+box 78 120 88 130 0 0 0 0 0 255
+# door
+box 20 175 30 199 240 240 240 200 200 200
+box 30 175 40 199 240 240 240 200 200 200
+# door outline
+line 30 176 30 198 150 150 150
+end
+object ids-sensor 300 200
+# front
+box 0 25 275 199 170 230 255 0 150 213
+# top
+poly 170 230 255 p 0 25 25 0 299 0 275 25 0 25 f 0 180 255
+# side
+poly 170 230 255 p 275 25 299 0 299 175 275 199 275 25 f 0 90 128
+# circle
+subobj 250 250 250
+circle 137 110 80 60 20 20 20
+endsub
+# inner
+subobj 0 150 213
+circle 137 110 65 45 20 20 20
+endsub
+# top arrow
+poly 0 0 0 p 15 75 235 75 , 235 65 , 260 80 , 235 95 , 235 85 15 85 , 15 75 f 250 250 250
+# bottom arrow
+poly 0 0 0 p 260 125 40 125 , 40 115 , 15 130 , 40 145 , 40 135 260 135 , 260 125 f 250 250 250
+end
+object phone 200 145
+# base
+poly 0 0 0 p 25 95 , 25 144 , 175 144 , 175 95 , 135 35 , 65 35 , 25 95 f 0 90 128
+box 65 20 75 35 0 0 0 0 150 203
+box 125 20 135 35 0 0 0 0 150 203
+# handset ends
+box 0 50 40 70 0 0 0 0 180 255
+box 160 50 199 70 0 0 0 0 180 255
+# handset
+# left end
+poly 0 0 0 p 10 50 , 10 10 , 20 0 , 30 0 , 30 50 , 10 50 f 0 150 203
+# right end
+poly 0 0 0 p 190 50 , 190 10 , 180 0 , 170 0 , 170 50 , 190 50 f 0 150 203
+# top bit
+box 30 0 170 20 0 0 0 0 150 203
+# fixups
+line 30 1 30 19 0 150 203
+line 170 1 170 19 0 150 203
+# dial
+subobj 0 180 255 0 0
+circle 100 85 40 40 0 0 0
+endsub
+subobj 0 90 128
+circle 100 85 25 25 0 0 0
+endsub
+end
diff --git a/windist.sh b/windist.sh
index 1498404..55df78e 100755
--- a/windist.sh
+++ b/windist.sh
@@ -9,3 +9,5 @@ WINFILE=${FULLNAME}-win32.zip
mkdir ${FULLNAME}
cp README.txt INSTALL.txt objects.dat buttons.dat netmapr.exe netmapr.c netmapr.h constants.h convert.c convert.h verdana.ttf example.map icon.bmp windows_files/*.dll ${FULLNAME}/
cp -R doc ${FULLNAME}/
+
+zip -r ${WINFILE} ${FULLNAME}