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 @@ -
Object Box
+
Object Box
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}