9600 lines
268 KiB
C
9600 lines
268 KiB
C
#include <stdio.h>
|
|
#include <stdarg.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <time.h>
|
|
#include <sys/time.h>
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
|
|
#include <math.h>
|
|
|
|
#include <SDL.h>
|
|
#include <SDL_ttf.h>
|
|
#include <SDL_keysym.h>
|
|
|
|
#include "savepng.h"
|
|
#include "netmapr.h"
|
|
#include "constants.h"
|
|
|
|
SDL_Surface *screen, *buffer;
|
|
SDL_Surface *emptyimg;
|
|
SDL_Surface *icon;
|
|
SDL_Event event;
|
|
int isevent;
|
|
|
|
char svgbuf[BUFLEN];
|
|
FILE *svgfile;
|
|
|
|
TTF_Font *font[MAXLETTERHEIGHT];
|
|
|
|
SDL_Color white = { 255, 255, 255, USECOLOUR};
|
|
SDL_Color black = { 0, 0, 0, USECOLOUR};
|
|
SDL_Color red = { 255, 0, 0, USECOLOUR};
|
|
SDL_Color green = { 0, 255, 0, USECOLOUR};
|
|
SDL_Color blue = { 0, 0, 255, USECOLOUR};
|
|
SDL_Color blue2 = { 0, 0, 70, USECOLOUR};
|
|
SDL_Color yellow = { 255, 255, 0, USECOLOUR};
|
|
SDL_Color cyan = { 0, 255, 255, USECOLOUR};
|
|
SDL_Color purple = { 255, 0, 255, USECOLOUR};
|
|
SDL_Color grey = { 90, 90, 90, USECOLOUR};
|
|
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 };
|
|
|
|
SDL_Surface *searchbg;
|
|
int searchflash = 0;
|
|
int searchcounter = 0;
|
|
int searchticks = 0;
|
|
int oldsearchticks = 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};
|
|
|
|
SDL_Cursor *normalmouse;
|
|
SDL_Cursor *objmouse;
|
|
SDL_Cursor *textmouse;
|
|
|
|
|
|
int linemask[MAXLINESTYLE][LINESTYLESIZE];
|
|
|
|
xy_t fillstack[MAXFILLSTACK];
|
|
int fillstackptr = 0;
|
|
|
|
/* screen "viewpane" position */
|
|
int screenx = 0;
|
|
int screeny = 0;
|
|
|
|
int thingdrawn[MAXOBJECTS + MAXLINKS];
|
|
|
|
SDL_Color fgcol;
|
|
SDL_Color objfillcol;
|
|
Uint8 defthickness = 1;
|
|
Uint8 defstyle = LS_SOLID;
|
|
Uint8 defarrow = 0;
|
|
|
|
int modified = FALSE;
|
|
int readonly = FALSE;
|
|
int needtocalc = FALSE;
|
|
|
|
int maplistpos = 0; /* scroll position in map list */
|
|
|
|
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[] = {0, 10, 15, 20};
|
|
int gridsizeindex = 1;
|
|
int gridsizenum = 4;
|
|
SDL_Color gridcol = {192, 192, 192, 0 };
|
|
|
|
int oldshowflows = FALSE;
|
|
int showflows = FALSE;
|
|
|
|
int shortcut[] = { 9, 0, 1, 2, 3, 4, 5, 6, 7, 8 };
|
|
int shortcutnum = 10;
|
|
|
|
int matchtype = 0;
|
|
|
|
int numobjtypes = 0;
|
|
int numletters = 0;
|
|
int numbuttons = 0;
|
|
int nummaps = 1;
|
|
|
|
int history[MAXHISTORY];
|
|
int numhistory = 0;
|
|
|
|
int children[MAXCHILDREN];
|
|
int numchildren = 0;
|
|
|
|
|
|
char currentfilename[BUFLEN];
|
|
int state = S_NONE;
|
|
SDL_Surface *shadow = NULL; /* for object moves */
|
|
SDL_Surface *bg = NULL; /* background for temp images*/
|
|
int *linebg; /* background for temp lines */
|
|
int bgx,bgy;
|
|
int bgw,bgh;
|
|
int xoff,yoff;
|
|
SDL_Rect temparea;
|
|
char statustext[BUFLEN];
|
|
char oldstatustext[BUFLEN];
|
|
int rollover = FALSE;
|
|
int oldmousepos = -1;
|
|
int mousepos = 0;
|
|
int oldselection = -1;
|
|
int dontpaste = FALSE;
|
|
|
|
SDL_Surface *toolbg;
|
|
SDL_Surface *toolhilite;
|
|
|
|
int curmap = 0;
|
|
|
|
int startx,starty;
|
|
int textanchor;
|
|
char text[BUFLEN];
|
|
int startobj,endobj;
|
|
int updateheight;
|
|
char * textpos; // new
|
|
|
|
char progdir[BUFLEN];
|
|
|
|
int shift;
|
|
int autoload = FALSE;
|
|
|
|
int main (int argc, char **argv) {
|
|
int done;
|
|
int c;
|
|
int c2;
|
|
int mod = FALSE;
|
|
int tmod;
|
|
int o;
|
|
Uint32 oldticks = 0;
|
|
Uint32 ticks;
|
|
int doubleclick = FALSE;
|
|
int n,found,delmap;
|
|
int mx,my,mb;
|
|
|
|
if (argc >= 2) {
|
|
int i;
|
|
strcpy(text, argv[1]);
|
|
/* cope with spaces in filenames */
|
|
for (i = 2; i < argc; i++) {
|
|
strcat(text, " ");
|
|
strcat(text, argv[i]);
|
|
}
|
|
autoload = TRUE;
|
|
}
|
|
|
|
if (getenv("NETMAPRDIR") != NULL) {
|
|
strncpy(progdir, getenv("NETMAPRDIR"), BUFLEN);
|
|
} else {
|
|
strcpy(progdir, "/usr/local/share/netmapr");
|
|
}
|
|
|
|
if (strstr(argv[0], "view")) {
|
|
readonly = TRUE;
|
|
}
|
|
|
|
/*
|
|
if (readonly) {
|
|
printf("Starting netmapr viewer v%s...\n", VERSION);
|
|
} else {
|
|
printf("Starting netmapr v%s...\n", VERSION);
|
|
}
|
|
*/
|
|
|
|
|
|
|
|
if (initgraphics()) {
|
|
printf("Error initialising graphics.\n");
|
|
exit(1);
|
|
}
|
|
atexit(cleanup);
|
|
|
|
SDL_EnableUNICODE(1);
|
|
|
|
|
|
if (autoload) {
|
|
loadmap();
|
|
strcpy(text, "");
|
|
}
|
|
|
|
|
|
if (readonly) {
|
|
sprintf(statustext, "Welcome to netmapr viewer v%s. Author: rob@nethack.net", VERSION);
|
|
} else {
|
|
sprintf(statustext, "Welcome to netmapr v%s. Author: rob@nethack.net", VERSION);
|
|
}
|
|
strcpy(oldstatustext,statustext);
|
|
drawscreen();
|
|
|
|
/* main loop */
|
|
done = 0;
|
|
|
|
while (!done) {
|
|
/* fade search result indicator */
|
|
if (searchflash > 0) {
|
|
searchticks = SDL_GetTicks();
|
|
if (searchticks - oldsearchticks >= SEARCHFLASHSPEED) {
|
|
searchflash--;
|
|
/* show the found object */
|
|
switch (state) {
|
|
case S_SAVING:
|
|
case S_LOADING:
|
|
case S_FGCOL:
|
|
case S_MAPNAMING:
|
|
case S_CREATETELE:
|
|
case S_REALLYQUIT:
|
|
case S_FILLCOL:
|
|
case S_SEARCH:
|
|
break;
|
|
default:
|
|
drawsearchflash();
|
|
break;
|
|
}
|
|
|
|
oldsearchticks = searchticks;
|
|
}
|
|
}
|
|
/* 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)) {
|
|
isevent = TRUE;
|
|
if (infoflash || errorflash || searchflash) {
|
|
if (!SDL_PollEvent(&event)) isevent = FALSE;
|
|
} else {
|
|
if (!SDL_WaitEvent(&event)) isevent = FALSE;
|
|
}
|
|
|
|
while (isevent) {
|
|
switch (event.type) {
|
|
case SDL_VIDEORESIZE:
|
|
/* set screen size */
|
|
screen = SDL_SetVideoMode(event.resize.w > MINSCREENX ? event.resize.w : MINSCREENX,
|
|
event.resize.h > MINSCREENY ? event.resize.h : MINSCREENY,
|
|
//map[curmap].bpp, SDL_SWSURFACE|SDL_DOUBLEBUF|SDL_RESIZABLE);
|
|
map[curmap].bpp, SDL_SWSURFACE|SDL_RESIZABLE);
|
|
SDL_FreeSurface(buffer);
|
|
buffer = SDL_CreateRGBSurface(SDL_SWSURFACE,screen->w - SIDEBARW,screen->h - STATUSH,
|
|
screen->format->BitsPerPixel, screen->format->Rmask,
|
|
screen->format->Gmask,screen->format->Bmask,
|
|
screen->format->Amask);
|
|
calcmapdimensions();
|
|
drawscreen();
|
|
break;
|
|
case SDL_MOUSEBUTTONDOWN:
|
|
searchflash = 0;
|
|
if (isonxscrollbar(event.button.x, event.button.y)) {
|
|
/* middle of the screen goes to where we clicked */
|
|
screenx = (((double)event.button.x / (double)(screen->w - SIDEBARW)) * map[curmap].width)
|
|
- ((screen->w - SIDEBARW)/2);
|
|
|
|
validatescreenpos();
|
|
drawxscrollbar();
|
|
changestate(S_XSCROLL);
|
|
} else if (isonyscrollbar(event.button.x, event.button.y)) {
|
|
/* middle of the screen goes to where we clicked */
|
|
screeny = (((double)event.button.y / (double)(screen->h - STATUSH - SBSIZE)) * map[curmap].height)
|
|
- ((screen->h - STATUSH - SBSIZE)/2);
|
|
|
|
validatescreenpos();
|
|
drawyscrollbar();
|
|
changestate(S_YSCROLL);
|
|
} else if (isonmap(event.button.x, event.button.y)) {
|
|
event.button.x += screenx;
|
|
event.button.y += screeny;
|
|
if (state == S_NONE) {
|
|
mod = SDL_GetModState();
|
|
if ((event.button.button == SDL_BUTTON_LEFT) && ((mod & KMOD_SHIFT))) {
|
|
/* centre map on clicked position */
|
|
screenx = event.button.x - ((screen->w - SIDEBARW)/2);
|
|
screeny = event.button.y - ((screen->h - STATUSH)/2);
|
|
validatescreenpos();
|
|
drawmap(TRUE);
|
|
} else if ((event.button.button == SDL_BUTTON_LEFT) && ((mod & KMOD_CTRL) == 0)) {
|
|
/* is there a selected link? if so check for it first */
|
|
if ((map[curmap].selecteditemtype == T_LINK) && (map[curmap].selecteditem != -1) &&
|
|
(isonlinkdst(map[curmap].selecteditem, event.button.x,event.button.y)) ) {
|
|
|
|
map[curmap].curlink = map[curmap].selecteditem;
|
|
startlinkdstmove(event.button.x, event.button.y);
|
|
} else if ((map[curmap].selecteditemtype == T_LINK) && (map[curmap].selecteditem != -1) &&
|
|
(isonlinksrc(map[curmap].selecteditem, event.button.x,event.button.y)) ) {
|
|
map[curmap].curlink = map[curmap].selecteditem;
|
|
startlinksrcmove(event.button.x, event.button.y);
|
|
} else if ( ((map[curmap].selecteditemtype == T_LINK) || (map[curmap].selecteditemtype == T_LINKPOINT))
|
|
&& (map[curmap].selecteditem != -1) &&
|
|
(isonlinkpoint(map[curmap].selecteditem, event.button.x,event.button.y) != -1) ) {
|
|
map[curmap].curlink = map[curmap].selecteditem;
|
|
map[curmap].curlinkpoint = isonlinkpoint(map[curmap].selecteditem, event.button.x,event.button.y);
|
|
startlinkpointmove(event.button.x, event.button.y);
|
|
} else {
|
|
// move/select object
|
|
o = thingat(event.button.x, event.button.y);
|
|
if (o != -1) {
|
|
switch (map[curmap].thing[o].type) {
|
|
case T_OBJECT:
|
|
map[curmap].curobj = map[curmap].thing[o].id;
|
|
startobjmove(event.button.x,event.button.y);
|
|
break;
|
|
case T_LINK:
|
|
map[curmap].curlink = map[curmap].thing[o].id;
|
|
startlinkmove(event.button.x, event.button.y);
|
|
break;
|
|
case T_TEXT:
|
|
map[curmap].curtext = map[curmap].thing[o].id;
|
|
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) ||
|
|
((event.button.button == SDL_BUTTON_LEFT) && (mod & KMOD_CTRL))) {
|
|
// if we're over an object, start drawing a new link
|
|
o = objat(event.button.x, event.button.y);
|
|
if (o != -1) {
|
|
map[curmap].curobj = o;
|
|
startlink(event.button.x,event.button.y);
|
|
}
|
|
} else if (event.button.button == SDL_BUTTON_RIGHT) {
|
|
// resize text
|
|
o = textat(event.button.x, event.button.y);
|
|
if (o != -1) {
|
|
map[curmap].curtext = o;
|
|
startresizetext(event.button.x,event.button.y);
|
|
} else {
|
|
// resize object
|
|
o = objat(event.button.x, event.button.y);
|
|
if (o != -1) {
|
|
map[curmap].curobj = o;
|
|
startresize(event.button.x,event.button.y);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
// resize object
|
|
o = objat(event.button.x, event.button.y);
|
|
if (o != -1) {
|
|
map[curmap].curobj = o;
|
|
startresize(event.button.x,event.button.y);
|
|
} else {
|
|
// resize text
|
|
o = textat(event.button.x, event.button.y);
|
|
if (o != -1) {
|
|
map[curmap].curtext = o;
|
|
startresizetext(event.button.x,event.button.y);
|
|
}
|
|
}
|
|
*/
|
|
} 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(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(amt);
|
|
}
|
|
}
|
|
} /* end if state = none */
|
|
} 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(-amt);
|
|
} else if (event.button.button == SDL_BUTTON_WHEELDOWN) {
|
|
scrollobox(amt);
|
|
}
|
|
}
|
|
break;
|
|
case SDL_MOUSEBUTTONUP:
|
|
searchflash = 0;
|
|
mod = SDL_GetModState();
|
|
if ((event.button.button == SDL_BUTTON_LEFT) && ((mod & KMOD_CTRL) == 0)) {
|
|
ticks = SDL_GetTicks();
|
|
if ((ticks - oldticks) <= DOUBLECLICKTHRES) {
|
|
doubleclick = TRUE;
|
|
} else {
|
|
doubleclick = FALSE;
|
|
}
|
|
oldticks = ticks;
|
|
|
|
if ((state == S_XSCROLL) || (state == S_YSCROLL)) {
|
|
changestate(S_NONE);
|
|
drawmap(TRUE);
|
|
} else if (state == S_EDITTEXT) {
|
|
endtextedit();
|
|
} else if (state == S_TYPETEXT) {
|
|
endtext();
|
|
} else if (isonmap(event.button.x, event.button.y)) {
|
|
event.button.x += screenx;
|
|
event.button.y += screeny;
|
|
if (state != S_REALLYQUIT) {
|
|
//if ((doubleclick) && (objat(event.button.x, event.button.y) == map[curmap].selecteditem)) {
|
|
if (doubleclick) {
|
|
o = objat(event.button.x, event.button.y);
|
|
|
|
/* only works on an object */
|
|
//if (map[curmap].selecteditem != -1) {
|
|
if (o != -1) {
|
|
/* can't create a new child via double click */
|
|
if (map[curmap].obj[o].child != -1) {
|
|
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);
|
|
drawmap(TRUE);
|
|
}
|
|
} else {
|
|
o = textat(event.button.x, event.button.y);
|
|
if (o != -1) {
|
|
startedittext(o);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (state == S_NONE) {
|
|
if (map[curmap].selecteditem != -1) {
|
|
map[curmap].selecteditem = -1;
|
|
map[curmap].selecteditemtype = T_EMPTY;
|
|
sprintf(statustext,"Objects/lines deselected.\n");
|
|
drawmap(TRUE);
|
|
}
|
|
} else if (state == S_DRAWFLOW) {
|
|
int clickedtype = -1;
|
|
o = textat(event.button.x, event.button.y);
|
|
if (o == -1) {
|
|
o = objat(event.button.x, event.button.y);
|
|
if (o == -1) {
|
|
o = linkat(event.button.x, event.button.y);
|
|
if (o != -1) {
|
|
clickedtype = T_LINK;
|
|
}
|
|
} else {
|
|
clickedtype = T_OBJECT;
|
|
}
|
|
} else {
|
|
clickedtype = T_TEXT;
|
|
}
|
|
if (clickedtype == -1) {
|
|
/* reset to old showflows value */
|
|
changestate(S_NONE);
|
|
drawmap(TRUE);
|
|
} 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(TRUE);
|
|
}
|
|
} else if (state == S_REALLYQUIT) {
|
|
o = getyn(event.button.x-screenx, event.button.y-screeny);
|
|
if (o == YES) {
|
|
done = TRUE;
|
|
} else {
|
|
changestate(S_NONE);
|
|
drawmap(TRUE);
|
|
}
|
|
} else if (state == S_MATCHSIZE) {
|
|
if (matchtype == T_OBJECT) {
|
|
o = objat(event.button.x, event.button.y);
|
|
if (o == -1) {
|
|
changestate(S_NONE);
|
|
sprintf(statustext, "Size match mode aborted.");
|
|
drawstatusbar();
|
|
} else {
|
|
int n;
|
|
/* resize selected item to match one which was clicked */
|
|
map[curmap].obj[map[curmap].selecteditem].w = map[curmap].obj[o].w;
|
|
map[curmap].obj[map[curmap].selecteditem].h = map[curmap].obj[o].h;
|
|
/* adjust offsets on all links to/from object */
|
|
for (n = 0; n < map[curmap].numlinks; n++) {
|
|
if (map[curmap].olink[n].srcobj == map[curmap].selecteditem) {
|
|
map[curmap].olink[n].srcxoff = (map[curmap].obj[o].w / 2);
|
|
map[curmap].olink[n].srcyoff = (map[curmap].obj[o].h / 2);
|
|
}
|
|
if (map[curmap].olink[n].dstobj == map[curmap].selecteditem) {
|
|
map[curmap].olink[n].dstxoff = (map[curmap].obj[o].w / 2);
|
|
map[curmap].olink[n].dstyoff = (map[curmap].obj[o].h / 2);
|
|
}
|
|
}
|
|
changestate(S_NONE);
|
|
sprintf(statustext, "Object #%d resized to match object #%d.",map[curmap].selecteditem,o);
|
|
drawmap(TRUE);
|
|
}
|
|
} else if (matchtype == T_TEXT) {
|
|
o = textat(event.button.x, event.button.y);
|
|
if (o == -1) {
|
|
changestate(S_NONE);
|
|
sprintf(statustext, "Size match mode aborted.");
|
|
drawstatusbar();
|
|
} else {
|
|
int tw,th;
|
|
/* resize selected text to match one which was clicked */
|
|
map[curmap].textob[map[curmap].selecteditem].h = map[curmap].textob[o].h;
|
|
TTF_SizeText(font[map[curmap].textob[o].h], map[curmap].textob[map[curmap].selecteditem].text, &tw,&th);
|
|
map[curmap].textob[map[curmap].selecteditem].w = tw;
|
|
/* adjust offsets on all links to/from object */
|
|
changestate(S_NONE);
|
|
sprintf(statustext, "Text #%d resized to match text #%d.",map[curmap].selecteditem,o);
|
|
drawmap(TRUE);
|
|
}
|
|
}
|
|
} else if (state == S_MATCHX) {
|
|
if (matchtype == T_OBJECT) {
|
|
o = objat(event.button.x, event.button.y);
|
|
if (o == -1) {
|
|
changestate(S_NONE);
|
|
sprintf(statustext, "X position match mode aborted.");
|
|
drawstatusbar();
|
|
} else {
|
|
/* move selected item to match one which was clicked */
|
|
/* match middle of objects! */
|
|
map[curmap].obj[map[curmap].selecteditem].x =
|
|
(map[curmap].obj[o].x + (map[curmap].obj[o].w/2))
|
|
-
|
|
(map[curmap].obj[map[curmap].selecteditem].w/2);
|
|
changestate(S_NONE);
|
|
sprintf(statustext, "Object #%d X relocated to match object #%d.",map[curmap].selecteditem,o);
|
|
drawmap(TRUE);
|
|
}
|
|
} else if (matchtype == T_TEXT) {
|
|
o = textat(event.button.x, event.button.y);
|
|
if (o == -1) {
|
|
changestate(S_NONE);
|
|
sprintf(statustext, "X position match mode aborted.");
|
|
drawstatusbar();
|
|
} else {
|
|
/* move selected item to match one which was clicked */
|
|
/* match middle of text */
|
|
map[curmap].textob[map[curmap].selecteditem].x =
|
|
(map[curmap].textob[o].x + (map[curmap].textob[o].w/2))
|
|
-
|
|
(map[curmap].textob[map[curmap].selecteditem].w/2);
|
|
/* validate */
|
|
if (map[curmap].textob[map[curmap].selecteditem].x < 1) map[curmap].textob[map[curmap].selecteditem].x = 1;
|
|
if (map[curmap].textob[map[curmap].selecteditem].x + map[curmap].textob[map[curmap].selecteditem].w > map[curmap].width) map[curmap].textob[map[curmap].selecteditem].x = map[curmap].width - map[curmap].textob[map[curmap].selecteditem].w;
|
|
|
|
changestate(S_NONE);
|
|
sprintf(statustext, "Text #%d X relocated to match text #%d.",map[curmap].selecteditem,o);
|
|
drawmap(TRUE);
|
|
}
|
|
}
|
|
} else if (state == S_MATCHY) {
|
|
if (matchtype == T_OBJECT) {
|
|
o = objat(event.button.x, event.button.y);
|
|
if (o == -1) {
|
|
changestate(S_NONE);
|
|
sprintf(statustext, "Y position match mode aborted.");
|
|
drawstatusbar();
|
|
} else {
|
|
/* move selected item to match one which was clicked */
|
|
map[curmap].obj[map[curmap].selecteditem].y =
|
|
(map[curmap].obj[o].y + (map[curmap].obj[o].h / 2))
|
|
-
|
|
map[curmap].obj[map[curmap].selecteditem].h/2;
|
|
changestate(S_NONE);
|
|
sprintf(statustext, "Object #%d Y relocated to match object #%d.",map[curmap].selecteditem,o);
|
|
drawmap(TRUE);
|
|
}
|
|
} else if (matchtype == T_TEXT) {
|
|
o = textat(event.button.x, event.button.y);
|
|
if (o == -1) {
|
|
changestate(S_NONE);
|
|
sprintf(statustext, "Y position match mode aborted.");
|
|
drawstatusbar();
|
|
} else {
|
|
int curh, copyh;
|
|
|
|
curh = TTF_FontHeight(font[map[curmap].textob[map[curmap].selecteditem].h]);
|
|
copyh = TTF_FontHeight(font[map[curmap].textob[o].h]);
|
|
/* move selected item to match one which was clicked */
|
|
map[curmap].textob[map[curmap].selecteditem].y =
|
|
(map[curmap].textob[o].y + (copyh / 2))
|
|
-
|
|
(curh / 2);
|
|
|
|
|
|
/* validate */
|
|
if (map[curmap].textob[map[curmap].selecteditem].y < 1) map[curmap].textob[map[curmap].selecteditem].y = 1;
|
|
if (map[curmap].textob[map[curmap].selecteditem].y + curh > map[curmap].height) map[curmap].textob[map[curmap].selecteditem].y = map[curmap].height - curh - 1;
|
|
|
|
/* match middle of text */
|
|
changestate(S_NONE);
|
|
sprintf(statustext, "Text #%d Y relocated to match text #%d.",map[curmap].selecteditem,o);
|
|
drawmap(TRUE);
|
|
}
|
|
}
|
|
} else if (state == S_OBJMOVING) {
|
|
/* has mouse actually moved? */
|
|
if ((event.button.x == startx) && (event.button.y == starty)) {
|
|
/* select the object */
|
|
map[curmap].selecteditem = map[curmap].curobj;
|
|
map[curmap].selecteditemtype = T_OBJECT;
|
|
changestate(S_NONE);
|
|
sprintf(statustext, "Object #%d (%s) selected.\n",map[curmap].selecteditem, objtype[map[curmap].obj[map[curmap].selecteditem].type].name);
|
|
drawmap(TRUE);
|
|
} else {
|
|
// actually move the object
|
|
if (!endobjmove(event.button.x, event.button.y)) {
|
|
sprintf(statustext, "Object #%d moved to (%d,%d).\n",map[curmap].curobj,event.button.x, event.button.y);
|
|
}
|
|
changestate(S_NONE);
|
|
drawmap(TRUE);
|
|
|
|
}
|
|
} else if (state == S_LINKMOVING) {
|
|
/* has mouse actually moved? */
|
|
if ((event.button.x - screenx == startx) && (event.button.y - screeny == starty)) {
|
|
/* select the link */
|
|
map[curmap].selecteditem = map[curmap].curlink;
|
|
map[curmap].selecteditemtype = T_LINK;
|
|
changestate(S_NONE);
|
|
sprintf(statustext,"Link #%d selected.\n",map[curmap].selecteditem);
|
|
drawmap(TRUE);
|
|
} else {
|
|
// actually move the link
|
|
endlinkmove(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(TRUE);
|
|
}
|
|
} else if (state == S_LINKPOINTMOVE) {
|
|
/* has mouse actually moved? */
|
|
if ((event.button.x == startx) && (event.button.y == starty)) {
|
|
/* select the link point */
|
|
map[curmap].selecteditem = map[curmap].curlink;
|
|
map[curmap].selecteditemtype = T_LINKPOINT;
|
|
map[curmap].selectedlinkpoint = map[curmap].curlinkpoint;
|
|
changestate(S_NONE);
|
|
sprintf(statustext,"Link #%d point #%d selected.\n",map[curmap].selecteditem,map[curmap].selectedlinkpoint);
|
|
drawmap(TRUE);
|
|
} else {
|
|
// actually move the link
|
|
endlinkpointmove(event.button.x, event.button.y);
|
|
changestate(S_NONE);
|
|
drawmap(TRUE);
|
|
}
|
|
} else if (state == S_TEXTMOVING) {
|
|
/* has mouse actually moved? */
|
|
if ((event.button.x == startx) && (event.button.y == starty)) {
|
|
/* select the object */
|
|
map[curmap].selecteditem = map[curmap].curtext;
|
|
map[curmap].selecteditemtype = T_TEXT;
|
|
changestate(S_NONE);
|
|
sprintf(statustext,"Text item #%d selected.\n",map[curmap].selecteditem);
|
|
drawmap(TRUE);
|
|
} else {
|
|
// actually move the text
|
|
if (!endtextmove(event.button.x, event.button.y)) {
|
|
sprintf(statustext,"Text item #%d moved to (%d,%d).\n",map[curmap].curtext,event.button.x, event.button.y);
|
|
}
|
|
changestate(S_NONE);
|
|
drawmap(TRUE);
|
|
|
|
}
|
|
} else if (state == S_LINKSRCMOVE) {
|
|
// actually move the link src endpoint
|
|
endlinksrcmove(event.button.x, event.button.y);
|
|
changestate(S_NONE);
|
|
drawmap(TRUE);
|
|
} else if (state == S_LINKDSTMOVE) {
|
|
// actually move the link dst endpoint
|
|
endlinkdstmove(event.button.x, event.button.y);
|
|
changestate(S_NONE);
|
|
drawmap(TRUE);
|
|
} else if (state == S_ADDOBJ) {
|
|
/* create a new object */
|
|
createobject(map[curmap].selectedtype, event.button.x, event.button.y);
|
|
drawmap(TRUE);
|
|
changestate(S_NONE);
|
|
} else if (state == S_ADDTEXT) {
|
|
/* start listening for text input */
|
|
startx = event.button.x;
|
|
starty = event.button.y;
|
|
textanchor = objat(event.button.x,event.button.y);
|
|
if (textanchor != -1) {
|
|
startx = map[curmap].obj[textanchor].x;
|
|
starty = map[curmap].obj[textanchor].y + map[curmap].obj[textanchor].h+3;
|
|
}
|
|
updateheight = DEFTEXTH;
|
|
|
|
strcpy(text, "");
|
|
textpos = text;
|
|
|
|
bg = NULL;
|
|
updatetextcursor();
|
|
|
|
changestate(S_TYPETEXT);
|
|
} else if (state == S_FILLCOL) {
|
|
getcolor(screen, event.button.x, event.button.y, &objfillcol);
|
|
objfillcol.unused |= USECOLOUR; /* clear NOCOLOUR flag */
|
|
if (map[curmap].selecteditem != -1) {
|
|
if (map[curmap].selecteditemtype == T_OBJECT) {
|
|
map[curmap].obj[map[curmap].selecteditem].fillcol = objfillcol;
|
|
map[curmap].obj[map[curmap].selecteditem].fillcol.unused |= USECOLOUR;
|
|
sprintf(statustext, "Fill colour of object #%d changed to R=%d,G=%d,B=%d",map[curmap].selecteditem, objfillcol.r,objfillcol.g,objfillcol.b);
|
|
} else {
|
|
sprintf(statustext, "Fill colour selected: R=%d,G=%d,B=%d",objfillcol.r,objfillcol.g,objfillcol.b);
|
|
}
|
|
} else {
|
|
sprintf(statustext, "Fill colour selected: R=%d,G=%d,B=%d",objfillcol.r,objfillcol.g,objfillcol.b);
|
|
}
|
|
changestate(S_NONE);
|
|
drawmap(TRUE);
|
|
} 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);
|
|
}
|
|
} else {
|
|
sprintf(statustext, "Foreground colour selected: R=%d,G=%d,B=%d",fgcol.r,fgcol.g,fgcol.b);
|
|
}
|
|
changestate(S_NONE);
|
|
drawmap(TRUE);
|
|
} else if (state == S_CREATETELE) {
|
|
int pos;
|
|
|
|
if (event.button.y >= 50) {
|
|
pos = (event.button.y - 50) / (DEFTEXTH*2);
|
|
pos--;
|
|
if (pos == -1) {
|
|
map[curmap].obj[map[curmap].selecteditem].child = pos;
|
|
sprintf(statustext, "Map link removed.");
|
|
strcpy(oldstatustext, statustext);
|
|
setmod(TRUE);
|
|
changestate(S_NONE);
|
|
drawmap(TRUE);
|
|
} else if ((pos+maplistpos) <= (nummaps-1)) {
|
|
if ((map[curmap].selecteditem != -1) && (map[curmap].selecteditemtype == T_OBJECT)) {
|
|
if ((pos+maplistpos) != curmap) {
|
|
map[curmap].obj[map[curmap].selecteditem].child = pos + maplistpos;
|
|
sprintf(statustext, "Map link created.");
|
|
strcpy(oldstatustext, statustext);
|
|
setmod(TRUE);
|
|
changestate(S_NONE);
|
|
drawmap(TRUE);
|
|
} else {
|
|
seterror(255);
|
|
sprintf(statustext, "ERROR: Cannot link to current map!");
|
|
drawstatusbar();
|
|
}
|
|
}
|
|
} else { /* mouse is not over a map name */
|
|
sprintf(statustext, "Map link creation cancelled.");
|
|
changestate(S_NONE);
|
|
drawmap(TRUE);
|
|
}
|
|
} else {
|
|
sprintf(statustext, "Map link creation cancelled.");
|
|
changestate(S_NONE);
|
|
drawmap(TRUE);
|
|
}
|
|
}
|
|
|
|
} else if (isonobox(event.button.x, event.button.y)) {
|
|
int tempx,tempy;
|
|
|
|
tempx = (event.button.x - obox.x) / (obox.gridsize+3);
|
|
tempy = (event.button.y - obox.y) / (obox.gridsize+3);
|
|
if (state == S_CHANGEOBJECT) {
|
|
int seltype;
|
|
seltype = tempy*obox.gridrowlen + tempx + (obox.pos*3);
|
|
if (seltype >= numobjtypes) seltype = numobjtypes-1;
|
|
if (map[curmap].selecteditemtype != T_OBJECT) {
|
|
seterror(255);
|
|
sprintf(statustext, "ERROR: Must select an object to change the type of!");
|
|
drawstatusbar();
|
|
} else if (map[curmap].selecteditem == -1) {
|
|
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);
|
|
map[curmap].obj[map[curmap].selecteditem].type = seltype;
|
|
state = S_NONE;
|
|
drawtoolbox();
|
|
drawmap(TRUE);
|
|
}
|
|
} else {
|
|
map[curmap].selectedtype = tempy*obox.gridrowlen + tempx + (obox.pos*3);
|
|
if (map[curmap].selectedtype >= numobjtypes) map[curmap].selectedtype = numobjtypes-1;
|
|
sprintf(statustext,"Object type '%s' selected.\n",objtype[map[curmap].selectedtype].name);
|
|
}
|
|
drawstatusbar();
|
|
|
|
drawobox();
|
|
} else if (isongoback(event.button.x, event.button.y)) {
|
|
/* go back */
|
|
goback();
|
|
} else if (isonmapname(event.button.x, event.button.y)) {
|
|
/* rename current map */
|
|
startx = 1;
|
|
starty = ((screen->h - STATUSH)/2)-2;
|
|
bg = NULL;
|
|
strcpy(text, map[curmap].name);
|
|
changestate(S_MAPNAMING);
|
|
drawmap(TRUE);
|
|
break;
|
|
} else if (isonmapboxchildren(event.button.x, event.button.y)) {
|
|
if ((state != S_XSCROLL) && (state != S_YSCROLL)) {
|
|
int pos;
|
|
int th;
|
|
|
|
/* calculate pixel size of mapbox text */
|
|
th = TTF_FontHeight(font[MAPBOXTEXTHEIGHT]);
|
|
/* change to child */
|
|
pos = (event.button.y - (mapbox.y+(th*2)+1)) / th;
|
|
/* 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 {
|
|
drillto(children[pos]);
|
|
}
|
|
}
|
|
break;
|
|
} else if (isontoolbox(event.button.x, event.button.y)) {
|
|
int tempx,tempy, selection;
|
|
int boxy;
|
|
|
|
tempx = (event.button.x - toolbox.x) / (toolbox.gridsize+3);
|
|
tempy = (event.button.y - toolbox.y) / (toolbox.gridsize+3);
|
|
|
|
boxy = toolbox.y + (tempy*(toolbox.gridsize+3));
|
|
|
|
/* 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(TRUE);
|
|
break;
|
|
} else if (state == S_FILLCOL) {
|
|
/* set bgcol to 'nothing' */
|
|
objfillcol = black;
|
|
objfillcol.unused &= ~(USECOLOUR);
|
|
if (map[curmap].selecteditem != -1) {
|
|
if (map[curmap].selecteditemtype == T_OBJECT) {
|
|
map[curmap].obj[map[curmap].selecteditem].fillcol = black;
|
|
map[curmap].obj[map[curmap].selecteditem].fillcol.unused &= ~(USECOLOUR);
|
|
sprintf(statustext, "Fill colour of object #%d removed.", map[curmap].selecteditem);
|
|
} else {
|
|
sprintf(statustext, "Fill colour removed.");
|
|
}
|
|
} else {
|
|
sprintf(statustext, "Fill colour removed.");
|
|
}
|
|
changestate(S_NONE);
|
|
drawmap(TRUE);
|
|
break;
|
|
}
|
|
|
|
selection = tempy*toolbox.gridrowlen + tempx;
|
|
switch (selection) {
|
|
case TB_POINTER:
|
|
/* special case - update sbar */
|
|
sprintf(statustext, "Selection mode entered.");
|
|
drawstatusbar();
|
|
changestate(S_NONE);
|
|
map[curmap].curobj = -1;
|
|
break;
|
|
case TB_ADDOBJ:
|
|
changestate(S_ADDOBJ);
|
|
if (map[curmap].selectedtype < 0) map[curmap].selectedtype = 0;
|
|
break;
|
|
case TB_ADDTEXT:
|
|
changestate(S_ADDTEXT);
|
|
break;
|
|
case TB_COPY:
|
|
copy();
|
|
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;
|
|
}
|
|
drawtoolbox();
|
|
drawmap(TRUE);
|
|
break;
|
|
case TB_GRID:
|
|
togglegrid();
|
|
drawmap(TRUE);
|
|
break;
|
|
case TB_NEW:
|
|
if (readonly) {
|
|
seterror(255);
|
|
sprintf(statustext, "Cannot delete maps in read-only mode.");
|
|
drawstatusbar();
|
|
break;
|
|
|
|
}
|
|
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);
|
|
|
|
drawmap(TRUE);
|
|
break;
|
|
case TB_LINESTYLE:
|
|
if (map[curmap].selecteditemtype == T_LINK) {
|
|
if (map[curmap].selecteditem != -1) {
|
|
int si = map[curmap].selecteditem;
|
|
/* TODO: add arrow */
|
|
/* where are we? */
|
|
if (event.button.y <= (boxy + 9)) {
|
|
/* clear thickness */
|
|
map[curmap].olink[si].style &= 0xFFFF00;
|
|
/* set to default */
|
|
map[curmap].olink[si].style |= defthickness;
|
|
} else if (event.button.y <= (boxy + 19)) {
|
|
/* clear style */
|
|
map[curmap].olink[si].style &= 0xFF00FF;
|
|
/* set to default */
|
|
map[curmap].olink[si].style |= (defstyle << 8);
|
|
} else {
|
|
/* clear arrow */
|
|
map[curmap].olink[si].style &= 0x00FFFF;
|
|
/* set to default */
|
|
map[curmap].olink[si].style |= (defarrow << 16);
|
|
}
|
|
setmod(TRUE);
|
|
drawmap(TRUE);
|
|
} else {
|
|
seterror(255);
|
|
sprintf(statustext, "No link selected!");
|
|
}
|
|
} else {
|
|
seterror(255);
|
|
sprintf(statustext, "No link selected!");
|
|
}
|
|
drawstatusbar();
|
|
break;
|
|
case TB_MATCHSIZE:
|
|
if (map[curmap].selecteditem != -1) {
|
|
switch (map[curmap].selecteditemtype) {
|
|
case T_OBJECT:
|
|
case T_TEXT:
|
|
matchtype = map[curmap].selecteditemtype;
|
|
changestate(S_MATCHSIZE);
|
|
drawmap(TRUE);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case TB_MATCHPOS:
|
|
if (map[curmap].selecteditem != -1) {
|
|
switch (map[curmap].selecteditemtype) {
|
|
case T_OBJECT:
|
|
case T_TEXT:
|
|
matchtype = map[curmap].selecteditemtype;
|
|
changestate(S_MATCHX);
|
|
drawmap(TRUE);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case TB_PASTE:
|
|
paste();
|
|
break;
|
|
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 {
|
|
seterror(255);
|
|
sprintf(statustext, "No object selected! (use RMB to select new foreground colour)");
|
|
}
|
|
drawmap(TRUE);
|
|
break;
|
|
case TB_FILLCOL:
|
|
if (map[curmap].selecteditem != -1) {
|
|
if (map[curmap].selecteditemtype == T_OBJECT) {
|
|
map[curmap].obj[map[curmap].selecteditem].fillcol = objfillcol;
|
|
map[curmap].obj[map[curmap].selecteditem].fillcol.unused = objfillcol.unused;
|
|
setmod(TRUE);
|
|
if (objfillcol.unused & USECOLOUR) {
|
|
sprintf(statustext, "Fill colour of object #%d changed to R=%d,G=%d,B=%d",map[curmap].selecteditem, objfillcol.r,objfillcol.g,objfillcol.b);
|
|
} else {
|
|
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(TRUE);
|
|
break;
|
|
case TB_DELETEMAP:
|
|
/* safety - must hold down SHIFT to delete maps */
|
|
|
|
if (readonly) {
|
|
seterror(255);
|
|
sprintf(statustext, "Cannot delete maps in read-only mode.");
|
|
drawstatusbar();
|
|
break;
|
|
|
|
}
|
|
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;
|
|
}
|
|
delmap = curmap;
|
|
/* any children in curent map? */
|
|
found = FALSE;
|
|
for (n = 0; n < map[delmap].numobjects; n++) {
|
|
if (map[delmap].obj[n].child != -1) {
|
|
found = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
if (found) {
|
|
seterror(255);
|
|
sprintf(statustext, "Cannot delete a map with children.");
|
|
drawstatusbar();
|
|
break;
|
|
}
|
|
/* shuffle numbers on all other objects */
|
|
for (n = 0; n < nummaps; n++) {
|
|
int o;
|
|
for (o = 0; o < map[n].numobjects; o++) {
|
|
if (map[n].obj[o].child == delmap) {
|
|
map[n].obj[o].child = -1;
|
|
} else if (map[n].obj[o].child > delmap) {
|
|
map[n].obj[o].child--;
|
|
}
|
|
}
|
|
}
|
|
/* move all higher maps down by one */
|
|
for (n = delmap; n < (nummaps-1); n++) {
|
|
map[n] = map[n+1];
|
|
}
|
|
nummaps--;
|
|
/* move far enough back to avoid all occurences of this map */
|
|
found = FALSE;
|
|
for (n = 0; n < (numhistory-1); n++) {
|
|
if (history[n+1] == delmap) {
|
|
if (history[n] > delmap) {
|
|
changemap(history[n] - 1);
|
|
} else {
|
|
changemap(history[n]);
|
|
}
|
|
numhistory = n+1;
|
|
found = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
if (!found) {
|
|
goback();
|
|
setinfo(255);
|
|
sprintf(statustext, "Deleted map #%d.\n",delmap);
|
|
}
|
|
/* fix history array */
|
|
for (n = 0; n < numhistory; n++) {
|
|
if (history[n] > delmap) {
|
|
history[n]--;
|
|
}
|
|
}
|
|
drawmap(TRUE);
|
|
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(TRUE);
|
|
} else {
|
|
seterror(255);
|
|
sprintf(statustext,"Cannot create map link - no object selected!");
|
|
drawstatusbar();
|
|
}
|
|
break;
|
|
|
|
case TB_DRILLDOWN:
|
|
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();
|
|
}
|
|
break;
|
|
case TB_SAVE:
|
|
startx = 1;
|
|
starty = ((screen->h - STATUSH)/2)-2;
|
|
bg = NULL;
|
|
strcpy(text, currentfilename);
|
|
changestate(S_SAVING);
|
|
drawmap(TRUE);
|
|
break;
|
|
case TB_LOAD:
|
|
startx = 1;
|
|
starty = ((screen->h - STATUSH)/2)-2;
|
|
bg = NULL;
|
|
strcpy(text, currentfilename);
|
|
changestate(S_LOADING);
|
|
drawmap(TRUE);
|
|
break;
|
|
|
|
}
|
|
drawtoolbox();
|
|
} /* end if is on map */
|
|
} else if ((event.button.button == SDL_BUTTON_MIDDLE) ||
|
|
((event.button.button == SDL_BUTTON_LEFT) && (mod & KMOD_CTRL))) {
|
|
if (state == S_DRAWLINK) {
|
|
// finish drawing link
|
|
o = objat(event.button.x + screenx, event.button.y + screeny);
|
|
if ((o != -1) && (o != startobj)) {
|
|
endobj = o;
|
|
endlink(event.button.x,event.button.y);
|
|
changestate(S_NONE);
|
|
drawmap(TRUE);
|
|
} else {
|
|
pasteline(screen,linebg);
|
|
sprintf(statustext,"Aborting link #%d.\n", map[curmap].numlinks);
|
|
drawstatusbar();
|
|
}
|
|
changestate(S_NONE);
|
|
} else if (state == S_NONE) {
|
|
/* are we on a link? if so, add a point to it */
|
|
o = linkat(event.button.x + screenx, event.button.y + screeny);
|
|
if (o != -1) {
|
|
addlinkpoint(o, event.button.x+screenx, event.button.y+screeny);
|
|
/* select the link */
|
|
map[curmap].selecteditemtype = T_LINK;
|
|
map[curmap].selecteditem = o;
|
|
drawmap(TRUE);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
} else if (event.button.button == SDL_BUTTON_RIGHT) {
|
|
if (state == S_RESIZING) {
|
|
// end resize
|
|
endresize(event.button.x, event.button.y);
|
|
changestate(S_NONE);
|
|
drawmap(TRUE);
|
|
} else if (state == S_TEXTRESIZING) {
|
|
// end text resize
|
|
endtextresize(event.button.x, event.button.y);
|
|
changestate(S_NONE);
|
|
}
|
|
/* check for right click on toolbox */
|
|
if (isontoolbox(event.button.x, event.button.y)) {
|
|
int tempx,tempy, selection,boxy;
|
|
|
|
tempx = (event.button.x - toolbox.x) / (toolbox.gridsize+3);
|
|
tempy = (event.button.y - toolbox.y) / (toolbox.gridsize+3);
|
|
boxy = toolbox.y + (tempy*(toolbox.gridsize+3));
|
|
selection = tempy*toolbox.gridrowlen + tempx;
|
|
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 {
|
|
changestate(S_CHANGEOBJECT);
|
|
}
|
|
break;
|
|
case TB_ADDTEXT:
|
|
if (state == S_NONE) {
|
|
if ( (map[curmap].selecteditemtype == T_TEXT) &&
|
|
(map[curmap].selecteditem != -1) ){
|
|
startedittext(map[curmap].selecteditem);
|
|
} else {
|
|
seterror(255);
|
|
sprintf(statustext, "Cannot edit text - no text item selected!");
|
|
drawstatusbar();
|
|
}
|
|
}
|
|
break;
|
|
case TB_GRID:
|
|
changegridsize();
|
|
drawmap(TRUE);
|
|
break;
|
|
case TB_FLOW:
|
|
oldshowflows = showflows;
|
|
showflows = TRUE;
|
|
drawtoolbox();
|
|
changestate(S_DRAWFLOW);
|
|
drawmap(TRUE);
|
|
break;
|
|
case TB_FGCOL:
|
|
changestate(S_FGCOL);
|
|
drawmap(TRUE);
|
|
break;
|
|
case TB_FILLCOL:
|
|
changestate(S_FILLCOL);
|
|
drawmap(TRUE);
|
|
break;
|
|
case TB_MATCHPOS: /* match y */
|
|
if (map[curmap].selecteditem != -1) {
|
|
switch (map[curmap].selecteditemtype) {
|
|
case T_OBJECT:
|
|
case T_TEXT:
|
|
matchtype = map[curmap].selecteditemtype;
|
|
changestate(S_MATCHY);
|
|
drawmap(TRUE);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case TB_LINESTYLE:
|
|
/* figure out where in the box we are */
|
|
if (event.button.y <= (boxy + 9)) {
|
|
changelinethickness(1);
|
|
} else if (event.button.y <= (boxy + 19)) {
|
|
changelinestyle(1);
|
|
} else {
|
|
changelinearrow(1);
|
|
}
|
|
drawstatusbar();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case SDL_MOUSEMOTION:
|
|
switch (state) {
|
|
case S_OBJMOVING:
|
|
updatemoveshadow(event.button.x, event.button.y);
|
|
break;
|
|
case S_RESIZING:
|
|
updateresizeshadow(event.button.x, event.button.y);
|
|
break;
|
|
case S_DRAWLINK:
|
|
updatelinkshadow(event.button.x, event.button.y);
|
|
break;
|
|
case S_TEXTMOVING:
|
|
updatetextshadow(event.button.x, event.button.y);
|
|
break;
|
|
case S_TEXTRESIZING:
|
|
updateresizetextshadow(event.button.x, event.button.y);
|
|
break;
|
|
case S_LINKPOINTMOVE:
|
|
updatelinkpointshadow(event.button.x, event.button.y);
|
|
break;
|
|
case S_NONE:
|
|
/* has mouse moved since last time? */
|
|
mousepos = getmousepos(event.button.x, event.button.y);
|
|
if ((mousepos != oldmousepos ) || (mousepos== MP_TOOLBOX)) {
|
|
/* rollovers */
|
|
if (mousepos == MP_TOOLBOX) {
|
|
SDL_Rect area;
|
|
int tempx,tempy, selection;
|
|
int boxy;
|
|
|
|
if (!rollover) strcpy(oldstatustext, statustext);
|
|
rollover = TRUE;
|
|
|
|
/* determine which button we're over */
|
|
tempx = (event.button.x - toolbox.x) / (toolbox.gridsize+3);
|
|
tempy = (event.button.y - toolbox.y) / (toolbox.gridsize+3);
|
|
|
|
boxy = toolbox.y + (tempy*(toolbox.gridsize+3));
|
|
|
|
selection = tempy*toolbox.gridrowlen + tempx;
|
|
/* replace old button */
|
|
if (toolbg != NULL) {
|
|
SDL_Rect area;
|
|
|
|
|
|
if (oldselection >= 0) {
|
|
if (dontpaste == FALSE) {
|
|
area.x = toolbox.x + ((oldselection % 3 )*(toolbox.gridsize+3));
|
|
area.y = toolbox.y + ((oldselection / 3)*(toolbox.gridsize+3));
|
|
area.w = toolbox.gridsize;
|
|
area.h = toolbox.gridsize;
|
|
SDL_BlitSurface(toolbg, NULL, screen, &area);
|
|
SDL_UpdateRect(screen, area.x, area.y, area.w, area.h);
|
|
} else {
|
|
dontpaste = FALSE;
|
|
}
|
|
}
|
|
SDL_FreeSurface(toolbg);
|
|
toolbg = NULL;
|
|
}
|
|
/* copy background of this button */
|
|
if (selection <= TB_SAVE) {
|
|
toolbg = SDL_CreateRGBSurface(SDL_SWSURFACE,toolbox.gridsize+3, toolbox.gridsize+3,
|
|
screen->format->BitsPerPixel, screen->format->Rmask,
|
|
screen->format->Gmask,screen->format->Bmask,
|
|
screen->format->Amask);
|
|
area.x = toolbox.x + ((selection % 3 )*(toolbox.gridsize+3));
|
|
area.y = toolbox.y + ((selection / 3)*(toolbox.gridsize+3));
|
|
area.w = toolbox.gridsize+1;
|
|
area.h = toolbox.gridsize+1;
|
|
SDL_BlitSurface(screen,&area, toolbg, 0);
|
|
|
|
/* draw highlight */
|
|
if (selection == TB_LINESTYLE) {
|
|
SDL_Rect sarea;
|
|
|
|
if (event.button.y <= (boxy + 9)) {
|
|
sarea.x = 0;
|
|
sarea.y = 0;
|
|
sarea.w = toolbox.gridsize;
|
|
sarea.h = 11;
|
|
area.h = 11;
|
|
area.y += 1;
|
|
} else if (event.button.y <= (boxy + 19)) {
|
|
sarea.x = 0;
|
|
sarea.y = 0;
|
|
sarea.w = toolbox.gridsize;
|
|
sarea.h = 10;
|
|
area.h = 10;
|
|
area.y += 12;
|
|
} else {
|
|
sarea.x = 0;
|
|
sarea.y = 0;
|
|
sarea.w = toolbox.gridsize;
|
|
sarea.h = 8;
|
|
area.h = 8;
|
|
area.y += 21;
|
|
}
|
|
SDL_BlitSurface(toolhilite, &sarea, screen, &area);
|
|
} else {
|
|
SDL_BlitSurface(toolhilite, NULL, screen, &area);
|
|
}
|
|
|
|
SDL_UpdateRect(screen, area.x, area.y, area.w, area.h);
|
|
}
|
|
|
|
if (selection != oldselection) {
|
|
switch (selection) {
|
|
case TB_POINTER:
|
|
sprintf(statustext, "LMB = Enter object selection mode");
|
|
drawstatusbar();
|
|
break;
|
|
case TB_ADDOBJ:
|
|
sprintf(statustext, "LMB = Add an object to the map, RMB = Change object type");
|
|
drawstatusbar();
|
|
break;
|
|
case TB_ADDTEXT:
|
|
sprintf(statustext, "LMB (on map) = Add text to the map, LMB (on object) = Add text to an object");
|
|
drawstatusbar();
|
|
break;
|
|
case TB_COPY:
|
|
sprintf(statustext, "LMB = Copy the current object/text/map");
|
|
drawstatusbar();
|
|
break;
|
|
case TB_PASTE:
|
|
sprintf(statustext, "LMB = Paste the current copy buffer");
|
|
drawstatusbar();
|
|
break;
|
|
case TB_GRID:
|
|
sprintf(statustext, "LMB = Toggle grid on/off, RMB = Change grid size");
|
|
drawstatusbar();
|
|
break;
|
|
case TB_FGCOL:
|
|
sprintf(statustext, "LMB = Apply default foreground colour to current selection, RMB = Change default foreground colour");
|
|
drawstatusbar();
|
|
break;
|
|
case TB_FILLCOL:
|
|
sprintf(statustext, "LMB = Apply default fill colour to current selection, RMB = Change default fill colour");
|
|
drawstatusbar();
|
|
break;
|
|
case TB_LINESTYLE:
|
|
if (event.button.y <= (boxy + 9)) {
|
|
sprintf(statustext, "LMB = Apply default thickness to current line, RMB = Change default line thickness");
|
|
} else if (event.button.y <= (boxy + 19)) {
|
|
sprintf(statustext, "LMB = Apply default style to current line, RMB = Change default line style");
|
|
} else {
|
|
sprintf(statustext, "LMB = Apply default arrowhead type to current line, RMB = Change default arrowhead type");
|
|
}
|
|
drawstatusbar();
|
|
break;
|
|
case TB_MATCHSIZE:
|
|
sprintf(statustext, "LMB = Match size of current selection to next item clicked");
|
|
drawstatusbar();
|
|
break;
|
|
case TB_MATCHPOS:
|
|
sprintf(statustext, "LMB = Match horizontal position of currently selected item to next item clicked, RMB = match vertical position");
|
|
drawstatusbar();
|
|
break;
|
|
case TB_FLOW:
|
|
sprintf(statustext, "LMB = Toggle display of traffic flows, RMB = Enter traffic flow definition mode");
|
|
drawstatusbar();
|
|
break;
|
|
case TB_DRILLDOWN:
|
|
sprintf(statustext, "LMB = Drill down to create new map under current object");
|
|
drawstatusbar();
|
|
break;
|
|
case TB_CREATETELE:
|
|
sprintf(statustext, "LMB = Set destination map for when current object is double-clicked");
|
|
drawstatusbar();
|
|
break;
|
|
case TB_DELETEMAP:
|
|
sprintf(statustext, "LMB = Delete current map (hold down SHIFT to confirm)");
|
|
drawstatusbar();
|
|
break;
|
|
case TB_NEW:
|
|
sprintf(statustext, "LMB = Delete ALL maps and start a fresh project (hold SHIFT to confirm)");
|
|
drawstatusbar();
|
|
break;
|
|
case TB_LOAD:
|
|
sprintf(statustext, "LMB = Load a new map");
|
|
drawstatusbar();
|
|
break;
|
|
case TB_SAVE:
|
|
sprintf(statustext, "LMB = Save the current map to disk (will automatically export based on extensions of BMP/PNG/SVG)");
|
|
drawstatusbar();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
oldselection = selection;
|
|
} else if (mousepos == MP_MAPBOXNAME) {
|
|
if (!rollover) strcpy(oldstatustext, statustext);
|
|
rollover = TRUE;
|
|
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 (blue text indicates maps already in the map history).");
|
|
drawstatusbar();
|
|
} else if (mousepos == MP_OBJECTBOX) {
|
|
if (!rollover) strcpy(oldstatustext, statustext);
|
|
rollover = TRUE;
|
|
sprintf(statustext, "LMB = Select a new object type.");
|
|
drawstatusbar();
|
|
} else {
|
|
strcpy(statustext, oldstatustext);
|
|
strcpy(oldstatustext, "");
|
|
drawstatusbar();
|
|
rollover = FALSE;
|
|
}
|
|
}
|
|
oldmousepos = mousepos;
|
|
break;
|
|
|
|
}
|
|
/* scrollbar drags */
|
|
mb = SDL_GetMouseState(&mx,&my);
|
|
//if (isonxscrollbar(mx,my)) {
|
|
if (state == S_XSCROLL) {
|
|
if (mb & SDL_BUTTON(1)) { /* if lmb is depressed */
|
|
screenx = (((double)event.button.x / (double)(screen->w - SIDEBARW)) * map[curmap].width)
|
|
- ((screen->w - SIDEBARW)/2);
|
|
|
|
validatescreenpos();
|
|
drawxscrollbar();
|
|
}
|
|
}
|
|
//if (isonyscrollbar(mx,my)) {
|
|
if (state == S_YSCROLL) {
|
|
if (mb & SDL_BUTTON(1)) { /* if lmb is depressed */
|
|
screeny = (((double)event.button.y / (double)(screen->h - STATUSH - SBSIZE)) * map[curmap].height)
|
|
- ((screen->h - STATUSH - SBSIZE)/2);
|
|
|
|
validatescreenpos();
|
|
drawyscrollbar();
|
|
}
|
|
}
|
|
break;
|
|
case SDL_QUIT:
|
|
if (modified) {
|
|
strcpy(text, "Changes not saved - really quit?");
|
|
changestate(S_REALLYQUIT);
|
|
drawmap(TRUE);
|
|
} else {
|
|
done = TRUE;
|
|
}
|
|
break;
|
|
case SDL_VIDEOEXPOSE:
|
|
/* redraw screen */
|
|
drawscreen();
|
|
break;
|
|
case SDL_KEYDOWN:
|
|
c = event.key.keysym.unicode & 0x7F;
|
|
c2 = event.key.keysym.sym;
|
|
mod = SDL_GetModState();
|
|
/* state independant */
|
|
if (mod & KMOD_SHIFT) {
|
|
if ((c >= 'a') && (c <= 'z')) {
|
|
c -= 32;
|
|
} else if (c == '1') {
|
|
c = '!';
|
|
} else if (c == '2') {
|
|
c = '@';
|
|
} else if (c == '3') {
|
|
c = '#';
|
|
} else if (c == '4') {
|
|
c = '$';
|
|
} else if (c == '5') {
|
|
c = '%';
|
|
} else if (c == '6') {
|
|
c = '^';
|
|
} else if (c == '7') {
|
|
c = '&';
|
|
} else if (c == '8') {
|
|
c = '*';
|
|
} else if (c == '9') {
|
|
c = '(';
|
|
} else if (c == '0') {
|
|
c = ')';
|
|
} else if (c == '-') {
|
|
c = '_';
|
|
} else if (c == '=') {
|
|
c = '+';
|
|
} else if (c == '\\') {
|
|
c = '|';
|
|
} else if (c == ';') {
|
|
c = ':';
|
|
} else if (c == '\'') {
|
|
c = '"';
|
|
} else if (c == ',') {
|
|
c = '<';
|
|
} else if (c == '.') {
|
|
c = '>';
|
|
} else if (c == '/') {
|
|
c = '?';
|
|
}
|
|
}
|
|
/* state dependant */
|
|
if ((state == S_TYPETEXT) || (state == S_SAVING) || (state == S_LOADING) || (state == S_MAPNAMING) || (state == S_EDITTEXT) || (state == S_SEARCH)) {
|
|
// ooooooooooooooo
|
|
if ((c2 == 'u') && (mod & KMOD_CTRL)) {
|
|
// delete from start to text pos
|
|
strcpy(text, textpos);
|
|
//text[0] = '\0';
|
|
textpos = text;
|
|
updatetextcursor();
|
|
} else if ((c2 == 'k') && (mod & KMOD_CTRL)) {
|
|
// delete from here to end
|
|
*textpos = '\0';
|
|
updatetextcursor();
|
|
} else if ((c2 == 'a') && (mod & KMOD_CTRL)) {
|
|
// go to start of text
|
|
textpos = text;
|
|
updatetextcursor();
|
|
} else if ((c2 == 'e') && (mod & KMOD_CTRL)) {
|
|
// go to end of text
|
|
textpos = &text[strlen(text)];
|
|
updatetextcursor();
|
|
} else if ((c >= FIRSTLET) && (c <= LASTLET)) {
|
|
// add onto end of text
|
|
char temptext[2];
|
|
char endbit[BUFLEN];
|
|
// remember from here until end
|
|
if (textpos) {
|
|
strcpy(endbit, textpos);
|
|
} else {
|
|
endbit[0] = '\0';
|
|
}
|
|
// end here
|
|
*textpos = '\0';
|
|
// append char
|
|
sprintf(temptext, "%c", c);
|
|
strcat(text, temptext);
|
|
// move cursor to end of appended bit
|
|
textpos = &text[strlen(text)];
|
|
// append end bit
|
|
if (strlen(endbit) > 0) {
|
|
strcat(text, endbit);
|
|
}
|
|
//
|
|
updatetextcursor();
|
|
} else if (c2 == SDLK_LEFT) {
|
|
// move cursor
|
|
if (textpos != text) textpos--;
|
|
updatetextcursor();
|
|
} else if (c2 == SDLK_RIGHT) {
|
|
if (textpos != &text[strlen(text)]) textpos++;
|
|
updatetextcursor();
|
|
//oooooooooo
|
|
} else if (c2 == SDLK_ESCAPE) {
|
|
sprintf(statustext, "Aborted.");
|
|
changestate(S_NONE);
|
|
drawmap(TRUE);
|
|
} else if (c == ' ') {
|
|
// add onto end of text
|
|
char endbit[BUFLEN];
|
|
// remember from here until end
|
|
strcpy(endbit, textpos);
|
|
// end here
|
|
*textpos = '\0';
|
|
// append char
|
|
strcat(text, " ");
|
|
// move cursor to end of appended bit
|
|
textpos = &text[strlen(text)];
|
|
// append end bit
|
|
strcat(text, endbit);
|
|
updatetextcursor();
|
|
} else if (c2 == SDLK_BACKSPACE) {
|
|
// remove last charater
|
|
if (textpos != text) {
|
|
strcpy(textpos-1, textpos);
|
|
}
|
|
//text[strlen(text)-1] = '\0';
|
|
textpos--;
|
|
updatetextcursor();
|
|
} else if (c == 13) { /* enter */
|
|
if (state == S_TYPETEXT) {
|
|
endtext();
|
|
} else if (state == S_EDITTEXT) {
|
|
endtextedit();
|
|
} else if (state == S_SAVING) {
|
|
savemap();
|
|
changestate(S_NONE);
|
|
drawmap(TRUE);
|
|
} else if (state == S_LOADING) {
|
|
loadmap();
|
|
changestate(S_NONE);
|
|
drawmap(TRUE);
|
|
} else if (state == S_SEARCH) {
|
|
changestate(S_NONE);
|
|
if (dosearch()) {
|
|
seterror(255);
|
|
sprintf(statustext, "Not found: '%s'",searchtext);
|
|
setsearchflash(0);
|
|
} else {
|
|
setinfo(255);
|
|
sprintf(statustext, "Found '%s' in text object #%d (map '%s')",searchtext, map[curmap].selecteditem, map[curmap].name);
|
|
setsearchflash(255);
|
|
}
|
|
drawmap(TRUE);
|
|
} 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(TRUE);
|
|
}
|
|
}
|
|
} else {
|
|
if (c2 == SDLK_HOME) {
|
|
screenx = 0;
|
|
screeny = 0;
|
|
drawmap(TRUE);
|
|
}
|
|
if (c2 == SDLK_END) {
|
|
screenx = map[curmap].width - (screen->w-SIDEBARW);
|
|
screeny = map[curmap].height - (screen->h-STATUSH);
|
|
drawmap(TRUE);
|
|
}
|
|
if (c == 'a') { /* add map[curmap].object */
|
|
if (state == S_NONE) {
|
|
changestate(S_ADDOBJ);
|
|
}
|
|
}
|
|
if (c == '/') { /* search/find */
|
|
if (state == S_NONE) {
|
|
startx = 1;
|
|
starty = ((screen->h-STATUSH)/2)-2;
|
|
bg = NULL;
|
|
strcpy(text, "");
|
|
changestate(S_SEARCH);
|
|
drawmap(TRUE);
|
|
}
|
|
}
|
|
if (c == 'n') { /* find next */
|
|
changestate(S_NONE);
|
|
if (dosearchnext()) {
|
|
seterror(255);
|
|
sprintf(statustext, "Not foundnext: '%s'",searchtext);
|
|
setsearchflash(0);
|
|
} else {
|
|
setinfo(255);
|
|
sprintf(statustext, "Foundnext %s'%s' in text object #%d (map '%s')",searchwrap ? "(wrapped) " : "",searchtext, map[curmap].selecteditem, map[curmap].name);
|
|
setsearchflash(255);
|
|
}
|
|
drawmap(TRUE);
|
|
}
|
|
if (c == 'm') { /* modify object type */
|
|
if (state == S_NONE) {
|
|
changestate(S_CHANGEOBJECT);
|
|
}
|
|
}
|
|
if (c == 't') { /* add text */
|
|
if (state == S_NONE) {
|
|
changestate(S_ADDTEXT);
|
|
}
|
|
}
|
|
if ((c == 'e') || (c2 == SDLK_F2)) { /* edit current text */
|
|
if (state == S_NONE) {
|
|
if ( (map[curmap].selecteditemtype == T_TEXT) &&
|
|
(map[curmap].selecteditem != -1) ){
|
|
startedittext(map[curmap].selecteditem);
|
|
} else {
|
|
seterror(255);
|
|
sprintf(statustext, "Cannot edit text - no text item selected!");
|
|
drawstatusbar();
|
|
}
|
|
}
|
|
}
|
|
if (c == 's') { /* save */
|
|
startx = 1;
|
|
starty = ((screen->h-STATUSH)/2)-2;
|
|
bg = NULL;
|
|
strcpy(text, currentfilename);
|
|
textpos = &text[strlen(text)];
|
|
changestate(S_SAVING);
|
|
drawmap(TRUE);
|
|
}
|
|
if ((c == 'l') || (c == 'o')) { /* load, open */
|
|
startx = 1;
|
|
starty = ((screen->h-STATUSH)/2)-2;
|
|
bg = NULL;
|
|
strcpy(text, currentfilename);
|
|
textpos = &text[strlen(text)];
|
|
changestate(S_LOADING);
|
|
drawmap(TRUE);
|
|
}
|
|
if ((c == ',') || (c == 'q')) { /* scroll object box up */
|
|
if (state == S_CREATETELE) {
|
|
scrollmaplist(-1);
|
|
} else {
|
|
scrollobox(-1);
|
|
}
|
|
}
|
|
if ((c == '.') || (c == 'w')) { /* scroll object box down */
|
|
if (state == S_CREATETELE) {
|
|
scrollmaplist(1);
|
|
} else {
|
|
scrollobox(1);
|
|
}
|
|
}
|
|
if ((c == '<') || (c == 'Q')) { /* scroll object box up */
|
|
if (state == S_CREATETELE) {
|
|
scrollmaplist(-20);
|
|
} else {
|
|
scrollobox(-OBOXPAGESIZE);
|
|
}
|
|
}
|
|
if ((c == '>') || (c == 'W')) { /* scroll object box down */
|
|
if (state == S_CREATETELE) {
|
|
scrollmaplist(20);
|
|
} else {
|
|
scrollobox(OBOXPAGESIZE);
|
|
}
|
|
}
|
|
if (c == 'x') {
|
|
if (map[curmap].selecteditem != -1) {
|
|
switch (map[curmap].selecteditemtype) {
|
|
case T_OBJECT:
|
|
case T_TEXT:
|
|
matchtype = map[curmap].selecteditemtype;
|
|
changestate(S_MATCHX);
|
|
drawmap(TRUE);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (c == 'y') {
|
|
if (map[curmap].selecteditem != -1) {
|
|
switch (map[curmap].selecteditemtype) {
|
|
case T_OBJECT:
|
|
case T_TEXT:
|
|
matchtype = map[curmap].selecteditemtype;
|
|
changestate(S_MATCHY);
|
|
drawmap(TRUE);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (c == 'b') {
|
|
if (map[curmap].selecteditem != -1) {
|
|
switch (map[curmap].selecteditemtype) {
|
|
case T_OBJECT:
|
|
case T_TEXT:
|
|
matchtype = map[curmap].selecteditemtype;
|
|
changestate(S_MATCHSIZE);
|
|
drawmap(TRUE);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (c == 'g') { /* toggle snap-to-grid */
|
|
togglegrid();
|
|
drawtoolbox();
|
|
}
|
|
if (c == ';') { /* change gridsize */
|
|
changegridsize();
|
|
drawmap(TRUE);
|
|
}
|
|
if (c == 'c') { /* copy */
|
|
copy();
|
|
}
|
|
if (c == 'd') { /* drill down */
|
|
if (state == S_NONE) {
|
|
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();
|
|
}
|
|
}
|
|
if (c == 'f') {
|
|
if (showflows) {
|
|
showflows = FALSE;
|
|
setinfo(255);
|
|
sprintf(statustext, "Traffic flows hidden.");
|
|
} else {
|
|
setinfo(255);
|
|
sprintf(statustext, "Traffic flows displayed.");
|
|
showflows = TRUE;
|
|
}
|
|
drawtoolbox();
|
|
drawmap(TRUE);
|
|
}
|
|
if ((c == 'p') || (c == 'v')) { /* paste */
|
|
paste();
|
|
}
|
|
/* keyboard shortcuts */
|
|
if ((c >= '0') && (c <= '9')) {
|
|
int mx,my;
|
|
int onum;
|
|
|
|
onum = c - '0';
|
|
|
|
SDL_GetMouseState(&mx, &my);
|
|
if (isonobox(mx, my)) {
|
|
int seltype, tempx, tempy;
|
|
/* define shortcut */
|
|
tempx = (mx - obox.x) / (obox.gridsize+3);
|
|
tempy = (my - obox.y) / (obox.gridsize+3);
|
|
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();
|
|
} else {
|
|
/* select shortcut */
|
|
int fitx, fity, fit;
|
|
/* select object */
|
|
map[curmap].selectedtype = shortcut[onum];
|
|
/* these two should never happen... */
|
|
if (map[curmap].selectedtype < 0 ) map[curmap].selectedtype = 0;
|
|
if (map[curmap].selectedtype >= numobjtypes) map[curmap].selectedtype = numobjtypes-1;
|
|
/* ensure that object is visible */
|
|
fitx = (obox.width / obox.gridsize);
|
|
fity = ((obox.height+3) / obox.gridsize);
|
|
fit = fitx * fity;
|
|
|
|
/* scroll object box to make it visible */
|
|
while (shortcut[onum] < (obox.pos*fitx)) {
|
|
obox.pos--;
|
|
}
|
|
while (shortcut[onum] > ((obox.pos*fitx) + fit)) {
|
|
obox.pos++;
|
|
}
|
|
|
|
sprintf(statustext,"Object type shortcut #%d ('%s') selected.\n",onum, objtype[map[curmap].selectedtype].name);
|
|
drawstatusbar();
|
|
drawobox();
|
|
}
|
|
}
|
|
if (c2 == SDLK_BACKSPACE) {
|
|
goback();
|
|
}
|
|
if (c2 == SDLK_PAGEUP) {
|
|
scrollobox(-OBOXPAGESIZE);
|
|
}
|
|
if (c2 == SDLK_PAGEDOWN) {
|
|
scrollobox(OBOXPAGESIZE);
|
|
}
|
|
if (c2 == SDLK_DELETE) {
|
|
if (map[curmap].selecteditem != -1) {
|
|
if (map[curmap].selecteditemtype == T_LINKPOINT) {
|
|
int i;
|
|
for (i = map[curmap].selectedlinkpoint; i < (map[curmap].olink[map[curmap].selecteditem].npoints-1); i++) {
|
|
map[curmap].olink[map[curmap].selecteditem].point[i].x = map[curmap].olink[map[curmap].selecteditem].point[i+1].x;
|
|
map[curmap].olink[map[curmap].selecteditem].point[i].y = map[curmap].olink[map[curmap].selecteditem].point[i+1].y;
|
|
}
|
|
map[curmap].olink[map[curmap].selecteditem].npoints--;
|
|
|
|
/* move selection to next point on same line */
|
|
if (map[curmap].olink[map[curmap].selecteditem].npoints > 0) {
|
|
if (map[curmap].selectedlinkpoint >= map[curmap].olink[map[curmap].selecteditem].npoints) {
|
|
map[curmap].selectedlinkpoint = map[curmap].olink[map[curmap].selecteditem].npoints-1;
|
|
}
|
|
} else {
|
|
/* deselect point (leave link selected) */
|
|
map[curmap].selectedlinkpoint = -1;
|
|
map[curmap].selecteditemtype = T_LINK;
|
|
}
|
|
|
|
sprintf(statustext, "Deleted link #%d point #%d.",map[curmap].selecteditem,map[curmap].selectedlinkpoint);
|
|
drawmap(TRUE);
|
|
} else {
|
|
deletething(map[curmap].selecteditem,map[curmap].selecteditemtype);
|
|
}
|
|
}
|
|
}
|
|
if (map[curmap].selecteditem != -1) {
|
|
if (c == ']') { /* raise */
|
|
int amt;
|
|
|
|
tmod = SDL_GetModState();
|
|
if ((tmod & KMOD_SHIFT)) {
|
|
amt = (map[curmap].numthings / MULTIRAISENUM);
|
|
} else amt = 1;
|
|
|
|
/* raise the selected map[curmap].object */
|
|
raiseselected(amt);
|
|
}
|
|
if (c == '[') { /* lower */
|
|
int amt;
|
|
|
|
tmod = SDL_GetModState();
|
|
if ((tmod & KMOD_SHIFT)) {
|
|
amt = (map[curmap].numthings / MULTIRAISENUM);
|
|
} else amt = 1;
|
|
|
|
/* lower the selected map[curmap].object */
|
|
lowerselected(amt);
|
|
}
|
|
if (c == '{') { /* lower by lots */
|
|
int amt = (map[curmap].numthings / MULTIRAISENUM);
|
|
lowerselected(amt);
|
|
}
|
|
if (c == '}') { /* raise by lots */
|
|
int amt = (map[curmap].numthings / MULTIRAISENUM);
|
|
raiseselected(amt);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (infoflash || errorflash) {
|
|
if (!SDL_PollEvent(&event)) isevent = FALSE;
|
|
} else {
|
|
isevent = FALSE;
|
|
}
|
|
}
|
|
|
|
} /* end main loop */
|
|
|
|
return 0;
|
|
}
|
|
|
|
void addlinkpoint(int linkid, int x, int y) {
|
|
int pos;
|
|
int i;
|
|
|
|
pos = findpointpos(&map[curmap].olink[linkid],x,y);
|
|
|
|
map[curmap].olink[linkid].npoints++;
|
|
|
|
/* shuffle points from that point upwards */
|
|
for (i = (map[curmap].olink[linkid].npoints-1);i > pos ; i--) {
|
|
map[curmap].olink[linkid].point[i] = map[curmap].olink[linkid].point[i-1];
|
|
}
|
|
|
|
map[curmap].olink[linkid].point[pos].x = x;
|
|
map[curmap].olink[linkid].point[pos].y = y;
|
|
|
|
setmod(TRUE);
|
|
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) {
|
|
|
|
if ((vimg->vnum + 1) >= MAXVECTORSPERIMAGE) return TRUE;
|
|
vimg->vector[vimg->vnum].type = type;
|
|
vimg->vector[vimg->vnum].x1 = x1;
|
|
vimg->vector[vimg->vnum].y1 = y1;
|
|
vimg->vector[vimg->vnum].x2 = x2;
|
|
vimg->vector[vimg->vnum].y2 = y2;
|
|
vimg->vector[vimg->vnum].c.r = c->r;
|
|
vimg->vector[vimg->vnum].c.g = c->g;
|
|
vimg->vector[vimg->vnum].c.b = c->b;
|
|
vimg->vector[vimg->vnum].c.unused = 0;
|
|
if (fc == NULL) {
|
|
vimg->vector[vimg->vnum].fc.r = 0;
|
|
vimg->vector[vimg->vnum].fc.g = 0;
|
|
vimg->vector[vimg->vnum].fc.b = 0;
|
|
vimg->vector[vimg->vnum].fc.unused = 0;
|
|
} else {
|
|
vimg->vector[vimg->vnum].fc.r = fc->r;
|
|
vimg->vector[vimg->vnum].fc.g = fc->g;
|
|
vimg->vector[vimg->vnum].fc.b = fc->b;
|
|
vimg->vector[vimg->vnum].fc.unused = fc->unused;
|
|
}
|
|
vimg->vnum = vimg->vnum + 1;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
void calcmapdimensions(void) {
|
|
int thismaxx,thismaxy; /* used to calculate map size */
|
|
int maxx = -1,maxy = -1; /* used to calculate map size */
|
|
int i;
|
|
|
|
/* draw all map[curmap].objects links etc*/
|
|
for (i = 0; i < map[curmap].numthings; i++) {
|
|
if (map[curmap].thing[i].type == T_OBJECT) {
|
|
/* calculate max map size */
|
|
thismaxx = map[curmap].obj[map[curmap].thing[i].id].x + map[curmap].obj[map[curmap].thing[i].id].w;
|
|
thismaxy = map[curmap].obj[map[curmap].thing[i].id].y + map[curmap].obj[map[curmap].thing[i].id].h;
|
|
if (thismaxx > maxx) maxx = thismaxx;
|
|
if (thismaxy > maxy) maxy = thismaxy;
|
|
} else if (map[curmap].thing[i].type == T_LINK) {
|
|
int p;
|
|
thismaxx = -1;
|
|
thismaxy = -1;
|
|
for (p = 0; p < map[curmap].olink[map[curmap].thing[i].id].npoints; p++) {
|
|
if (map[curmap].olink[map[curmap].thing[i].id].point[p].x > thismaxx)
|
|
thismaxx = map[curmap].olink[map[curmap].thing[i].id].point[p].x;
|
|
if (map[curmap].olink[map[curmap].thing[i].id].point[p].y > thismaxy)
|
|
thismaxy = map[curmap].olink[map[curmap].thing[i].id].point[p].y;
|
|
}
|
|
/* calculate max map size */
|
|
if (thismaxx > maxx) maxx = thismaxx;
|
|
if (thismaxy > maxy) maxy = thismaxy;
|
|
} else if (map[curmap].thing[i].type == T_TEXT) {
|
|
/* calculate max map size */
|
|
thismaxx = map[curmap].textob[map[curmap].thing[i].id].x + map[curmap].textob[map[curmap].thing[i].id].w;
|
|
thismaxy = map[curmap].textob[map[curmap].thing[i].id].y + map[curmap].textob[map[curmap].thing[i].id].h;
|
|
if (thismaxx > maxx) maxx = thismaxx;
|
|
if (thismaxy > maxy) maxy = thismaxy;
|
|
} else {
|
|
printf("WARNING: Thing #%d has unknown type %d!\n",i,map[curmap].thing[i].type);
|
|
}
|
|
}
|
|
|
|
/* set map dimensions - automatically grow/shrink to be a bit bigger than required size */
|
|
if (maxx <= (map[curmap].width - 300)) map[curmap].width = maxx + 100;
|
|
if (maxy <= (map[curmap].height - 300)) map[curmap].height = maxx + 100;
|
|
if (maxx+200 > map[curmap].width) map[curmap].width = maxx + 200;
|
|
if (maxy+200 > map[curmap].height) map[curmap].height = maxy + 200;
|
|
|
|
/* make sure map is always at least as big as the visible screen size */
|
|
if (map[curmap].width < screen->w - SIDEBARW) map[curmap].width = screen->w - SIDEBARW;
|
|
if (map[curmap].height < screen->h - STATUSH) map[curmap].height = screen->h - STATUSH;
|
|
|
|
|
|
|
|
/* determine position of sidebar */
|
|
obox.x = screen->w - SIDEBARW;
|
|
obox.y = ((screen->h / 4) * 3) - 10;
|
|
obox.width = SIDEBARW;
|
|
obox.height = screen->h - obox.y;
|
|
obox.bgcol = black;
|
|
obox.gridbgcol = grey;
|
|
obox.gridcol = grey;
|
|
obox.gridsize = 30;
|
|
obox.gridrowlen = SIDEBARW / obox.gridsize;
|
|
|
|
toolbox.x = screen->w - SIDEBARW;
|
|
toolbox.y = 0;
|
|
toolbox.width = SIDEBARW;
|
|
toolbox.height = screen->h / 3;
|
|
toolbox.bgcol = black;
|
|
toolbox.gridsize = 30;
|
|
toolbox.gridrowlen = SIDEBARW / toolbox.gridsize;
|
|
|
|
mapbox.x = screen->w - SIDEBARW;
|
|
mapbox.y = toolbox.y+toolbox.height+10;
|
|
mapbox.width = SIDEBARW;
|
|
mapbox.height = obox.y - mapbox.y - 20;
|
|
mapbox.offset = 0;
|
|
|
|
}
|
|
|
|
int setgridsize(int size) {
|
|
int n;
|
|
for (n = 0; n < gridsizenum; n++) {
|
|
if (gridsizelist[n] == size) {
|
|
gridsizeindex = n;
|
|
gridsize = gridsizelist[n];
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void changegridsize(void) {
|
|
if (++gridsizeindex >= gridsizenum) {
|
|
gridsizeindex = 0;
|
|
}
|
|
gridsize = gridsizelist[gridsizeindex];
|
|
setinfo(255);
|
|
sprintf(statustext, "Grid size set to %d.", gridsize);
|
|
}
|
|
|
|
void changelinearrow(int changeby) {
|
|
|
|
if ((changeby < 0) && (defarrow == 0)) {
|
|
defarrow = AP_BOTH;
|
|
} else {
|
|
defarrow += changeby;
|
|
}
|
|
|
|
/* wrap around */
|
|
if (defarrow > AP_BOTH) defarrow = 0;
|
|
|
|
/* change arrow style on currently selected line */
|
|
if (map[curmap].selecteditemtype == T_LINK) {
|
|
if (map[curmap].selecteditem != -1) {
|
|
map[curmap].olink[map[curmap].selecteditem].style &= 0x00ffff;
|
|
map[curmap].olink[map[curmap].selecteditem].style |= (defarrow << 16);
|
|
setmod(TRUE);
|
|
drawmap(TRUE);
|
|
}
|
|
}
|
|
|
|
/* redraw toolbox */
|
|
drawtoolbox();
|
|
}
|
|
|
|
void changelinestyle(int changeby) {
|
|
if ((changeby < 0) && (defstyle == 0)) {
|
|
defstyle = MAXLINESTYLE - 1;
|
|
} else {
|
|
defstyle += changeby;
|
|
}
|
|
/* wrap around */
|
|
if (defstyle >= MAXLINESTYLE) defstyle = 0;
|
|
|
|
/* change line style of currently selected line */
|
|
if (map[curmap].selecteditemtype == T_LINK) {
|
|
if (map[curmap].selecteditem != -1) {
|
|
map[curmap].olink[map[curmap].selecteditem].style &= 0xff00ff;
|
|
map[curmap].olink[map[curmap].selecteditem].style |= (defstyle << 8);
|
|
setmod(TRUE);
|
|
drawmap(TRUE);
|
|
}
|
|
}
|
|
|
|
/* redraw toolbox */
|
|
drawtoolbox();
|
|
}
|
|
|
|
void changelinethickness(int changeby) {
|
|
defthickness += changeby;
|
|
/* wrap around */
|
|
if (defthickness <= 0) defthickness = 5;
|
|
if (defthickness > 5) defthickness = 1;
|
|
|
|
/* change thickness of currently selected line */
|
|
if (map[curmap].selecteditemtype == T_LINK) {
|
|
if (map[curmap].selecteditem != -1) {
|
|
map[curmap].olink[map[curmap].selecteditem].style &= 0xffff00;
|
|
map[curmap].olink[map[curmap].selecteditem].style |= defthickness;
|
|
setmod(TRUE);
|
|
drawmap(TRUE);
|
|
}
|
|
}
|
|
|
|
/* redraw toolbox */
|
|
drawtoolbox();
|
|
}
|
|
|
|
void changemap(int newmap) {
|
|
map[newmap].selecteditem = -1;
|
|
map[newmap].selecteditemtype = -1;
|
|
/*map[newmap].selectedtype = map[curmap].selectedtype; */
|
|
curmap = newmap;
|
|
}
|
|
|
|
void changestate(int newstate) {
|
|
int oldstate;
|
|
|
|
oldstate = state;
|
|
/* can't do most things in readonly mode */
|
|
if (readonly) {
|
|
switch (newstate) {
|
|
case S_NONE:
|
|
case S_LOADING:
|
|
case S_REALLYQUIT:
|
|
break;
|
|
default:
|
|
newstate = S_NONE;
|
|
break;
|
|
}
|
|
}
|
|
if (newstate != state) {
|
|
if (oldstate == S_DRAWFLOW) {
|
|
showflows = oldshowflows;
|
|
}
|
|
if ((state == S_ADDOBJ) || (state == S_ADDTEXT)) {
|
|
/* change mouse back to normal */
|
|
SDL_SetCursor(normalmouse);
|
|
}
|
|
if (newstate == S_ADDOBJ) SDL_SetCursor(objmouse);
|
|
if (newstate == S_ADDTEXT) SDL_SetCursor(textmouse);
|
|
|
|
state = newstate;
|
|
if (oldstate == S_DRAWFLOW) {
|
|
drawmap(TRUE);
|
|
}
|
|
drawtoolbox();
|
|
switch (state) {
|
|
case S_NONE:
|
|
//sprintf(statustext,"Selection mode enabled.\n"); fflush(STDOUT);
|
|
if (oldstate == S_DRAWFLOW) {
|
|
sprintf(statustext,"Traffic flow definition complete.");
|
|
}
|
|
break;
|
|
case S_ADDOBJ:
|
|
sprintf(statustext,"Object creation mode enabled.\n");
|
|
break;
|
|
case S_CHANGEOBJECT:
|
|
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");
|
|
break;
|
|
case S_TYPETEXT:
|
|
sprintf(statustext,"Text entry mode entered.\n");
|
|
break;
|
|
case S_EDITTEXT:
|
|
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;
|
|
case S_LOADING:
|
|
sprintf(statustext,"Load mode entered.\n");
|
|
break;
|
|
case S_XSCROLL:
|
|
sprintf(statustext,"Scrolling horizontally...\n");
|
|
break;
|
|
case S_YSCROLL:
|
|
sprintf(statustext,"Scrolling vertically...\n");
|
|
break;
|
|
}
|
|
drawstatusbar();
|
|
}
|
|
}
|
|
|
|
void cleanup(void) {
|
|
int i;
|
|
SDL_FreeCursor(textmouse);
|
|
SDL_FreeCursor(objmouse);
|
|
for (i = 1; i < MAXLETTERHEIGHT; i++) {
|
|
TTF_CloseFont(font[i]);
|
|
}
|
|
TTF_Quit();
|
|
SDL_EnableUNICODE(0);
|
|
SDL_Quit();
|
|
}
|
|
|
|
void copy(void) {
|
|
if (map[curmap].selecteditem == -1) {
|
|
/* copy entire map */
|
|
copytype = T_MAP;
|
|
copyfrom = -1;
|
|
copymap = curmap;
|
|
sprintf(statustext,"Map %d ('%s') set as copy source.",curmap, map[curmap].name);
|
|
drawstatusbar();
|
|
} else {
|
|
if (map[curmap].selecteditemtype == T_OBJECT) {
|
|
copytype = T_OBJECT;
|
|
copymap = curmap;
|
|
copyfrom = map[curmap].selecteditem;
|
|
sprintf(statustext,"Object %d set as copy source.",copyfrom);
|
|
drawstatusbar();
|
|
} else if (map[curmap].selecteditemtype == T_TEXT) {
|
|
copytype = T_TEXT;
|
|
copymap = curmap;
|
|
copyfrom = map[curmap].selecteditem;
|
|
sprintf(statustext,"Text %d ('%s') set as copy source.",copyfrom, map[curmap].textob[copyfrom].text);
|
|
drawstatusbar();
|
|
}
|
|
}
|
|
}
|
|
|
|
int createobject(int type, int x, int y) {
|
|
map[curmap].obj[map[curmap].numobjects].type = type;
|
|
map[curmap].obj[map[curmap].numobjects].w = objtype[type].defw;
|
|
map[curmap].obj[map[curmap].numobjects].h = objtype[type].defh;
|
|
if ((x + map[curmap].obj[map[curmap].numobjects].w) >= map[curmap].width) {
|
|
x = map[curmap].width - map[curmap].obj[map[curmap].numobjects].w - 1;
|
|
}
|
|
if ((y + map[curmap].obj[map[curmap].numobjects].h) >= map[curmap].height) {
|
|
y = map[curmap].height - map[curmap].obj[map[curmap].numobjects].h - 1;
|
|
}
|
|
|
|
/* adjust for grid */
|
|
if (grid) {
|
|
x = x - (x % gridsize);
|
|
y = y - (y % gridsize);
|
|
}
|
|
|
|
map[curmap].obj[map[curmap].numobjects].x = x;
|
|
map[curmap].obj[map[curmap].numobjects].y = y;
|
|
|
|
map[curmap].obj[map[curmap].numobjects].child = -1;
|
|
map[curmap].obj[map[curmap].numobjects].fillcol.unused &= ~ISFLOW; /* not a flow */
|
|
|
|
setmod(TRUE);
|
|
sprintf(statustext,"Object #%d (%s) created at (%d,%d).\n",map[curmap].numobjects, objtype[type].name, x, y);
|
|
drawstatusbar();
|
|
|
|
|
|
/* add to 'thing' list */
|
|
map[curmap].thing[map[curmap].numthings].type = T_OBJECT;
|
|
map[curmap].thing[map[curmap].numthings].id = map[curmap].numobjects;
|
|
|
|
map[curmap].numobjects++;
|
|
map[curmap].numthings++;
|
|
|
|
|
|
return 0;
|
|
}
|
|
|
|
void copyline(SDL_Surface *screen,int x1, int y1, int x2, int y2, int *lbuf) {
|
|
int deltax, deltay;
|
|
int numpixels;
|
|
int d;
|
|
int dinc1,dinc2,xinc1,xinc2,yinc1,yinc2;
|
|
int i;
|
|
int x;
|
|
int y;
|
|
SDL_Color bgcol;
|
|
|
|
/* store coords */
|
|
lbuf[0] = x1;
|
|
lbuf[1] = y1;
|
|
lbuf[2] = x2;
|
|
lbuf[3] = y2;
|
|
|
|
deltax = (x2 - x1);
|
|
if (deltax < 0) deltax = -deltax;
|
|
deltay = (y2 - y1);
|
|
if (deltay < 0) deltay = -deltay;
|
|
|
|
if (deltax >= deltay) {
|
|
numpixels = deltax + 1;
|
|
d = (deltay*2) - deltax;
|
|
dinc1 = deltay << 1;
|
|
dinc2 = (deltay-deltax) << 1;
|
|
xinc1 = 1;
|
|
xinc2 = 1;
|
|
yinc1 = 0;
|
|
yinc2 = 1;
|
|
} else {
|
|
numpixels = deltay + 1;
|
|
d = (deltax*2) - deltay;
|
|
dinc1 = deltax << 1;
|
|
dinc2 = (deltax - deltay) << 1;
|
|
xinc1 = 0;
|
|
xinc2 = 1;
|
|
yinc1 = 1;
|
|
yinc2 = 1;
|
|
}
|
|
|
|
if (x1 > x2) {
|
|
xinc1 = - xinc1;
|
|
xinc2 = - xinc2;
|
|
}
|
|
if (y1 > y2) {
|
|
yinc1 = - yinc1;
|
|
yinc2 = - yinc2;
|
|
}
|
|
|
|
x = x1; y = y1;
|
|
|
|
for (i = 0; i < numpixels; i++) {
|
|
getcolor(screen, x, y, &bgcol);
|
|
lbuf[i+4] = SDL_MapRGB(screen->format, bgcol.r, bgcol.g, bgcol.b);
|
|
|
|
if (d < 0) {
|
|
d += dinc1;
|
|
x += xinc1;
|
|
y += yinc1;
|
|
} else {
|
|
d += dinc2;
|
|
x += xinc2;
|
|
y += yinc2;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void deletething(int id, int type) {
|
|
int i;
|
|
int found;
|
|
|
|
|
|
if (type == T_LINK) {
|
|
/* remove the link*/
|
|
deletelink(id);
|
|
} else if (type == T_TEXT) {
|
|
deletetext(id);
|
|
} else if (type == T_OBJECT) {
|
|
/* remove any links connecting to this map[curmap].object */
|
|
found = 0;
|
|
while (found >= 0 ) {
|
|
found = -1;
|
|
for (i = 0; i < map[curmap].numlinks; i++) {
|
|
if ((map[curmap].olink[i].srcobj == id) || (map[curmap].olink[i].dstobj == id)) {
|
|
found = i;
|
|
break;
|
|
}
|
|
}
|
|
if (found >= 0) {
|
|
deletelink(found);
|
|
}
|
|
}
|
|
|
|
/* remove any text anchored to this map[curmap].object */
|
|
found = 0;
|
|
while (found >= 0 ) {
|
|
found = -1;
|
|
for (i = 0; i < map[curmap].numtext; i++) {
|
|
if (map[curmap].textob[i].anchor == id) {
|
|
found = i;
|
|
break;
|
|
}
|
|
}
|
|
if (found >= 0) {
|
|
deletetext(found);
|
|
}
|
|
}
|
|
/* remove the map[curmap].object */
|
|
deleteobject(id);
|
|
/* shuffle ids on any link referencing this object */
|
|
for (i = 0; i < map[curmap].numlinks; i++) {
|
|
if (map[curmap].olink[i].srcobj > id) {
|
|
map[curmap].olink[i].srcobj--;
|
|
}
|
|
if (map[curmap].olink[i].dstobj > id) {
|
|
map[curmap].olink[i].dstobj--;
|
|
}
|
|
}
|
|
/* shuffle ids on any text referencing this object */
|
|
for (i = 0; i < map[curmap].numtext; i++) {
|
|
if (map[curmap].textob[i].anchor > id) {
|
|
map[curmap].textob[i].anchor--;
|
|
}
|
|
}
|
|
}
|
|
setmod(TRUE);
|
|
map[curmap].selecteditem = -1;
|
|
map[curmap].selecteditemtype = -1;
|
|
drawmap(TRUE);
|
|
}
|
|
|
|
void deletelink(int linkid) {
|
|
int i;
|
|
int n;
|
|
int found;
|
|
|
|
|
|
for (i = linkid; i < (map[curmap].numlinks-1); i++) {
|
|
map[curmap].olink[i] = map[curmap].olink[i+1];
|
|
}
|
|
map[curmap].numlinks--;
|
|
/* shuffle thing # */
|
|
for (n = 0; n < map[curmap].numthings; n++) {
|
|
/* mark for deletion */
|
|
if ((map[curmap].thing[n].id == linkid) && (map[curmap].thing[n].type == T_LINK)) {
|
|
map[curmap].thing[n].id = -1;
|
|
}
|
|
/* shuffle id */
|
|
if ((map[curmap].thing[n].id > linkid) && (map[curmap].thing[n].type == T_LINK)) {
|
|
map[curmap].thing[n].id--;
|
|
}
|
|
}
|
|
|
|
found = -1;
|
|
for (n = 0; n < map[curmap].numthings; n++) {
|
|
if ((map[curmap].thing[n].type == T_LINK) && (map[curmap].thing[n].id == -1)) {
|
|
found = n;
|
|
}
|
|
}
|
|
|
|
if (found != -1) {
|
|
// remove the thing
|
|
for (n = found; n < (map[curmap].numthings-1); n++) {
|
|
map[curmap].thing[n] = map[curmap].thing[n+1];
|
|
}
|
|
map[curmap].numthings--;
|
|
} else {
|
|
seterror(255);
|
|
sprintf(statustext,"Can't find matching thing for link #%d!\n",linkid);
|
|
}
|
|
|
|
setmod(TRUE);
|
|
sprintf(statustext,"Deleted link #%d.\n",linkid);
|
|
drawstatusbar();
|
|
|
|
}
|
|
|
|
|
|
void deleteobject(int oid) {
|
|
int i;
|
|
int n;
|
|
int found;
|
|
|
|
for (i = oid; i < (map[curmap].numobjects-1); i++) {
|
|
map[curmap].obj[i] = map[curmap].obj[i+1];
|
|
}
|
|
map[curmap].numobjects--;
|
|
/* shuffle thing # */
|
|
for (n = 0; n < map[curmap].numthings; n++) {
|
|
if ((map[curmap].thing[n].id == oid) && (map[curmap].thing[n].type == T_OBJECT)) {
|
|
map[curmap].thing[n].id = -1;
|
|
}
|
|
if ((map[curmap].thing[n].id > oid) && (map[curmap].thing[n].type == T_OBJECT)) {
|
|
map[curmap].thing[n].id--;
|
|
}
|
|
}
|
|
|
|
found = -1;
|
|
for (n = 0; n < map[curmap].numthings; n++) {
|
|
if ((map[curmap].thing[n].type == T_OBJECT) && (map[curmap].thing[n].id == -1 )) {
|
|
found = n;
|
|
}
|
|
}
|
|
|
|
if (found != -1) {
|
|
// remove the thing
|
|
for (n = found; n < (map[curmap].numthings-1); n++) {
|
|
map[curmap].thing[n] = map[curmap].thing[n+1];
|
|
}
|
|
map[curmap].numthings--;
|
|
} else {
|
|
seterror(255);
|
|
sprintf(statustext,"Can't find matching thing for object #%d!\n",oid);
|
|
}
|
|
|
|
setmod(TRUE);
|
|
sprintf(statustext,"Deleted object #%d.\n",oid);
|
|
drawstatusbar();
|
|
|
|
|
|
}
|
|
|
|
void deletetext(int textid) {
|
|
int i;
|
|
int n;
|
|
int found;
|
|
|
|
|
|
for (i = textid; i < (map[curmap].numtext-1); i++) {
|
|
map[curmap].textob[i] = map[curmap].textob[i+1];
|
|
}
|
|
map[curmap].numtext--;
|
|
/* shuffle thing # */
|
|
for (n = 0; n < map[curmap].numthings; n++) {
|
|
/* mark for deletion */
|
|
if ((map[curmap].thing[n].id == textid) && (map[curmap].thing[n].type == T_TEXT)) {
|
|
map[curmap].thing[n].id = -1;
|
|
}
|
|
/* shuffle id */
|
|
if ((map[curmap].thing[n].id > textid) && (map[curmap].thing[n].type == T_TEXT)) {
|
|
map[curmap].thing[n].id--;
|
|
}
|
|
}
|
|
|
|
found = -1;
|
|
for (n = 0; n < map[curmap].numthings; n++) {
|
|
if ((map[curmap].thing[n].type == T_TEXT) && (map[curmap].thing[n].id == -1)) {
|
|
found = n;
|
|
}
|
|
}
|
|
|
|
if (found != -1) {
|
|
// remove the thing
|
|
for (n = found; n < (map[curmap].numthings-1); n++) {
|
|
map[curmap].thing[n] = map[curmap].thing[n+1];
|
|
}
|
|
map[curmap].numthings--;
|
|
} else {
|
|
seterror(255);
|
|
sprintf(statustext,"Can't find matching thing for text item #%d!\n",textid);
|
|
}
|
|
|
|
setmod(TRUE);
|
|
sprintf(statustext,"Deleted text item #%d.\n",textid);
|
|
drawstatusbar();
|
|
|
|
}
|
|
|
|
|
|
|
|
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,n;
|
|
int x;
|
|
int y;
|
|
int tempx,tempy;
|
|
int o,oldo;
|
|
SDL_Surface *temps;
|
|
int arrowthickness;
|
|
|
|
arrowthickness = (arrowstyle & 0x0000ff);
|
|
|
|
|
|
/* calculate where the arrowpoint should go - follow the line until
|
|
we're not on an object */
|
|
|
|
if (arrowpos == AP_END) {
|
|
/* temporarily reverse endpoints */
|
|
tempx = x1;
|
|
tempy = y1;
|
|
x1 = x2;
|
|
y1 = y2;
|
|
x2 = tempx;
|
|
y2 = tempy;
|
|
}
|
|
|
|
deltax = (x2 - x1);
|
|
if (deltax < 0) deltax = -deltax;
|
|
deltay = (y2 - y1);
|
|
if (deltay < 0) deltay = -deltay;
|
|
|
|
if (deltax >= deltay) {
|
|
numpixels = deltax + 1;
|
|
d = (deltay*2) - deltax;
|
|
dinc1 = deltay << 1;
|
|
dinc2 = (deltay-deltax) << 1;
|
|
xinc1 = 1;
|
|
xinc2 = 1;
|
|
yinc1 = 0;
|
|
yinc2 = 1;
|
|
} else {
|
|
numpixels = deltay + 1;
|
|
d = (deltax*2) - deltay;
|
|
dinc1 = deltax << 1;
|
|
dinc2 = (deltax - deltay) << 1;
|
|
xinc1 = 0;
|
|
xinc2 = 1;
|
|
yinc1 = 1;
|
|
yinc2 = 1;
|
|
}
|
|
|
|
if (x1 > x2) {
|
|
xinc1 = - xinc1;
|
|
xinc2 = - xinc2;
|
|
}
|
|
if (y1 > y2) {
|
|
yinc1 = - yinc1;
|
|
yinc2 = - yinc2;
|
|
}
|
|
|
|
x = x1; y = y1;
|
|
|
|
middlex = -1;
|
|
middley = -1;
|
|
|
|
|
|
/*
|
|
temps = SDL_CreateRGBSurface(SDL_SWSURFACE,10,10,
|
|
screen->format->BitsPerPixel, screen->format->Rmask,
|
|
screen->format->Gmask,screen->format->Bmask,
|
|
screen->format->Amask);
|
|
*/
|
|
|
|
temps = NULL;
|
|
o = -1;
|
|
oldo = -99;
|
|
|
|
for (i = 0; i < numpixels; i++) {
|
|
o = objat(x,y);
|
|
if (o == -1) {
|
|
middlex = x;
|
|
middley = y;
|
|
break;
|
|
} else {
|
|
int ox,oy;
|
|
SDL_Color tempc;
|
|
|
|
if (o != oldo) {
|
|
if (oldo == -99) {
|
|
SDL_Rect area;
|
|
int tid;
|
|
|
|
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);
|
|
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, TRUE);
|
|
|
|
|
|
/*
|
|
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);
|
|
temps = NULL;
|
|
}
|
|
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;
|
|
oy = y - map[curmap].obj[o].y;
|
|
|
|
getcolor(temps, ox + arrowthickness - 1, oy + arrowthickness -1, &tempc);
|
|
if ( (tempc.r == map[curmap].bgcol.r) &&
|
|
(tempc.g == map[curmap].bgcol.g) &&
|
|
(tempc.b == map[curmap].bgcol.b)) {
|
|
/* free temporary surface */
|
|
SDL_FreeSurface(temps);
|
|
temps = NULL;
|
|
|
|
middlex = x;
|
|
middley = y;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (d < 0) {
|
|
d += dinc1;
|
|
x += xinc1;
|
|
y += yinc1;
|
|
} else {
|
|
d += dinc2;
|
|
x += xinc2;
|
|
y += yinc2;
|
|
}
|
|
}
|
|
|
|
|
|
if (temps != NULL) {
|
|
SDL_FreeSurface(temps);
|
|
temps = NULL;
|
|
}
|
|
*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;
|
|
}
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
int dosearchnext(void) {
|
|
int i = -1;
|
|
int firsttime = TRUE;
|
|
int m;
|
|
int numtextfound = 0;
|
|
|
|
/* go through each text object until we find what we're looking for */
|
|
for (m = searchmap; ; m++) { /* for each map */
|
|
|
|
|
|
if (m >= nummaps) {
|
|
m = 0;
|
|
searchwrap = TRUE;
|
|
}
|
|
|
|
if ((m == searchmap) && (numtextfound == 0) && (!firsttime)) {
|
|
/* no text objects exist */
|
|
return 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;
|
|
}
|
|
|
|
/* 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;
|
|
}
|
|
}
|
|
numtextfound += (map[m].numtext);
|
|
|
|
|
|
}
|
|
|
|
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 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 &= 0x0000ff;
|
|
|
|
drawline(screen, arrowpointx, arrowpointy, arrowend1x, arrowend1y, c, arrowstyle);
|
|
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 arrowlength = 5;
|
|
int arrowthickness;
|
|
|
|
arrowthickness = (arrowstyle & 0x0000ff);
|
|
|
|
|
|
//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,"<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" style=\"stroke:rgb(%d,%d,%d);stroke-width:%d; \"/>\n", arrowpointx, arrowpointy, arrowend1x, arrowend1y,c.r,c.g,c.b, arrowstyle );
|
|
fprintf(svgfile, svgbuf);
|
|
sprintf(svgbuf,"<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" style=\"stroke:rgb(%d,%d,%d);stroke-width:%d; \"/>\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;
|
|
}
|
|
|
|
void drawbezier(SDL_Surface *screen, int x1, int y1,
|
|
int x2,int y2,
|
|
int x3,int y3,
|
|
int x4,int y4,
|
|
SDL_Color c) {
|
|
int i;
|
|
float t;
|
|
int abx,aby,bcx,bcy,cdx,cdy;
|
|
int abbcx,abbcy,bccdx,bccdy;
|
|
int newx,newy;
|
|
int oldx,oldy;
|
|
|
|
oldx = x1;
|
|
oldy = y1;
|
|
|
|
for (i = 0; i < BEZIERQUALITY; i++) {
|
|
t = (float)i / (float)(BEZIERQUALITY - 1);
|
|
|
|
lerp(&abx,&aby, x1, y1, x2, y2, t);
|
|
lerp(&bcx,&bcy, x2, y2, x3, y3, t);
|
|
lerp(&cdx,&cdy, x3, y3, x4, y4, t);
|
|
lerp(&abbcx,&abbcy, abx, aby, bcx, bcy, t);
|
|
lerp(&bccdx,&bccdy, bcx, bcy, cdx, cdy, t);
|
|
lerp(&newx,&newy, abbcx, abbcy, bccdx, bccdy, t);
|
|
|
|
drawline(screen, oldx, oldy, newx, newy, c, 1);
|
|
oldx = newx;
|
|
oldy = newy;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void drawbox(SDL_Surface *screen, int x1, int y1, int x2, int y2, SDL_Color c, SDL_Color *fc) {
|
|
if (fc != NULL) {
|
|
if (fc->unused & USECOLOUR) {
|
|
/* fill */
|
|
if (((x2 - x1) >= 2) && ((y2 - y1) >= 2)) {
|
|
int y;
|
|
for (y = (y1+1) ; y <= (y2-1); y++) {
|
|
drawline(screen, x1+1, y, x2-1,y,*fc,1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
drawline(screen,x1,y1,x2,y1,c,1);
|
|
drawline(screen,x1,y1,x1,y2,c,1);
|
|
drawline(screen,x1,y2,x2,y2,c,1);
|
|
drawline(screen,x2,y1,x2,y2,c,1);
|
|
}
|
|
|
|
void drawellipsepoints(SDL_Surface *screen, int x1, int y1, int x, int y, SDL_Color c) {
|
|
drawpixel(screen, x1 + x, y1 + y, c);
|
|
drawpixel(screen, x1 - x, y1 + y, c);
|
|
drawpixel(screen, x1 - x, y1 - y, c);
|
|
drawpixel(screen, x1 + x, y1 - y, c);
|
|
}
|
|
|
|
void drawellipse(SDL_Surface *screen, int x1, int y1, int xr, int yr, SDL_Color c) {
|
|
double x,y;
|
|
double xc,yc;
|
|
double ee;
|
|
double twoas, twobs;
|
|
double stoppingx,stoppingy;
|
|
|
|
twoas = 2 * xr * xr;
|
|
twobs = 2 * yr * yr;
|
|
|
|
/* first set */
|
|
x = xr;
|
|
y = 0;
|
|
xc = yr * yr * (1 - 2*xr);
|
|
yc = xr * xr;
|
|
ee = 0;
|
|
stoppingx = twobs * xr;
|
|
stoppingy = 0;
|
|
while (stoppingx >= stoppingy) {
|
|
drawellipsepoints(screen, x1, y1, x,y, c);
|
|
y++;
|
|
stoppingy += twoas;
|
|
ee += yc;
|
|
yc += twoas;
|
|
if ((2*ee + xc) > 0) {
|
|
x--;
|
|
stoppingx -= twobs;
|
|
ee += xc;
|
|
xc += twobs;
|
|
}
|
|
}
|
|
|
|
|
|
/* second set */
|
|
x = 0;
|
|
y = yr;
|
|
xc = yr * yr;
|
|
yc = xr * xr * (1 - 2*yr);
|
|
ee = 0;
|
|
stoppingx = 0;
|
|
stoppingy = twoas * yr;
|
|
while (stoppingx <= stoppingy) {
|
|
drawellipsepoints(screen, x1, y1, x,y, c);
|
|
x++;
|
|
stoppingx += twobs;
|
|
ee += xc;
|
|
xc += twobs;
|
|
if ((2*ee + yc) > 0) {
|
|
y--;
|
|
stoppingy -= twoas;
|
|
ee += yc;
|
|
yc += twoas;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void drawflowbox(SDL_Surface *dest, int oid, int otype) {
|
|
int x1,y1,x2,y2;
|
|
int i;
|
|
int ls = 10;
|
|
|
|
switch (otype) {
|
|
case T_OBJECT:
|
|
x1 = map[curmap].obj[oid].x;
|
|
y1 = map[curmap].obj[oid].y;
|
|
x2 = map[curmap].obj[oid].x + map[curmap].obj[oid].w;
|
|
y2 = map[curmap].obj[oid].y + map[curmap].obj[oid].h;
|
|
drawbox(dest, x1, y1, x2, y2, blue, NULL);
|
|
break;
|
|
case T_LINK:
|
|
x1 = map[curmap].obj[map[curmap].olink[oid].srcobj].x + map[curmap].olink[oid].srcxoff;
|
|
y1 = map[curmap].obj[map[curmap].olink[oid].srcobj].y + map[curmap].olink[oid].srcyoff;
|
|
x2 = map[curmap].obj[map[curmap].olink[oid].dstobj].x + map[curmap].olink[oid].dstxoff;
|
|
y2 = map[curmap].obj[map[curmap].olink[oid].dstobj].y + map[curmap].olink[oid].dstyoff;
|
|
drawbox(dest, x1-ls, y1-ls, x1+ls, y1+ls, blue, &blue);
|
|
drawbox(dest, x2-ls, y2-ls, x2+ls, y2+ls, blue, &blue);
|
|
for (i = 0; i < map[curmap].olink[oid].npoints; i++) {
|
|
x1 = map[curmap].olink[oid].point[i].x;
|
|
y1 = map[curmap].olink[oid].point[i].y;
|
|
drawbox(dest, x1-ls, y1-ls, x1+ls, y1+ls, blue, &blue);
|
|
}
|
|
break;
|
|
case T_TEXT:
|
|
if (map[curmap].textob[oid].anchor == -1) {
|
|
x1 = map[curmap].textob[oid].x;
|
|
y1 = map[curmap].textob[oid].y;
|
|
} else {
|
|
x1 = map[curmap].textob[oid].x + map[curmap].obj[map[curmap].textob[oid].anchor].x;
|
|
y1 = map[curmap].textob[oid].y + map[curmap].obj[map[curmap].textob[oid].anchor].y;
|
|
}
|
|
x2 = x1 + map[curmap].textob[oid].w;
|
|
y2 = y1 + map[curmap].textob[oid].h;
|
|
drawbox(dest, x1, y1, x2, y2, blue, NULL);
|
|
break;
|
|
default:
|
|
return;
|
|
}
|
|
}
|
|
|
|
void drawcolorchart(SDL_Surface *dest) {
|
|
int x,y;
|
|
//int i;
|
|
SDL_Color c;
|
|
int speed;
|
|
int finished = FALSE;
|
|
int size = 18;
|
|
|
|
|
|
int mode = 1;
|
|
|
|
c.r = 0;
|
|
c.g = 0;
|
|
c.b = 0;
|
|
c.unused = USECOLOUR;
|
|
|
|
speed = 24 ;
|
|
|
|
for (y = 0; (y < (map[curmap].height-size)) && (!finished); y+= size) {
|
|
for (x = 0; (x < (map[curmap].width-size)) && (!finished); x+= size) {
|
|
drawbox(dest,x,y,x+(size-1),y+(size-1),black, &c);
|
|
/* fill box */
|
|
/*for (i = 1; i <= (size-2); i++) {
|
|
drawline(dest, x+1, y+i, x+(size-2), y+i, c,1);
|
|
}*/
|
|
/* change color */
|
|
|
|
if (mode == 1) {
|
|
if (c.b + speed > 255) {
|
|
c.b = 0;
|
|
if (c.g + speed > 255) {
|
|
c.g = 0;
|
|
if (c.r + speed > 255) {
|
|
c.r = 255 - speed;
|
|
c.g = 255 - speed;
|
|
c.b = 255 - speed;
|
|
mode = 2;
|
|
} else c.r += speed;
|
|
} else c.g += speed;
|
|
} else c.b += speed;
|
|
} else {
|
|
if (c.r-speed <= 0) finished = TRUE;
|
|
if (c.g-speed <= 0) finished = TRUE;
|
|
if (c.b-speed <= 0) finished = TRUE;
|
|
c.r -= speed;
|
|
c.g -= speed;
|
|
c.b -= speed;
|
|
}
|
|
|
|
if (c.r >= 240) c.r = 255;
|
|
if (c.g >= 240) c.g = 255;
|
|
if (c.b >= 240) c.b = 255;
|
|
}
|
|
}
|
|
SDL_Flip(screen);
|
|
}
|
|
|
|
int findpointpos(link_t *l, int px, int py) {
|
|
int i;
|
|
int x,y,x2,y2;
|
|
int pos = 0;
|
|
|
|
x = map[curmap].obj[l->srcobj].x + l->srcxoff;
|
|
y = map[curmap].obj[l->srcobj].y + l->srcyoff;
|
|
|
|
for (i = 0; i < l->npoints; i++) {
|
|
x2 = l->point[i].x;
|
|
y2 = l->point[i].y;
|
|
|
|
if (isonline(px, py, x, y, x2, y2)) {
|
|
return pos;
|
|
}
|
|
pos++;
|
|
|
|
x = x2;
|
|
y = y2;
|
|
}
|
|
|
|
/* draw line to final map[curmap].object */
|
|
x2 = map[curmap].obj[l->dstobj].x + l->dstxoff;
|
|
y2 = map[curmap].obj[l->dstobj].y + l->dstyoff;
|
|
|
|
return pos;
|
|
}
|
|
|
|
void drawline(SDL_Surface *screen, int x1, int y1, int x2, int y2, SDL_Color c, int linestyle) {
|
|
int deltax, deltay;
|
|
int numpixels;
|
|
int d;
|
|
int dinc1,dinc2,xinc1,xinc2,yinc1,yinc2;
|
|
int i;
|
|
int x;
|
|
int y;
|
|
int xx,yy;
|
|
int maskcount = 0;
|
|
int maskindex = 0;
|
|
Uint8 arrow,style, thickness;
|
|
|
|
arrow = (linestyle & (0x00ff0000)) >> 16;
|
|
style = (linestyle & (0x0000ff00)) >> 8;
|
|
thickness = (linestyle & (0x000000ff));
|
|
|
|
|
|
deltax = (x2 - x1);
|
|
if (deltax < 0) deltax = -deltax;
|
|
deltay = (y2 - y1);
|
|
if (deltay < 0) deltay = -deltay;
|
|
|
|
if (deltax >= deltay) {
|
|
numpixels = deltax + 1;
|
|
d = (deltay*2) - deltax;
|
|
dinc1 = deltay << 1;
|
|
dinc2 = (deltay-deltax) << 1;
|
|
xinc1 = 1;
|
|
xinc2 = 1;
|
|
yinc1 = 0;
|
|
yinc2 = 1;
|
|
} else {
|
|
numpixels = deltay + 1;
|
|
d = (deltax*2) - deltay;
|
|
dinc1 = deltax << 1;
|
|
dinc2 = (deltax - deltay) << 1;
|
|
xinc1 = 0;
|
|
xinc2 = 1;
|
|
yinc1 = 1;
|
|
yinc2 = 1;
|
|
}
|
|
|
|
if (x1 > x2) {
|
|
xinc1 = - xinc1;
|
|
xinc2 = - xinc2;
|
|
}
|
|
if (y1 > y2) {
|
|
yinc1 = - yinc1;
|
|
yinc2 = - yinc2;
|
|
}
|
|
|
|
x = x1; y = y1;
|
|
|
|
maskcount = 0;
|
|
maskindex = 0;
|
|
for (i = 0; i < numpixels; i++) {
|
|
|
|
if (linemask[style][maskindex] == 1) {
|
|
/* plot point */
|
|
for (yy = 0; yy < thickness ; yy++) {
|
|
for (xx = 0; xx < thickness ; xx++) {
|
|
drawpixel(screen,x+xx,y+yy,c);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* increment mask count */
|
|
if (++maskcount >= thickness) {
|
|
maskcount = 0;
|
|
/* increment mask index */
|
|
maskindex++;
|
|
if (maskindex >= LINESTYLESIZE) {
|
|
maskindex = 0;
|
|
}
|
|
if (linemask[style][maskindex] == -1) maskindex = 0;
|
|
}
|
|
|
|
|
|
if (d < 0) {
|
|
d += dinc1;
|
|
x += xinc1;
|
|
y += yinc1;
|
|
} else {
|
|
d += dinc2;
|
|
x += xinc2;
|
|
y += yinc2;
|
|
}
|
|
}
|
|
|
|
/* draw arrowheads if required */
|
|
if (arrow) {
|
|
if ((arrow == AP_START) || (arrow == AP_END)) {
|
|
drawarrowhead(screen, x1, y1, x2, y2, c, linestyle, arrow);
|
|
} else if (arrow == AP_BOTH) {
|
|
drawarrowhead(screen, x1, y1, x2, y2, c, linestyle, AP_START);
|
|
drawarrowhead(screen, x1, y1, x2, y2, c, linestyle, AP_END);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
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 - screenx;
|
|
y = map[curmap].obj[l->srcobj].y + l->srcyoff - screeny;
|
|
arrow = (l->style & 0x00ff0000) >> 16;
|
|
|
|
for (i = 0; i < l->npoints; i++) {
|
|
x2 = l->point[i].x - screenx;
|
|
y2 = l->point[i].y - screeny;
|
|
|
|
/* 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);
|
|
|
|
/* 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;
|
|
}
|
|
|
|
/* draw line to final map[curmap].object */
|
|
x2 = map[curmap].obj[l->dstobj].x + l->dstxoff - screenx;
|
|
y2 = map[curmap].obj[l->dstobj].y + l->dstyoff - screeny;
|
|
|
|
/* 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) {
|
|
int i;
|
|
int x,y,x2,y2;
|
|
int width;
|
|
char temp[BUFLEN];
|
|
char dasharray[BUFLEN];
|
|
int linestyle;
|
|
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;
|
|
linestyle = (l->style & 0x0000ff00) >> 8;
|
|
arrow = (l->style & 0x00ff0000) >> 16;
|
|
|
|
old = linemask[linestyle][0];
|
|
count = 1;
|
|
first = 1;
|
|
|
|
sprintf(dasharray, "stroke-dasharray:");
|
|
for (i = 0; linemask[linestyle][i] != -1; i++) {
|
|
cur = linemask[linestyle][i];
|
|
//sprintf(temp, "[%d]", cur);
|
|
//strcat(dasharray, temp);
|
|
if (cur == old) {
|
|
count++;
|
|
} else {
|
|
if (first) {
|
|
sprintf(temp, "%d", count*width);
|
|
first = 0;
|
|
} else {
|
|
sprintf(temp, ",%d", count*width);
|
|
}
|
|
count = 1;
|
|
strcat(dasharray, temp);
|
|
old = cur;
|
|
}
|
|
}
|
|
|
|
if (first == 1) {
|
|
/* don't need dash-array */
|
|
strcpy(dasharray, "");
|
|
} else {
|
|
sprintf(temp, ",%d", count*width);
|
|
strcat(dasharray, temp);
|
|
}
|
|
|
|
|
|
for (i = 0; i < l->npoints; i++) {
|
|
x2 = l->point[i].x;
|
|
y2 = l->point[i].y;
|
|
|
|
|
|
sprintf(svgbuf,"<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" style=\"stroke:rgb(%d,%d,%d);stroke-width:%d; %s;\"/>\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;
|
|
}
|
|
|
|
/* draw line to final map[curmap].object */
|
|
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,"<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" style=\"stroke:rgb(%d,%d,%d);stroke-width:%d; %s;\"/>\n", x, y, x2, y2,l->col.r,l->col.g,l->col.b, width ,dasharray);
|
|
fprintf(svgfile, svgbuf);
|
|
}
|
|
|
|
|
|
void drawobject(SDL_Surface *dest, mapobject_t *o, int doublebuffer, int adjust) {
|
|
SDL_Surface *temps;
|
|
SDL_Rect area;
|
|
Uint32 bgcol;
|
|
int testing = 0;
|
|
|
|
/* create temp surface */
|
|
if (testing) {
|
|
printf("About to create surface...");
|
|
fflush(STDOUT);
|
|
}
|
|
if (doublebuffer) {
|
|
temps = SDL_CreateRGBSurface(SDL_SWSURFACE,o->w+3, o->h+3,
|
|
screen->format->BitsPerPixel, screen->format->Rmask,
|
|
screen->format->Gmask,screen->format->Bmask,
|
|
screen->format->Amask);
|
|
} else {
|
|
temps = dest;
|
|
}
|
|
|
|
bgcol = SDL_MapRGB(temps->format, map[curmap].bgcol.r,map[curmap].bgcol.g,map[curmap].bgcol.b);
|
|
SDL_FillRect(temps, NULL, bgcol);
|
|
|
|
/* draw onto temp surface */
|
|
if (testing) {
|
|
printf("About to drawvector ...");
|
|
fflush(STDOUT);
|
|
}
|
|
if (o->fillcol.unused & USECOLOUR) {
|
|
drawvector(temps, &objtype[o->type].vimg, 0, 0, o->w, o->h, NULL, &o->fillcol);
|
|
} else {
|
|
drawvector(temps, &objtype[o->type].vimg, 0, 0, o->w, o->h, NULL, NULL);
|
|
}
|
|
|
|
/* set transparent colour on temp surface */
|
|
if (testing) {
|
|
printf("About to setcolour ...");
|
|
fflush(STDOUT);
|
|
}
|
|
SDL_SetColorKey(temps, SDL_SRCCOLORKEY|SDL_RLEACCEL, bgcol);
|
|
|
|
/* blit to screen */
|
|
if (doublebuffer) {
|
|
area.x = o->x;
|
|
area.y = o->y;
|
|
if (adjust) {
|
|
area.x -= screenx;
|
|
area.y -= screeny;
|
|
}
|
|
area.w = o->w;
|
|
area.h = o->h;
|
|
if (testing) {
|
|
printf("About to blitsurface ...");
|
|
fflush(STDOUT);
|
|
}
|
|
SDL_BlitSurface(temps, 0, dest, &area);
|
|
SDL_FreeSurface(temps);
|
|
temps = NULL;
|
|
} else {
|
|
SDL_UpdateRect(temps, 0, 0, o->w, o->h);
|
|
}
|
|
|
|
if (testing) {
|
|
printf("About to return ...");
|
|
fflush(STDOUT);
|
|
}
|
|
|
|
}
|
|
|
|
void drawobjectSVG(SDL_Surface *dest, mapobject_t *o, int doublebuffer) {
|
|
static int gnum = 0;
|
|
|
|
/* create SVG group */
|
|
sprintf(svgbuf, "<g id=\"object%d\" >\n", gnum);
|
|
fprintf(svgfile, svgbuf);
|
|
|
|
if (o->fillcol.unused & USECOLOUR) {
|
|
drawvectorSVG(&objtype[o->type].vimg, o->x, o->y, o->w, o->h, NULL, &o->fillcol);
|
|
} else {
|
|
drawvectorSVG(&objtype[o->type].vimg, o->x, o->y, o->w, o->h, NULL, NULL);
|
|
}
|
|
|
|
sprintf(svgbuf, "</g>\n");
|
|
fprintf(svgfile, svgbuf);
|
|
gnum++;
|
|
|
|
}
|
|
|
|
void drawpixel(SDL_Surface *screen, int x, int y, SDL_Color c) {
|
|
Uint32 color = SDL_MapRGB(screen->format, c.r, c.g, c.b);
|
|
|
|
if ((x < 0) || (y < 0) || (x >= screen->w) || (y >= screen->h)) {
|
|
return;
|
|
}
|
|
|
|
/*if ( SDL_MUSTLOCK(screen) ) {
|
|
if ( SDL_LockSurface(screen) < 0 ) {
|
|
return;
|
|
}
|
|
}*/
|
|
switch (screen->format->BytesPerPixel) {
|
|
case 1: { /* Assuming 8-bpp */
|
|
Uint8 *bufp;
|
|
|
|
bufp = (Uint8 *)screen->pixels + y*screen->pitch + x;
|
|
*bufp = color;
|
|
}
|
|
break;
|
|
|
|
case 2: { /* Probably 15-bpp or 16-bpp */
|
|
Uint16 *bufp;
|
|
|
|
bufp = (Uint16 *)screen->pixels + y*screen->pitch/2 + x;
|
|
*bufp = color;
|
|
}
|
|
break;
|
|
|
|
case 3: { /* Slow 24-bpp mode, usually not used */
|
|
Uint8 *bufp;
|
|
|
|
bufp = (Uint8 *)screen->pixels + y*screen->pitch + x * 3;
|
|
if(SDL_BYTEORDER == SDL_LIL_ENDIAN) {
|
|
bufp[0] = color;
|
|
bufp[1] = color >> 8;
|
|
bufp[2] = color >> 16;
|
|
} else {
|
|
bufp[2] = color;
|
|
bufp[1] = color >> 8;
|
|
bufp[0] = color >> 16;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 4: { /* Probably 32-bpp */
|
|
Uint32 *bufp;
|
|
|
|
bufp = (Uint32 *)screen->pixels + y*screen->pitch/4 + x;
|
|
*bufp = color;
|
|
}
|
|
break;
|
|
}
|
|
/*
|
|
if ( SDL_MUSTLOCK(screen) ) {
|
|
SDL_UnlockSurface(screen);
|
|
}
|
|
*/
|
|
//SDL_UpdateRect(screen, x, y, 1, 1);
|
|
}
|
|
|
|
void drawmap(int wantdecs) {
|
|
int i;
|
|
int testing = 0;
|
|
SDL_Rect area;
|
|
Uint32 fillcol;
|
|
int txoff,tyoff;
|
|
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) || (state == S_SEARCH)) {
|
|
/* show text entry screen */
|
|
showfiledialog();
|
|
return;
|
|
}
|
|
|
|
if ((state == S_FGCOL) || (state == S_FILLCOL)) {
|
|
drawcolorchart(screen);
|
|
return;
|
|
}
|
|
|
|
if (state == S_CREATETELE) {
|
|
drawmaplist(screen);
|
|
return;
|
|
}
|
|
|
|
if (state == S_REALLYQUIT) {
|
|
drawyn(text);
|
|
return;
|
|
}
|
|
|
|
if (testing) {
|
|
printf("START DRAWMAP\n"); fflush(STDOUT);
|
|
}
|
|
|
|
/* clear map */
|
|
fillcol = SDL_MapRGB(buffer->format, map[curmap].bgcol.r,map[curmap].bgcol.g,map[curmap].bgcol.b);
|
|
SDL_FillRect(buffer, NULL, fillcol);
|
|
|
|
/* draw grid */
|
|
if (gridsize != 0) {
|
|
for (x = 0; x < screen->w - SIDEBARW; x += (gridsize*2)) {
|
|
drawline(buffer,x,0,x,(screen->h - STATUSH), gridcol, (LS_BIGDASH << 8) | 1);
|
|
if ((x+gridsize) < screen->w - SIDEBARW) {
|
|
drawline(buffer,x+gridsize,0,x+gridsize,(screen->h - DEFTEXTH-2), gridcol, (LS_DOTTED << 8) | 1);
|
|
}
|
|
}
|
|
|
|
for (y = 0; y < screen->h - STATUSH; y += (gridsize*2)) {
|
|
drawline(buffer,0,y,screen->w - SIDEBARW, y,gridcol, (LS_BIGDASH << 8) | 1);
|
|
if ((y+gridsize) < (screen->h - STATUSH)) {
|
|
drawline(buffer,0,y+gridsize,screen->w - SIDEBARW, y+gridsize,gridcol, (LS_DOTTED << 8) | 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
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)) {
|
|
drawobject(buffer, &map[curmap].obj[map[curmap].thing[i].id], TRUE, TRUE);
|
|
thingdrawn[i] = TRUE;
|
|
}
|
|
} 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)) {
|
|
drawlink(buffer, &map[curmap].olink[map[curmap].thing[i].id]);
|
|
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)) {
|
|
drawtext(buffer, &map[curmap].textob[map[curmap].thing[i].id], TRUE);
|
|
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 (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)) {
|
|
drawobject(buffer, &map[curmap].obj[map[curmap].thing[i].id], TRUE, 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)) {
|
|
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)) {
|
|
drawtext(buffer, &map[curmap].textob[map[curmap].thing[i].id], TRUE);
|
|
if (state == S_DRAWFLOW) drawflowbox(buffer, map[curmap].thing[i].id, T_TEXT);
|
|
thingdrawn[i] = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (testing) {
|
|
printf("FINISHED THINGS \n"); fflush(STDOUT);
|
|
}
|
|
|
|
if (testing) {
|
|
printf("DRAWING HIGHLIGHT\n"); fflush(STDOUT);
|
|
}
|
|
|
|
/* highlight the selected map[curmap].object */
|
|
/* by drawing boxes in its corners */
|
|
if (map[curmap].selecteditem != -1) {
|
|
if (map[curmap].selecteditemtype == T_OBJECT) {
|
|
int n;
|
|
|
|
/* 10% of map[curmap].object's size */
|
|
area.w = map[curmap].obj[map[curmap].selecteditem].w / OBJSELHANDLEPCT;
|
|
area.h = map[curmap].obj[map[curmap].selecteditem].h / OBJSELHANDLEPCT;
|
|
if (area.w < 2) area.w = 2;
|
|
if (area.h < 2) area.h = 2;
|
|
|
|
fillcol = SDL_MapRGB(buffer->format, 0, 0, 0);
|
|
|
|
/* top left */
|
|
area.x = map[curmap].obj[map[curmap].selecteditem].x - screenx;
|
|
area.y = map[curmap].obj[map[curmap].selecteditem].y - screeny;
|
|
SDL_FillRect(buffer, &area, fillcol);
|
|
/* top right */
|
|
area.x = map[curmap].obj[map[curmap].selecteditem].x + map[curmap].obj[map[curmap].selecteditem].w - area.w - screenx;
|
|
area.y = map[curmap].obj[map[curmap].selecteditem].y - screeny;
|
|
SDL_FillRect(buffer, &area, fillcol);
|
|
/* bottom left */
|
|
area.x = map[curmap].obj[map[curmap].selecteditem].x - screenx;
|
|
area.y = map[curmap].obj[map[curmap].selecteditem].y + map[curmap].obj[map[curmap].selecteditem].h - area.h - screeny;
|
|
SDL_FillRect(buffer, &area, fillcol);
|
|
/* bottom right */
|
|
area.x = map[curmap].obj[map[curmap].selecteditem].x + map[curmap].obj[map[curmap].selecteditem].w - area.w - screenx;
|
|
area.y = map[curmap].obj[map[curmap].selecteditem].y + map[curmap].obj[map[curmap].selecteditem].h - area.h - screeny;
|
|
SDL_FillRect(buffer, &area, fillcol);
|
|
|
|
/* Also highlight any text anchored to this object */
|
|
for (n = 0; n < map[curmap].numtext; n++) {
|
|
if (map[curmap].textob[n].anchor == map[curmap].selecteditem) {
|
|
int th;
|
|
|
|
/* calculate text's height */
|
|
th = TTF_FontHeight(font[map[curmap].textob[n].h]);
|
|
|
|
/* 10% of text's size */
|
|
area.w = map[curmap].textob[n].w / OBJSELHANDLEPCT;
|
|
area.h = th / OBJSELHANDLEPCT;
|
|
if (area.w < 2) area.w = 2;
|
|
if (area.h < 2) area.h = 2;
|
|
|
|
anchoreditem = map[curmap].textob[n].anchor;
|
|
if (anchoreditem == -1) {
|
|
txoff = 0;
|
|
tyoff = 0;
|
|
} else {
|
|
txoff = map[curmap].obj[anchoreditem].x;
|
|
tyoff = map[curmap].obj[anchoreditem].y;
|
|
}
|
|
|
|
fillcol = SDL_MapRGB(buffer->format, 0, 255, 0);
|
|
|
|
/* top left */
|
|
area.x = map[curmap].textob[n].x + txoff - screenx;
|
|
area.y = map[curmap].textob[n].y + tyoff - screeny;
|
|
SDL_FillRect(buffer, &area, fillcol);
|
|
/* top right */
|
|
area.x = map[curmap].textob[n].x +txoff + map[curmap].textob[n].w - area.w - screenx;
|
|
area.y = map[curmap].textob[n].y + tyoff - screeny;
|
|
SDL_FillRect(buffer, &area, fillcol);
|
|
/* bottom left */
|
|
area.x = map[curmap].textob[n].x +txoff - screenx;
|
|
area.y = map[curmap].textob[n].y + tyoff + th - area.h - screeny;
|
|
SDL_FillRect(buffer, &area, fillcol);
|
|
/* bottom right */
|
|
area.x = map[curmap].textob[n].x+txoff + map[curmap].textob[n].w - area.w - screenx;
|
|
area.y = map[curmap].textob[n].y +tyoff+ th - area.h - screeny;
|
|
SDL_FillRect(buffer, &area, fillcol);
|
|
}
|
|
}
|
|
|
|
} else if (map[curmap].selecteditemtype == T_TEXT) {
|
|
int th;
|
|
|
|
/* calculate text's height */
|
|
th = TTF_FontHeight(font[map[curmap].textob[map[curmap].selecteditem].h]);
|
|
|
|
/* 10% of text's size */
|
|
area.w = map[curmap].textob[map[curmap].selecteditem].w / OBJSELHANDLEPCT;
|
|
area.h = th / OBJSELHANDLEPCT;
|
|
if (area.w < 2) area.w = 2;
|
|
if (area.h < 2) area.h = 2;
|
|
|
|
anchoreditem = map[curmap].textob[map[curmap].selecteditem].anchor;
|
|
if (anchoreditem == -1) {
|
|
txoff = 0;
|
|
tyoff = 0;
|
|
} else {
|
|
txoff = map[curmap].obj[anchoreditem].x;
|
|
tyoff = map[curmap].obj[anchoreditem].y;
|
|
}
|
|
|
|
fillcol = SDL_MapRGB(buffer->format, 0, 0, 0);
|
|
|
|
/* top left */
|
|
area.x = map[curmap].textob[map[curmap].selecteditem].x + txoff - screenx;
|
|
area.y = map[curmap].textob[map[curmap].selecteditem].y + tyoff - screeny;
|
|
SDL_FillRect(buffer, &area, fillcol);
|
|
/* top right */
|
|
area.x = map[curmap].textob[map[curmap].selecteditem].x +txoff + map[curmap].textob[map[curmap].selecteditem].w - area.w - screenx;
|
|
area.y = map[curmap].textob[map[curmap].selecteditem].y + tyoff - screeny;
|
|
SDL_FillRect(buffer, &area, fillcol);
|
|
/* bottom left */
|
|
area.x = map[curmap].textob[map[curmap].selecteditem].x +txoff - screenx;
|
|
area.y = map[curmap].textob[map[curmap].selecteditem].y + tyoff + th - area.h - screeny;
|
|
SDL_FillRect(buffer, &area, fillcol);
|
|
/* bottom right */
|
|
area.x = map[curmap].textob[map[curmap].selecteditem].x+txoff + map[curmap].textob[map[curmap].selecteditem].w - area.w - screenx;
|
|
area.y = map[curmap].textob[map[curmap].selecteditem].y +tyoff+ th - area.h - screeny;
|
|
SDL_FillRect(buffer, &area, fillcol);
|
|
|
|
/* if this text is anchored, highlight the map[curmap].object which it is anchored to */
|
|
if (anchoreditem != -1) {
|
|
area.w = map[curmap].obj[anchoreditem].w / OBJSELHANDLEPCT;
|
|
area.h = map[curmap].obj[anchoreditem].h / OBJSELHANDLEPCT;
|
|
if (area.w < 2) area.w = 2;
|
|
if (area.h < 2) area.h = 2;
|
|
|
|
fillcol = SDL_MapRGB(buffer->format, 0, 255, 0);
|
|
|
|
/* top left */
|
|
area.x = map[curmap].obj[anchoreditem].x - screenx;
|
|
area.y = map[curmap].obj[anchoreditem].y - screeny;
|
|
SDL_FillRect(buffer, &area, fillcol);
|
|
/* top right */
|
|
area.x = map[curmap].obj[anchoreditem].x + map[curmap].obj[anchoreditem].w - area.w - screenx;
|
|
area.y = map[curmap].obj[anchoreditem].y - screeny;
|
|
SDL_FillRect(buffer, &area, fillcol);
|
|
/* bottom left */
|
|
area.x = map[curmap].obj[anchoreditem].x - screenx;
|
|
area.y = map[curmap].obj[anchoreditem].y + map[curmap].obj[anchoreditem].h - area.h - screeny;
|
|
SDL_FillRect(buffer, &area, fillcol);
|
|
/* bottom right */
|
|
area.x = map[curmap].obj[anchoreditem].x + map[curmap].obj[anchoreditem].w - area.w - screenx;
|
|
area.y = map[curmap].obj[anchoreditem].y + map[curmap].obj[anchoreditem].h - area.h - screeny;
|
|
SDL_FillRect(buffer, &area, fillcol);
|
|
}
|
|
|
|
} else if (map[curmap].selecteditemtype == T_LINK) {
|
|
/* 10% of map[curmap].object's size */
|
|
area.w = LINESELHANDLESIZE;
|
|
area.h = LINESELHANDLESIZE;
|
|
|
|
fillcol = SDL_MapRGB(buffer->format, 0, 0, 0);
|
|
|
|
/* start of line */
|
|
area.x = map[curmap].obj[map[curmap].olink[map[curmap].selecteditem].srcobj].x + map[curmap].olink[map[curmap].selecteditem].srcxoff - (LINESELHANDLESIZE/2) - screenx;
|
|
area.y = map[curmap].obj[map[curmap].olink[map[curmap].selecteditem].srcobj].y + map[curmap].olink[map[curmap].selecteditem].srcyoff - (LINESELHANDLESIZE/2) - screeny;
|
|
SDL_FillRect(buffer, &area, fillcol);
|
|
/* end of line */
|
|
area.x = map[curmap].obj[map[curmap].olink[map[curmap].selecteditem].dstobj].x + map[curmap].olink[map[curmap].selecteditem].dstxoff - (LINESELHANDLESIZE/2) - screenx;
|
|
area.y = map[curmap].obj[map[curmap].olink[map[curmap].selecteditem].dstobj].y + map[curmap].olink[map[curmap].selecteditem].dstyoff - (LINESELHANDLESIZE/2) - screeny;
|
|
SDL_FillRect(buffer, &area, fillcol);
|
|
|
|
/* points on the line */
|
|
for (i = 0; i < map[curmap].olink[map[curmap].selecteditem].npoints; i++) {
|
|
area.x = map[curmap].olink[map[curmap].selecteditem].point[i].x - (LINESELHANDLESIZE/2) - screenx;
|
|
area.y = map[curmap].olink[map[curmap].selecteditem].point[i].y - (LINESELHANDLESIZE/2) - screeny;
|
|
SDL_FillRect(buffer, &area, fillcol);
|
|
}
|
|
} else if (map[curmap].selecteditemtype == T_LINKPOINT) {
|
|
/* highlight the line in green */
|
|
/* 10% of map[curmap].object's size */
|
|
area.w = LINESELHANDLESIZE;
|
|
area.h = LINESELHANDLESIZE;
|
|
|
|
fillcol = SDL_MapRGB(buffer->format, 0, 255, 0);
|
|
|
|
/* start of line */
|
|
area.x = map[curmap].obj[map[curmap].olink[map[curmap].selecteditem].srcobj].x + map[curmap].olink[map[curmap].selecteditem].srcxoff - (LINESELHANDLESIZE/2) - screenx;
|
|
area.y = map[curmap].obj[map[curmap].olink[map[curmap].selecteditem].srcobj].y + map[curmap].olink[map[curmap].selecteditem].srcyoff - (LINESELHANDLESIZE/2) - screeny;
|
|
SDL_FillRect(buffer, &area, fillcol);
|
|
/* end of line */
|
|
area.x = map[curmap].obj[map[curmap].olink[map[curmap].selecteditem].dstobj].x + map[curmap].olink[map[curmap].selecteditem].dstxoff - (LINESELHANDLESIZE/2) - screenx;
|
|
area.y = map[curmap].obj[map[curmap].olink[map[curmap].selecteditem].dstobj].y + map[curmap].olink[map[curmap].selecteditem].dstyoff - (LINESELHANDLESIZE/2) - screeny;
|
|
SDL_FillRect(buffer, &area, fillcol);
|
|
|
|
/* points on the line */
|
|
for (i = 0; i < map[curmap].olink[map[curmap].selecteditem].npoints; i++) {
|
|
if (i == map[curmap].selectedlinkpoint) {
|
|
fillcol = SDL_MapRGB(buffer->format, 0, 0, 0);
|
|
} else {
|
|
fillcol = SDL_MapRGB(buffer->format, 0, 255, 0);
|
|
}
|
|
area.x = map[curmap].olink[map[curmap].selecteditem].point[i].x - (LINESELHANDLESIZE/2) - screenx;
|
|
area.y = map[curmap].olink[map[curmap].selecteditem].point[i].y - (LINESELHANDLESIZE/2) - screeny;
|
|
SDL_FillRect(buffer, &area, fillcol);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* blit buffer to screen */
|
|
SDL_BlitSurface(buffer, 0, screen,0);
|
|
|
|
if (testing) {
|
|
printf("START MAPBOX\n"); fflush(STDOUT);
|
|
}
|
|
drawmapbox();
|
|
|
|
/* draw status bar */
|
|
if (wantdecs) {
|
|
if (testing) {
|
|
printf("START STATUSBAR\n"); fflush(STDOUT);
|
|
}
|
|
drawstatusbar();
|
|
}
|
|
|
|
if (testing) {
|
|
printf("FLIP\n"); fflush(STDOUT);
|
|
}
|
|
|
|
if (wantdecs) {
|
|
/* draw scrollbars, if required */
|
|
if (map[curmap].width > (screen->w - SIDEBARW)) {
|
|
drawxscrollbar();
|
|
}
|
|
if (map[curmap].height > (screen->h - STATUSH)) {
|
|
drawyscrollbar();
|
|
}
|
|
}
|
|
|
|
/* calculate mapdimensions if diagram has been modified */
|
|
if (needtocalc) {
|
|
calcmapdimensions();
|
|
needtocalc = FALSE;
|
|
}
|
|
|
|
/* flip */
|
|
SDL_Flip(screen);
|
|
//SDL_UpdateRect(screen, 0, 0, map[curmap].width, map[curmap].height);
|
|
}
|
|
|
|
void drawxscrollbar(void) {
|
|
int barw;
|
|
double barx;
|
|
|
|
barx = ((double)screenx / (double)map[curmap].width) * (screen->w - SIDEBARW - SBSIZE);
|
|
|
|
/* scrollbar outline */
|
|
drawbox(screen, 0, screen->h - STATUSH - SBSIZE,
|
|
screen->w - SIDEBARW - SBSIZE, screen->h - STATUSH - 1, blue2 , &blue2);
|
|
|
|
/* screen position */
|
|
barw = (((double)(screen->w - SIDEBARW - SBSIZE) / (double)map[curmap].width) * (screen->w - SIDEBARW - SBSIZE));
|
|
if (barx+barw > (screen->w - SIDEBARW-SBSIZE)) barw = screen->w - SIDEBARW - SBSIZE - barx;
|
|
|
|
drawbox(screen, barx, screen->h - STATUSH - SBSIZE+1,
|
|
barx + barw, screen->h - STATUSH - 2, blue , &blue);
|
|
|
|
SDL_UpdateRect(screen, 0,screen->h - STATUSH - SBSIZE, screen->w, SBSIZE);
|
|
}
|
|
|
|
void drawyscrollbar(void) {
|
|
int barh;
|
|
double bary;
|
|
|
|
bary = ((double)screeny / (double)map[curmap].height) * (screen->h - STATUSH - SBSIZE);
|
|
|
|
/* scrollbar outline */
|
|
drawbox(screen, screen->w - SIDEBARW - SBSIZE, 0,
|
|
screen->w - SIDEBARW - 2, screen->h - STATUSH - SBSIZE - 1, blue2, &blue2);
|
|
|
|
/* screen position */
|
|
barh = (((double)(screen->h - STATUSH - SBSIZE) / (double)map[curmap].height) * (screen->h - STATUSH - SBSIZE));
|
|
if (bary+barh > (screen->h - STATUSH - SBSIZE)) barh = screen->h - STATUSH - SBSIZE - bary;
|
|
|
|
drawbox(screen, screen->w - SIDEBARW - SBSIZE+1, bary,
|
|
screen->w - SIDEBARW - 3, bary + barh, blue , &blue);
|
|
|
|
SDL_UpdateRect(screen, screen->w - SIDEBARW - SBSIZE, 0, SBSIZE, screen->h - STATUSH - SBSIZE - 1);
|
|
}
|
|
|
|
void validatescreenpos(void) {
|
|
if (screenx + (screen->w - SIDEBARW) > map[curmap].width) {
|
|
screenx = map[curmap].width - (screen->w - SIDEBARW);
|
|
}
|
|
if (screenx < 0) screenx = 0;
|
|
|
|
if (screeny + (screen->h - STATUSH) > map[curmap].height) {
|
|
screeny = map[curmap].height - (screen->h - STATUSH);
|
|
}
|
|
if (screeny < 0) screeny = 0;
|
|
}
|
|
|
|
void drawsearchflash(void) {
|
|
SDL_Surface *temps;
|
|
SDL_Rect area;
|
|
int txoff,tyoff;
|
|
int anchoreditem;
|
|
|
|
|
|
if (!searchflash) {
|
|
return;
|
|
}
|
|
/* highlight the object just found in a search */
|
|
if (map[curmap].selecteditem != -1) {
|
|
if (map[curmap].selecteditemtype == T_TEXT) {
|
|
int th;
|
|
|
|
/* calculate text's height */
|
|
th = TTF_FontHeight(font[map[curmap].textob[map[curmap].selecteditem].h]);
|
|
|
|
area.w = map[curmap].textob[map[curmap].selecteditem].w;
|
|
area.h = th;
|
|
|
|
anchoreditem = map[curmap].textob[map[curmap].selecteditem].anchor;
|
|
if (anchoreditem == -1) {
|
|
txoff = 0;
|
|
tyoff = 0;
|
|
} else {
|
|
txoff = map[curmap].obj[anchoreditem].x;
|
|
tyoff = map[curmap].obj[anchoreditem].y;
|
|
}
|
|
area.x = map[curmap].textob[map[curmap].selecteditem].x - screenx + txoff;
|
|
area.y = map[curmap].textob[map[curmap].selecteditem].y - screeny + tyoff;
|
|
|
|
/* restore background */
|
|
SDL_BlitSurface(searchbg, NULL, screen, &area);
|
|
|
|
/* draw hilight */
|
|
temps = SDL_CreateRGBSurface(SDL_SWSURFACE,area.w, area.h,
|
|
screen->format->BitsPerPixel, screen->format->Rmask,
|
|
screen->format->Gmask,screen->format->Bmask,
|
|
screen->format->Amask);
|
|
SDL_FillRect(temps, 0, SDL_MapRGB(temps->format, 0, 0, 255));
|
|
SDL_SetColorKey(temps, SDL_SRCCOLORKEY|SDL_RLEACCEL, SDL_MapRGB(temps->format, 255, 255, 255));
|
|
SDL_SetAlpha(temps, SDL_SRCALPHA, searchflash);
|
|
SDL_BlitSurface(temps, NULL, screen, &area);
|
|
SDL_FreeSurface(temps);
|
|
SDL_UpdateRect(screen, area.x, area.y, area.w, area.h);
|
|
}
|
|
}
|
|
}
|
|
|
|
void drawstatusbar(void) {
|
|
Uint32 col;
|
|
SDL_Rect area;
|
|
|
|
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 = screen->h - STATUSH;
|
|
area.w = screen->w - SIDEBARW;
|
|
area.h = DEFTEXTH + 4;
|
|
SDL_FillRect(screen, &area, col);
|
|
|
|
if ((errorflash) || (infoflash)) {
|
|
statusbarcolour.r = 255;
|
|
statusbarcolour.g = 255;
|
|
statusbarcolour.b = 255;
|
|
}
|
|
|
|
drawline(screen, 0, screen->h - STATUSH, screen->w - SIDEBARW, screen->h - STATUSH, blue,1);
|
|
|
|
/* strip newlines from text */
|
|
if (statustext[strlen(statustext)-1] == '\n')
|
|
statustext[strlen(statustext)-1] = '\0';
|
|
|
|
drawtextat(screen, 2, screen->h - DEFTEXTH-2, statustext, DEFTEXTH, black);
|
|
|
|
/* show modified status */
|
|
if (modified) {
|
|
int tw,th;
|
|
|
|
/* calculate width */
|
|
TTF_SizeText(font[DEFTEXTH-1], "MOD", &tw,&th);
|
|
drawbox(screen, screen->w - SIDEBARW-33,screen->h - STATUSH+1,
|
|
screen->w - SIDEBARW-30+tw+1,screen->h - STATUSH+2+th,blue, NULL);
|
|
|
|
drawtextat(screen, screen->w - SIDEBARW-30, screen->h - DEFTEXTH - 2, "MOD", DEFTEXTH-1, blue);
|
|
}
|
|
/* show readonly status */
|
|
if (readonly) {
|
|
int tw,th;
|
|
|
|
TTF_SizeText(font[DEFTEXTH-1], "RO", &tw,&th);
|
|
|
|
/* same place as 'mod' box, as in readonly mode map can't be modified */
|
|
drawbox(screen, screen->w - SIDEBARW-33,screen->h - STATUSH+1,
|
|
screen->w - SIDEBARW-30+tw+1,screen->h - STATUSH+2+th,blue, NULL);
|
|
drawtextat(screen, screen->w - SIDEBARW-30, screen->h - DEFTEXTH - 2, "RO", DEFTEXTH-1, blue);
|
|
}
|
|
|
|
SDL_UpdateRect(screen, area.x, area.y, area.w, area.h);
|
|
}
|
|
|
|
int drawSVG(char *svgfilename) {
|
|
int i;
|
|
if (startSVG(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)) {
|
|
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]);
|
|
}
|
|
} 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]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
endSVG();
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
void drawmapbox(void) {
|
|
text_t temp;
|
|
int x,y;
|
|
int i;
|
|
int lh = MAPBOXTEXTHEIGHT;
|
|
int found;
|
|
int n;
|
|
Uint32 fillcol;
|
|
SDL_Rect area;
|
|
int tw,th;
|
|
char temptext[BUFLEN];
|
|
int changed;
|
|
int donesomething;
|
|
char name1[BUFLEN], name2[BUFLEN];
|
|
|
|
|
|
x = mapbox.x+1;
|
|
y = mapbox.y+1;
|
|
|
|
/* clear it */
|
|
area.x = mapbox.x;
|
|
area.y = mapbox.y;
|
|
area.w = screen->w - mapbox.x;
|
|
area.h = mapbox.height;
|
|
|
|
fillcol = SDL_MapRGB(screen->format, 90, 90, 90);
|
|
|
|
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);
|
|
|
|
drawbox(screen, mapbox.x+1, mapbox.y+1, mapbox.x + mapbox.width-3,mapbox.y + th,white, &white);
|
|
|
|
/* current map */
|
|
/* centre this inside the map box */
|
|
drawtextat(screen, (x+((mapbox.width-3)/2) - (tw/2)), y, temptext, lh, black);
|
|
|
|
y += th;
|
|
|
|
/* seperator line */
|
|
drawline(screen, x, y, x+mapbox.width-2, y, white,1);
|
|
y++;
|
|
|
|
/* show .. */
|
|
if (numhistory >= 1) {
|
|
/* draw back arrow */
|
|
drawline(screen, x+5,y+(lh/2),x+mapbox.width-15,y+(lh/2),white,1);
|
|
drawline(screen, x+5,y+(lh/2),x+15,y+1,white,1);
|
|
drawline(screen, x+5,y+(lh/2),x+15,y+(lh-1),white,1);
|
|
|
|
}
|
|
y += th;
|
|
|
|
/* children ... */
|
|
/* first generate list of children */
|
|
|
|
numchildren = 0;
|
|
|
|
for (i = 0; i < map[curmap].numobjects; i++) {
|
|
if (map[curmap].obj[i].child != -1) {
|
|
/* make sure we haven't already drawn this name */
|
|
found = FALSE;
|
|
for (n = 0; n < numchildren; n++) {
|
|
if (children[n] == map[curmap].obj[i].child) {
|
|
found = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
if (!found) {
|
|
children[numchildren] = map[curmap].obj[i].child;
|
|
numchildren++;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* 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)) {
|
|
/* replace this entry with an arrow */
|
|
children[i] = C_SCROLLUP;
|
|
/* draw an up arrow */
|
|
TTF_SizeText(font[lh], "unused", &tw,&th);
|
|
drawline(screen, x + (mapbox.width / 2)-3, y+th-4,
|
|
x + (mapbox.width / 2), y+th-7,
|
|
white, 1);
|
|
drawline(screen, x + (mapbox.width / 2)+3, y+th-4,
|
|
x + (mapbox.width / 2), y+th-7,
|
|
white, 1);
|
|
} else {
|
|
/* get its name */
|
|
sprintf(temp.text, "*Unknown*"); /* default, shouldn't actually ever be used */
|
|
for (n = 0; n < map[curmap].numobjects; n++) {
|
|
if (map[curmap].obj[n].child == children[i]) {
|
|
sprintf(temp.text, map[map[curmap].obj[n].child].name);
|
|
break;
|
|
}
|
|
}
|
|
|
|
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;
|
|
|
|
/* 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;
|
|
/* off the bottom of the page - replace previous item with an arrow */
|
|
|
|
y = y - th - 1; /* go back one line */
|
|
/* clear previous text */
|
|
ar.x = x;
|
|
ar.y = y;
|
|
ar.w = mapbox.width - 3;
|
|
ar.h = th;
|
|
SDL_FillRect(screen, &ar, fillcol);
|
|
|
|
/* draw arrow */
|
|
drawline(screen, x + (mapbox.width / 2)-3, y+th-7,
|
|
x + (mapbox.width / 2), y+th-4,
|
|
white, 1);
|
|
drawline(screen, x + (mapbox.width / 2)+3, y+th-7,
|
|
x + (mapbox.width / 2), y+th-4,
|
|
white, 1);
|
|
|
|
children[i-1] = C_SCROLLDOWN;
|
|
break;
|
|
}
|
|
|
|
drawtext(screen, &temp, FALSE);
|
|
}
|
|
|
|
y += th;
|
|
}
|
|
|
|
SDL_UpdateRect(screen, mapbox.x, mapbox.y, screen->w - mapbox.x,mapbox.height+2);
|
|
//SDL_Flip(screen);
|
|
}
|
|
|
|
void drawmaplist(SDL_Surface *dest) {
|
|
int x,y;
|
|
int i;
|
|
Uint32 fillcol;
|
|
SDL_Rect area;
|
|
|
|
/* clear screen*/
|
|
|
|
fillcol = SDL_MapRGB(screen->format, map[curmap].bgcol.r,map[curmap].bgcol.g,map[curmap].bgcol.b);
|
|
area.x = 0;
|
|
area.y = 0;
|
|
area.w = screen->w - SIDEBARW;
|
|
area.h = screen->h - STATUSH;
|
|
SDL_FillRect(screen, &area, fillcol);
|
|
|
|
x = 10;
|
|
y = 10;
|
|
|
|
drawtextat(screen, x, y, "Select map to link to:", DEFTEXTH*2, black);
|
|
|
|
y = 50;
|
|
|
|
drawbox(dest, x, y, screen->w-SIDEBARW-1,y+(DEFTEXTH*2),blue, NULL);
|
|
drawtextat(screen, x+1, y+1, "(none)", (DEFTEXTH*2)-2, blue);
|
|
|
|
|
|
y += (DEFTEXTH*2);
|
|
|
|
for (i = maplistpos; i < nummaps; i++) {
|
|
drawbox(dest, x, y, screen->w-SIDEBARW-1,y+(DEFTEXTH*2),blue, NULL);
|
|
drawtextat(dest, x+1, y+1, map[i].name, (DEFTEXTH*2)-2, blue);
|
|
|
|
y += (DEFTEXTH*2);
|
|
|
|
}
|
|
|
|
SDL_Flip(screen);
|
|
}
|
|
|
|
void drawobox(void) {
|
|
int x,y,i;
|
|
SDL_Rect area;
|
|
mapobject_t temp;
|
|
Uint32 fillcol;
|
|
SDL_Color outlinecol;
|
|
int outlinepos;
|
|
int fitx,fity,fit;
|
|
|
|
fillcol = SDL_MapRGB(screen->format, obox.bgcol.r,obox.bgcol.g,obox.bgcol.b);
|
|
area.x = obox.x;
|
|
area.y = obox.y;
|
|
area.w = obox.width;
|
|
area.h = obox.height+4;
|
|
SDL_FillRect(screen, &area, fillcol);
|
|
|
|
x = obox.x;
|
|
y = obox.y;
|
|
|
|
|
|
/* calculate how many items we can fit in the obox */
|
|
/* figure out how many objects we can fit in the box */
|
|
fitx = (obox.width / obox.gridsize);
|
|
fity = ((obox.height+3) / obox.gridsize);
|
|
fit = fitx * fity;
|
|
|
|
for (i = (obox.pos*3); i < numobjtypes; i++) {
|
|
int n;
|
|
|
|
if ((x + obox.gridsize) >= (screen->w)) {
|
|
x = obox.x;
|
|
if ((y + obox.gridsize) >= (screen->h)) {
|
|
break;
|
|
}
|
|
y += obox.gridsize + 3;
|
|
}
|
|
/* draw box */
|
|
//outlinecol = obox.gridcol;
|
|
drawline(screen, x, y,x+obox.gridsize,y,gridhigh,1); /* top */
|
|
drawline(screen, x, y+obox.gridsize,x+obox.gridsize,y+obox.gridsize,gridlow,1); /* bottom */
|
|
drawline(screen, x, y,x,y+obox.gridsize,gridhigh,1); /* left */
|
|
drawline(screen, x+obox.gridsize, y,x+obox.gridsize,y+obox.gridsize,gridlow,1); /* right */
|
|
/* fill it */
|
|
fillcol = SDL_MapRGB(screen->format, obox.gridbgcol.r,obox.gridbgcol.g,obox.gridbgcol.b);
|
|
area.x = x+1;
|
|
area.y = y+1;
|
|
area.w = obox.gridsize-1;
|
|
area.h = obox.gridsize-1;
|
|
SDL_FillRect(screen, &area, fillcol);
|
|
|
|
/* draw object */
|
|
temp.type = i;
|
|
temp.x = x+1;
|
|
temp.y = y+1;
|
|
temp.w = obox.gridsize-2;
|
|
temp.h = obox.gridsize-2;
|
|
temp.fillcol.r = 0;
|
|
temp.fillcol.g = 0;
|
|
temp.fillcol.b = 0;
|
|
temp.fillcol.unused = 0;
|
|
drawobject(screen, &temp, TRUE, FALSE);
|
|
|
|
/* show keyboard shortcuts */
|
|
for (n = 0; n < shortcutnum; n++) {
|
|
if (shortcut[n] == i) {
|
|
SDL_Surface *ts;
|
|
SDL_Rect area;
|
|
char numtext[2];
|
|
int tw,th;
|
|
SDL_Color fc = yellow;
|
|
|
|
sprintf(numtext, "%d",n);
|
|
|
|
ts = TTF_RenderText_Blended(font[SHORTCUTSIZE], numtext, blue);
|
|
TTF_SizeText(font[SHORTCUTSIZE], numtext, &tw,&th);
|
|
|
|
fc.unused |= USECOLOUR;
|
|
|
|
drawbox(screen,x+2,y - 2 + (obox.gridsize) - SHORTCUTSIZE,
|
|
x+2+tw, y + (obox.gridsize) - SHORTCUTSIZE + tw,
|
|
yellow, &fc);
|
|
|
|
|
|
area.x = x + 3;
|
|
area.y = y + (obox.gridsize) - 4 - SHORTCUTSIZE;
|
|
area.w = tw;
|
|
area.h = th;
|
|
|
|
SDL_BlitSurface(ts, 0, screen, &area);
|
|
SDL_FreeSurface(ts);
|
|
ts = NULL;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
//SDL_UpdateRect(screen, x, y, obox.gridsize+1,obox.gridsize+1);
|
|
|
|
x += obox.gridsize+3;
|
|
|
|
}
|
|
|
|
/* draw selector */
|
|
outlinecol = red;
|
|
outlinepos = map[curmap].selectedtype - (obox.pos*3);
|
|
|
|
if ((outlinepos >= 0) && (outlinepos < fit)) {
|
|
y = ((map[curmap].selectedtype - (obox.pos*3)) / obox.gridrowlen) * (obox.gridsize+3) + obox.y;
|
|
x = ((map[curmap].selectedtype - (obox.pos*3)) % obox.gridrowlen) * (obox.gridsize+3) + obox.x;
|
|
|
|
drawline(screen, x, y,x+obox.gridsize,y,outlinecol,1); /* top */
|
|
drawline(screen, x, y+obox.gridsize,x+obox.gridsize,y+obox.gridsize,outlinecol,1); /* bottom */
|
|
drawline(screen, x, y,x,y+obox.gridsize,outlinecol,1); /* left */
|
|
drawline(screen, x+obox.gridsize, y,x+obox.gridsize,y+obox.gridsize,outlinecol,1); /* right */
|
|
}
|
|
|
|
//SDL_UpdateRect(screen, x, y, obox.gridsize+1,obox.gridsize+1);
|
|
|
|
//SDL_UpdateRect(screen,obox.x, obox.y, obox.width-1, obox.height+5);
|
|
SDL_Flip(screen);
|
|
}
|
|
|
|
void drawscreen(void){
|
|
drawmap(TRUE);
|
|
drawtoolbox();
|
|
drawobox();
|
|
SDL_Flip(screen);
|
|
}
|
|
|
|
void drawtext(SDL_Surface *dest, text_t *t, int adjust) {
|
|
int tw,th;
|
|
int txoff,tyoff;
|
|
|
|
SDL_Rect area;
|
|
SDL_Surface *ts;
|
|
|
|
if (strlen(t->text) == 0) {
|
|
return;
|
|
}
|
|
|
|
/* calculate letter width, letter height */
|
|
tw = t->w / strlen(t->text);
|
|
th = t->h;
|
|
|
|
if (t->anchor == -1) {
|
|
txoff = 0;
|
|
tyoff = 0;
|
|
} else {
|
|
txoff = map[curmap].obj[t->anchor].x;
|
|
tyoff = map[curmap].obj[t->anchor].y;
|
|
}
|
|
|
|
|
|
if (th >= MAXLETTERHEIGHT) th = MAXLETTERHEIGHT-1;
|
|
ts = TTF_RenderText_Blended(font[th], t->text, t->c);
|
|
area.x = t->x + txoff;
|
|
area.y = t->y + tyoff;
|
|
area.w = t->w;
|
|
area.h = t->h;
|
|
|
|
if (adjust) {
|
|
area.x -= screenx;
|
|
area.y -= screeny;
|
|
}
|
|
|
|
SDL_BlitSurface(ts, 0, dest, &area);
|
|
SDL_FreeSurface(ts);
|
|
ts = NULL;
|
|
|
|
}
|
|
|
|
|
|
/* x or y == -1 means to centre */
|
|
void drawtextat(SDL_Surface *dest, int x, int y, char *text, int size, SDL_Color c) {
|
|
int tw,th;
|
|
text_t temp;
|
|
|
|
sprintf(temp.text, text);
|
|
temp.h = size;
|
|
TTF_SizeText(font[size], temp.text, &tw,&th);
|
|
temp.w = tw;
|
|
if (x >= 0) {
|
|
temp.x = x;
|
|
} else {
|
|
temp.x = ((screen->w-SIDEBARW) / 2) - (tw / 2);
|
|
}
|
|
if (y >= 0) {
|
|
temp.y = y;
|
|
} else {
|
|
temp.y = ((screen->h-STATUSH) / 2) - (th / 2);
|
|
}
|
|
temp.c.r = c.r;
|
|
temp.c.g = c.g;
|
|
temp.c.b = c.b;
|
|
temp.anchor = -1;
|
|
|
|
drawtext(dest, &temp, FALSE);
|
|
}
|
|
|
|
void drawtextSVG(text_t *t) {
|
|
int tw,th;
|
|
int txoff,tyoff;
|
|
|
|
if (strlen(t->text) == 0) {
|
|
return;
|
|
}
|
|
|
|
/* calculate letter width, letter height */
|
|
tw = t->w / strlen(t->text);
|
|
th = t->h;
|
|
|
|
|
|
if (t->anchor == -1) {
|
|
txoff = 0;
|
|
tyoff = 0;
|
|
} else {
|
|
txoff = map[curmap].obj[t->anchor].x;
|
|
tyoff = map[curmap].obj[t->anchor].y;
|
|
}
|
|
|
|
|
|
if (th >= MAXLETTERHEIGHT) th = MAXLETTERHEIGHT-1;
|
|
|
|
/* have to add text pixel height here, cause SVG measures from bottom left of text - netmapr
|
|
measures from top left */
|
|
|
|
sprintf(svgbuf, "<text x=\"%d\" y=\"%d\" font-family=\"Verdana\" font-size=\"%d\" fill=\"rgb(%d,%d,%d)\" >\n",
|
|
t->x + txoff, t->y + tyoff + t->h, t->h, t->c.r, t->c.g, t->c.b);
|
|
fprintf(svgfile, svgbuf);
|
|
sprintf(svgbuf, "%s\n</text>\n",t->text);
|
|
fprintf(svgfile, svgbuf);
|
|
|
|
|
|
}
|
|
|
|
|
|
void drawtoolbox(void) {
|
|
int x,y,i;
|
|
SDL_Rect area;
|
|
Uint32 fillcol;
|
|
Uint32 bcol;
|
|
int z;
|
|
|
|
if (oldselection >= 0) dontpaste = TRUE;
|
|
|
|
fillcol = SDL_MapRGB(screen->format, toolbox.bgcol.r,toolbox.bgcol.g,toolbox.bgcol.b);
|
|
area.x = toolbox.x;
|
|
area.y = toolbox.y;
|
|
area.w = toolbox.width;
|
|
area.h = toolbox.height;
|
|
SDL_FillRect(screen, &area, fillcol);
|
|
|
|
x = toolbox.x;
|
|
y = toolbox.y;
|
|
|
|
/* draw each button */
|
|
for (i = 0; i < numbuttons; i++) {
|
|
if ((x + toolbox.gridsize) >= (screen->w)) {
|
|
x = toolbox.x;
|
|
y += toolbox.gridsize+3;
|
|
if ((y + toolbox.gridsize) >= (toolbox.height)) {
|
|
break;
|
|
}
|
|
}
|
|
/* draw box */
|
|
drawline(screen, x, y,x+toolbox.gridsize,y,gridhigh,1); /* top */
|
|
drawline(screen, x, y+1,x+toolbox.gridsize,y+1,gridhigh,1); /* top */
|
|
|
|
drawline(screen, x, y+toolbox.gridsize-1,x+toolbox.gridsize,y+toolbox.gridsize-1,gridlow,1); /* bottom */
|
|
drawline(screen, x, y+toolbox.gridsize,x+toolbox.gridsize,y+toolbox.gridsize,gridlow,1); /* bottom */
|
|
|
|
drawline(screen, x, y,x,y+toolbox.gridsize,gridhigh,1); /* left */
|
|
drawline(screen, x+1, y,x+1,y+toolbox.gridsize-1,gridhigh,1); /* left */
|
|
|
|
drawline(screen, x+toolbox.gridsize, y+1,x+toolbox.gridsize,y+toolbox.gridsize,gridlow,1); /* right */
|
|
drawline(screen, x+toolbox.gridsize-1, y+1,x+toolbox.gridsize-1,y+toolbox.gridsize,gridlow,1); /* right */
|
|
|
|
for (z = y+2; z < y+toolbox.gridsize;z++) {
|
|
drawline(screen,x+2,z,x+toolbox.gridsize-2,z,gridmiddle,1);
|
|
}
|
|
|
|
area.x = x+2;
|
|
area.y = y+2;
|
|
area.w = toolbox.gridsize-4;
|
|
area.h = toolbox.gridsize-4;
|
|
|
|
/* set transparent colour on temp surface */
|
|
bcol = SDL_MapRGB(buffer->format, 0, 0, 0);
|
|
|
|
/* blit button image onto button */
|
|
SDL_SetColorKey(button[i].img, SDL_SRCCOLORKEY|SDL_RLEACCEL, bcol);
|
|
SDL_BlitSurface(button[i].img, 0, screen, &area);
|
|
|
|
/* special cases */
|
|
if (i == TB_FGCOL) {
|
|
floodfill(screen, area.x + 5, area.y + 5, fgcol);
|
|
}
|
|
if (i == TB_FILLCOL) {
|
|
if (objfillcol.unused & USECOLOUR) {
|
|
floodfill(screen, area.x + 5, area.y + 5, objfillcol);
|
|
} else {
|
|
floodfill(screen, area.x + 5, area.y + 5, black);
|
|
drawline(screen, area.x+(area.w/2)-3, area.y+(area.h/2)-3-4, area.x+(area.w/2)+3, area.y+(area.h/2)+3-4,white,1);
|
|
drawline(screen, area.x+(area.w/2)+3, area.y+(area.h/2)-3-4, area.x+(area.w/2)-3, area.y+(area.h/2)+3-4,white,1);
|
|
}
|
|
}
|
|
if (i == TB_GRID) {
|
|
if (grid) {
|
|
drawbox(screen, area.x+5,area.y+20,area.x + area.w - 15, area.y + area.h - 5, black, &black);
|
|
if (state == S_DRAWFLOW) {
|
|
drawbox(screen, area.x+area.w - 14,area.y+20,area.x + area.w - 7, area.y + area.h - 5, yellow, &yellow);
|
|
} else {
|
|
drawbox(screen, area.x+area.w - 14,area.y+20,area.x + area.w - 7, area.y + area.h - 5, green, &green);
|
|
}
|
|
} else {
|
|
drawbox(screen, area.x+5,area.y+20,area.x + area.w - 15, area.y + area.h - 5, red, &red);
|
|
drawbox(screen, area.x+area.w - 14,area.y+20,area.x + area.w - 7, area.y + area.h - 5, black, &black);
|
|
}
|
|
}
|
|
if (i == TB_LINESTYLE) {
|
|
int style;
|
|
/* show line thickness */
|
|
style = defthickness;
|
|
drawline(screen, area.x + 5,area.y+5-(defthickness/2),area.x + area.w - 5-defthickness, area.y+5-(defthickness/2)
|
|
,white,style);
|
|
/* show line style (dotted, dashed, etc)*/
|
|
style = (defstyle << 8) | 1;
|
|
//drawline(screen, area.x + 5,area.y+15,area.x + area.w - 5-defthickness, area.y+15 ,white,style);
|
|
drawline(screen, area.x + 5,area.y+15,area.x + area.w - 5, area.y+15 ,white,style);
|
|
|
|
/* show arrow style (start, end, none) */
|
|
style = (defarrow << 16) | 1;
|
|
drawline(screen, area.x + 5,area.y+24,area.x + area.w - 5, area.y+24 ,white,style);
|
|
}
|
|
if (i == TB_FLOW) {
|
|
if (showflows) {
|
|
drawbox(screen, area.x+5,area.y+20,area.x + area.w - 15, area.y + area.h - 5, black, &black);
|
|
if (state == S_DRAWFLOW) {
|
|
drawbox(screen, area.x+area.w - 14,area.y+20,area.x + area.w - 7, area.y + area.h - 5, yellow, &yellow);
|
|
} else {
|
|
drawbox(screen, area.x+area.w - 14,area.y+20,area.x + area.w - 7, area.y + area.h - 5, green, &green);
|
|
}
|
|
} else {
|
|
drawbox(screen, area.x+5,area.y+20,area.x + area.w - 15, area.y + area.h - 5, red, &red);
|
|
drawbox(screen, area.x+area.w - 14,area.y+20,area.x + area.w - 7, area.y + area.h - 5, black, &black);
|
|
}
|
|
}
|
|
|
|
SDL_UpdateRect(screen, x, y, toolbox.gridsize+3,toolbox.gridsize+3);
|
|
|
|
x += toolbox.gridsize+3;
|
|
|
|
}
|
|
|
|
/* draw selectors */
|
|
if (state == S_NONE) drawtoolboxselector(TB_POINTER, 0);
|
|
if (state == S_ADDOBJ) drawtoolboxselector(TB_ADDOBJ, 0);
|
|
if (state == S_CHANGEOBJECT) drawtoolboxselector(TB_ADDOBJ, 1);
|
|
if (state == S_ADDTEXT) drawtoolboxselector(TB_ADDTEXT, 0);
|
|
if (state == S_SAVING) drawtoolboxselector(TB_SAVE, 0);
|
|
if (state == S_LOADING) drawtoolboxselector(TB_LOAD, 0);
|
|
if (state == S_MATCHSIZE) drawtoolboxselector(TB_MATCHSIZE, 0);
|
|
if (state == S_MATCHX) drawtoolboxselector(TB_MATCHPOS, 0);
|
|
if (state == S_MATCHY) drawtoolboxselector(TB_MATCHPOS, 0);
|
|
if (state == S_CREATETELE) drawtoolboxselector(TB_CREATETELE, 0);
|
|
if (state == S_DRAWFLOW) drawtoolboxselector(TB_FLOW, 0);
|
|
|
|
|
|
}
|
|
|
|
void drawtoolboxselector(int buttonid, int altcolour) {
|
|
SDL_Color outlinecol;
|
|
int x,y;
|
|
|
|
/* draw selector */
|
|
if (altcolour) {
|
|
outlinecol = blue;
|
|
} else {
|
|
outlinecol = red;
|
|
}
|
|
y = (buttonid / toolbox.gridrowlen) * (toolbox.gridsize+3) + toolbox.y;
|
|
x = (buttonid % toolbox.gridrowlen) * (toolbox.gridsize+3) + toolbox.x;
|
|
|
|
drawline(screen, x, y,x+toolbox.gridsize,y,outlinecol,1); /* top */
|
|
drawline(screen, x, y+1,x+toolbox.gridsize,y+1,outlinecol,1); /* top */
|
|
drawline(screen, x, y+toolbox.gridsize,x+toolbox.gridsize,y+toolbox.gridsize,outlinecol,1); /* bottom */
|
|
drawline(screen, x, y+toolbox.gridsize-1,x+toolbox.gridsize,y+toolbox.gridsize-1,outlinecol,1); /* bottom */
|
|
drawline(screen, x, y,x,y+toolbox.gridsize,outlinecol,1); /* left */
|
|
drawline(screen, x+1, y,x+1,y+toolbox.gridsize,outlinecol,1); /* left */
|
|
drawline(screen, x+toolbox.gridsize, y,x+toolbox.gridsize,y+toolbox.gridsize,outlinecol,1); /* right */
|
|
drawline(screen, x+toolbox.gridsize-1, y,x+toolbox.gridsize-1,y+toolbox.gridsize,outlinecol,1); /* right */
|
|
|
|
SDL_UpdateRect(screen, x, y, toolbox.gridsize+3,toolbox.gridsize+3);
|
|
}
|
|
|
|
void drawvector(SDL_Surface *dest, vectorimg_t *vimg, int x, int y, int w, int h, SDL_Color *overridefg, SDL_Color *overridebg) {
|
|
float xscale,yscale;
|
|
int realx1, realy1;
|
|
int realx2, realy2;
|
|
int realx3, realy3;
|
|
int realx4, realy4;
|
|
int i;
|
|
SDL_Color linecol,fillcol, polycol, subobjfill;
|
|
SDL_Surface *temp;
|
|
SDL_Rect area;
|
|
Uint32 bgcol;
|
|
|
|
int left = 9999;
|
|
int right = -1;
|
|
int top = 9999;
|
|
int bottom = -1;
|
|
|
|
int insubobj = FALSE;
|
|
|
|
subobjfill.r = 0;
|
|
subobjfill.g = 0;
|
|
subobjfill.b = 0;
|
|
subobjfill.unused = 0;
|
|
|
|
temp = NULL;
|
|
|
|
xscale = (float)w / (float)vimg->w;
|
|
yscale = (float)h / (float)vimg->h;
|
|
|
|
polycol.unused = 0;
|
|
|
|
|
|
|
|
for (i = 0; i < vimg->vnum; i++) {
|
|
// select colour
|
|
if (overridefg == NULL) {
|
|
if (vimg->vector[i].c.unused == 255) {
|
|
linecol = fgcol;
|
|
} else {
|
|
linecol = vimg->vector[i].c;
|
|
}
|
|
} else {
|
|
linecol = *overridefg;
|
|
}
|
|
|
|
if (overridebg == NULL) {
|
|
//if (vimg->vector[i].c.unused == 255) {
|
|
/* used to display current colour in foreground/background buttons */
|
|
// fillcol = objfillcol;
|
|
//} else {
|
|
//fillcol = vimg->vector[i].c;
|
|
fillcol = vimg->vector[i].fc;
|
|
//}
|
|
} else {
|
|
fillcol = *overridebg;
|
|
}
|
|
|
|
// scale the coords of this vector
|
|
|
|
if (vimg->vector[i].type == VT_BEZIER) {
|
|
int ax,ay;
|
|
int bx,by;
|
|
int cx,cy;
|
|
int dx,dy;
|
|
|
|
ax = (vimg->vector[i].x1 & 0xffff0000) >> 16;
|
|
ay = (vimg->vector[i].y1 & 0xffff0000) >> 16;
|
|
bx = (vimg->vector[i].x1 & 0x0000ffff);
|
|
by = (vimg->vector[i].y1 & 0x0000ffff);
|
|
cx = (vimg->vector[i].x2 & 0xffff0000) >> 16;
|
|
cy = (vimg->vector[i].y2 & 0xffff0000) >> 16;
|
|
dx = (vimg->vector[i].x2 & 0x0000ffff);
|
|
dy = (vimg->vector[i].y2 & 0x0000ffff);
|
|
|
|
realx1 = ((float)ax * xscale);
|
|
realy1 = ((float)ay * yscale);
|
|
realx2 = ((float)bx * xscale);
|
|
realy2 = ((float)by * yscale);
|
|
realx3 = ((float)cx * xscale);
|
|
realy3 = ((float)cy * yscale);
|
|
realx4 = ((float)dx * xscale);
|
|
realy4 = ((float)dy * yscale);
|
|
} else {
|
|
realx1 = ((float)vimg->vector[i].x1 * xscale);
|
|
realy1 = ((float)vimg->vector[i].y1 * yscale);
|
|
realx2 = ((float)vimg->vector[i].x2 * xscale);
|
|
realy2 = ((float)vimg->vector[i].y2 * yscale);
|
|
realx3 = 0;
|
|
realy3 = 0;
|
|
realx4 = 0;
|
|
realy4 = 0;
|
|
}
|
|
|
|
|
|
/* create temp surface */
|
|
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,
|
|
screen->format->BitsPerPixel, screen->format->Rmask,
|
|
screen->format->Gmask,screen->format->Bmask, screen->format->Amask);
|
|
// clear temp surface to bg colour
|
|
bgcol = SDL_MapRGB(temp->format, 40, 50, 60);
|
|
SDL_FillRect(temp, NULL, bgcol);
|
|
SDL_SetColorKey(temp, SDL_SRCCOLORKEY|SDL_RLEACCEL, bgcol);
|
|
|
|
// initialise border colour
|
|
polycol = linecol;
|
|
|
|
left = 9999;
|
|
right = -1;
|
|
top = 9999;
|
|
bottom = -1;
|
|
}
|
|
} else if (vimg->vector[i].type != VT_ENDPOLY) {
|
|
if (!insubobj) {
|
|
temp = SDL_CreateRGBSurface(SDL_SWSURFACE,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
|
|
bgcol = SDL_MapRGB(temp->format, 40, 50, 60);
|
|
SDL_FillRect(temp, NULL, bgcol);
|
|
SDL_SetColorKey(temp, SDL_SRCCOLORKEY|SDL_RLEACCEL, bgcol);
|
|
}
|
|
}
|
|
|
|
|
|
/* draw this vector onto a temp surface */
|
|
switch (vimg->vector[i].type) {
|
|
case VT_LINE:
|
|
drawline(temp,realx1,realy1, realx2,realy2,linecol,1);
|
|
if (realx1 < left) left = realx1;
|
|
if (realx2 < left) left = realx2;
|
|
if (realx1 > right) right = realx1;
|
|
if (realx2 > right) right = realx2;
|
|
if (realy1 < top) top = realy1;
|
|
if (realy2 < top) top = realy2;
|
|
if (realy1 > bottom) bottom = realy1;
|
|
if (realy2 > bottom) bottom = realy2;
|
|
break;
|
|
case VT_POLY:
|
|
drawline(temp,realx1,realy1, realx2,realy2,polycol,1);
|
|
if (realx1 < left) left = realx1;
|
|
if (realx2 < left) left = realx2;
|
|
if (realx1 > right) right = realx1;
|
|
if (realx2 > right) right = realx2;
|
|
if (realy1 < top) top = realy1;
|
|
if (realy2 < top) top = realy2;
|
|
if (realy1 > bottom) bottom = realy1;
|
|
if (realy2 > bottom) bottom = realy2;
|
|
break;
|
|
case VT_SUBOBJ:
|
|
insubobj = TRUE;
|
|
subobjfill.r = fillcol.r;
|
|
subobjfill.g = fillcol.g;
|
|
subobjfill.b = fillcol.b;
|
|
subobjfill.unused |= USECOLOUR;
|
|
break;
|
|
case VT_ENDPOLY:
|
|
insubobj = FALSE;
|
|
if (subobjfill.unused & USECOLOUR) {
|
|
fillcol = subobjfill;
|
|
subobjfill.r = 0;
|
|
subobjfill.g = 0;
|
|
subobjfill.b = 0;
|
|
subobjfill.unused = 0;
|
|
}
|
|
floodfill(temp,(left+right)/2,(top+bottom)/2, fillcol);
|
|
//drawline(temp,(left+right)/2,(top+bottom)/2, (left+right)/2 + 1, (top+bottom)/2 + 1, fillcol, 1);
|
|
break;
|
|
case VT_BOX:
|
|
drawbox(temp,realx1,realy1, realx2,realy2,linecol, &fillcol);
|
|
if (realx1 < left) left = realx1;
|
|
if (realx2 < left) left = realx2;
|
|
if (realx1 > right) right = realx1;
|
|
if (realx2 > right) right = realx2;
|
|
if (realy1 < top) top = realy1;
|
|
if (realy2 < top) top = realy2;
|
|
if (realy1 > bottom) bottom = realy1;
|
|
if (realy2 > bottom) bottom = realy2;
|
|
break;
|
|
case VT_ELLIPSE:
|
|
drawellipse(temp,realx1,realy1, realx2,realy2, linecol);
|
|
if (realx1 - realx2 < left) left = realx1 - realx2;
|
|
if (realx1 + realx2 > right) right = realx1 + realx2;
|
|
if (realy1 - realy2 < top) top = realy1 - realy2;
|
|
if (realy1 + realy2 > bottom) bottom = realy1 + realy2;
|
|
|
|
break;
|
|
case VT_BEZIER:
|
|
drawbezier(temp,realx1,realy1,
|
|
realx2,realy2,
|
|
realx3,realy3,
|
|
realx4,realy4,
|
|
linecol);
|
|
if (realx1 < left) left = realx1;
|
|
if (realx2 < left) left = realx2;
|
|
if (realx3 < left) left = realx3;
|
|
if (realx4 < left) left = realx4;
|
|
if (realx1 > right) right = realx1;
|
|
if (realx2 > right) right = realx2;
|
|
if (realx3 > right) right = realx3;
|
|
if (realx3 > right) right = realx4;
|
|
if (realy1 < top) top = realy1;
|
|
if (realy2 < top) top = realy2;
|
|
if (realy3 < top) top = realy3;
|
|
if (realy4 < top) top = realy4;
|
|
if (realy1 > bottom) bottom = realy1;
|
|
if (realy2 > bottom) bottom = realy2;
|
|
if (realy3 > bottom) bottom = realy3;
|
|
if (realy4 > bottom) bottom = realy4;
|
|
break;
|
|
/*case VT_FILL:
|
|
floodfill(dest,realx1,realy1, fillcol);
|
|
break;
|
|
*/
|
|
}
|
|
|
|
if (vimg->vector[i].type != VT_POLY) {
|
|
if (!insubobj) {
|
|
// blit surface onto drawing surface
|
|
area.x = x;
|
|
area.y = y;
|
|
area.w = w;
|
|
area.h = h;
|
|
SDL_BlitSurface(temp, NULL, dest, &area);
|
|
}
|
|
}
|
|
|
|
/* free it */
|
|
if (vimg->vector[i].type != VT_POLY) {
|
|
if (!insubobj) {
|
|
SDL_FreeSurface(temp);
|
|
temp = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (temp != NULL) {
|
|
SDL_FreeSurface(temp);
|
|
temp = NULL;
|
|
}
|
|
return;
|
|
}
|
|
|
|
|
|
void drawvectorSVG(vectorimg_t *vimg, int x, int y, int w, int h, SDL_Color *overridefg, SDL_Color *overridebg) {
|
|
float xscale,yscale;
|
|
int realx1, realy1;
|
|
int realx2, realy2;
|
|
int realx3, realy3;
|
|
int realx4, realy4;
|
|
int i;
|
|
SDL_Color linecol,fillcol, polycol, subobjfill;
|
|
char temp[BUFLEN];
|
|
|
|
|
|
int left = 9999;
|
|
int right = -1;
|
|
int top = 9999;
|
|
int bottom = -1;
|
|
|
|
int insubobj = FALSE;
|
|
int inpoly = FALSE;
|
|
int inbez = FALSE;
|
|
|
|
subobjfill.r = 0;
|
|
subobjfill.g = 0;
|
|
subobjfill.b = 0;
|
|
subobjfill.unused = 0;
|
|
|
|
xscale = (float)w / (float)vimg->w;
|
|
yscale = (float)h / (float)vimg->h;
|
|
|
|
polycol.unused = 0;
|
|
|
|
|
|
printf("** called drawvector()\n");
|
|
|
|
|
|
for (i = 0; i < vimg->vnum; i++) {
|
|
// select colour
|
|
if (overridefg == NULL) {
|
|
if (vimg->vector[i].c.unused == 255) {
|
|
linecol = fgcol;
|
|
} else {
|
|
linecol = vimg->vector[i].c;
|
|
}
|
|
} else {
|
|
linecol = *overridefg;
|
|
}
|
|
|
|
if (overridebg == NULL) {
|
|
//if (vimg->vector[i].c.unused == 255) {
|
|
/* used to display current colour in foreground/background buttons */
|
|
// fillcol = objfillcol;
|
|
//} else {
|
|
//fillcol = vimg->vector[i].c;
|
|
fillcol = vimg->vector[i].fc;
|
|
//}
|
|
} else {
|
|
fillcol = *overridebg;
|
|
}
|
|
|
|
// scale the coords of this vector
|
|
|
|
if (vimg->vector[i].type == VT_BEZIER) {
|
|
int ax,ay;
|
|
int bx,by;
|
|
int cx,cy;
|
|
int dx,dy;
|
|
|
|
ax = (vimg->vector[i].x1 & 0xffff0000) >> 16;
|
|
ay = (vimg->vector[i].y1 & 0xffff0000) >> 16;
|
|
bx = (vimg->vector[i].x1 & 0x0000ffff);
|
|
by = (vimg->vector[i].y1 & 0x0000ffff);
|
|
cx = (vimg->vector[i].x2 & 0xffff0000) >> 16;
|
|
cy = (vimg->vector[i].y2 & 0xffff0000) >> 16;
|
|
dx = (vimg->vector[i].x2 & 0x0000ffff);
|
|
dy = (vimg->vector[i].y2 & 0x0000ffff);
|
|
|
|
realx1 = x+ ((float)ax * xscale);
|
|
realy1 = y+ ((float)ay * yscale);
|
|
realx2 = x+ ((float)bx * xscale);
|
|
realy2 = y+ ((float)by * yscale);
|
|
realx3 = x+ ((float)cx * xscale);
|
|
realy3 = y+ ((float)cy * yscale);
|
|
realx4 = x+ ((float)dx * xscale);
|
|
realy4 = y+ ((float)dy * yscale);
|
|
} else {
|
|
realx1 = x+ ((float)vimg->vector[i].x1 * xscale);
|
|
realy1 = y+ ((float)vimg->vector[i].y1 * yscale);
|
|
realx2 = x+ ((float)vimg->vector[i].x2 * xscale);
|
|
realy2 = y+ ((float)vimg->vector[i].y2 * yscale);
|
|
realx3 = 0;
|
|
realy3 = 0;
|
|
realx4 = 0;
|
|
realy4 = 0;
|
|
}
|
|
|
|
|
|
/* create temp surface */
|
|
if (vimg->vector[i].type == VT_POLY) {
|
|
/* start of polygon */
|
|
if (inpoly == FALSE) {
|
|
inpoly = TRUE;
|
|
polycol = linecol;
|
|
|
|
sprintf(svgbuf,"<path d=\"M%d %d ", realx1, realy1 );
|
|
}
|
|
}
|
|
|
|
/* draw this vector onto a temp surface */
|
|
switch (vimg->vector[i].type) {
|
|
case VT_LINE:
|
|
/* TODO: add style */
|
|
|
|
sprintf(svgbuf,"<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" style=\"stroke:rgb(%d,%d,%d);stroke-width=%d\"/>\n", realx1, realy1, realx2, realy2,linecol.r,linecol.g,linecol.b, 1 );
|
|
fprintf(svgfile, svgbuf);
|
|
break;
|
|
case VT_POLY:
|
|
sprintf(temp, "L%d %d ", realx2,realy2);
|
|
strcat(svgbuf, temp);
|
|
if (realx1 < left) left = realx1;
|
|
if (realx2 < left) left = realx2;
|
|
if (realx1 > right) right = realx1;
|
|
if (realx2 > right) right = realx2;
|
|
if (realy1 < top) top = realy1;
|
|
if (realy2 < top) top = realy2;
|
|
if (realy1 > bottom) bottom = realy1;
|
|
if (realy2 > bottom) bottom = realy2;
|
|
break;
|
|
case VT_SUBOBJ:
|
|
insubobj = TRUE;
|
|
subobjfill.r = fillcol.r;
|
|
subobjfill.g = fillcol.g;
|
|
subobjfill.b = fillcol.b;
|
|
subobjfill.unused |= USECOLOUR;
|
|
|
|
break;
|
|
case VT_ENDPOLY:
|
|
if (subobjfill.unused & USECOLOUR) {
|
|
fillcol = subobjfill;
|
|
subobjfill.r = 0;
|
|
subobjfill.g = 0;
|
|
subobjfill.b = 0;
|
|
subobjfill.unused = 0;
|
|
}
|
|
if (inpoly || inbez) {
|
|
sprintf(temp, "\" style=\"fill:rgb(%d,%d,%d);stroke:rgb(%d,%d,%d);stroke-width:1\"/>\n", fillcol.r, fillcol.g, fillcol.b, polycol.r, polycol.g, polycol.b);
|
|
strcat(svgbuf, temp);
|
|
fprintf(svgfile, svgbuf);
|
|
/*} else if (insubobj) {
|
|
sprintf(svgbuf, "\" style=\"fill:rgb(%d,%d,%d);stroke:rgb(%d,%d,%d);stroke-width:1\"/>\n", fillcol.r, fillcol.g, fillcol.b, polycol.r, polycol.g, polycol.b);
|
|
fprintf(svgfile, svgbuf);
|
|
*/
|
|
}
|
|
|
|
//sprintf(svgbuf, "<g id=\"group%d\" fill:rgb(%d,%d,%d) >\n", gnum,
|
|
|
|
inbez = FALSE;
|
|
insubobj = FALSE;
|
|
inpoly = FALSE;
|
|
break;
|
|
case VT_BOX:
|
|
if (fillcol.unused & USECOLOUR) {
|
|
sprintf(svgbuf,"<rect x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" style=\"fill:rgb(%d,%d,%d);stroke-width:1;stroke:rgb(%d,%d,%d)\"/>\n", realx1, realy1, realx2-realx1, realy2-realy1,fillcol.r,fillcol.g,fillcol.b, linecol.r,linecol.g,linecol.b );
|
|
} else {
|
|
sprintf(svgbuf,"<rect x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" style=\"stroke-width:1;stroke:rgb(%d,%d,%d)\"/>\n", realx1, realy1, realx2-realx1, realy2-realy1,linecol.r,linecol.g,linecol.b );
|
|
}
|
|
fprintf(svgfile, svgbuf);
|
|
break;
|
|
case VT_ELLIPSE:
|
|
if (insubobj) {
|
|
/* use colour from subobj */
|
|
sprintf(svgbuf,"<ellipse cx=\"%d\" cy=\"%d\" rx=\"%d\" ry=\"%d\" style=\"fill:rgb(%d,%d,%d);stroke-width:1;stroke:rgb(%d,%d,%d)\"/>\n", realx1, realy1, realx2-x, realy2 -y,subobjfill.r, subobjfill.g, subobjfill.b, linecol.r,linecol.g,linecol.b);
|
|
} else {
|
|
sprintf(svgbuf,"<ellipse cx=\"%d\" cy=\"%d\" rx=\"%d\" ry=\"%d\" style=\"stroke-width:1;stroke:rgb(%d,%d,%d)\"/>\n", realx1, realy1, realx2-x, realy2-y,linecol.r,linecol.g,linecol.b);
|
|
}
|
|
fprintf(svgfile, svgbuf);
|
|
break;
|
|
case VT_BEZIER:
|
|
/*TODO: implement */
|
|
if (insubobj) {
|
|
if (inbez) {
|
|
/*
|
|
sprintf(svgbuf,"T%d %d %d %d %d %d %d %d ",
|
|
realx1, realy1,
|
|
realx2, realy2,
|
|
realx3, realy3,
|
|
realx4, realy4
|
|
);
|
|
*/
|
|
sprintf(svgbuf," C%d %d %d %d %d %d",
|
|
realx2, realy2,
|
|
realx3, realy3,
|
|
realx4, realy4
|
|
);
|
|
fprintf(svgfile, svgbuf);
|
|
} else {
|
|
/*
|
|
sprintf(svgbuf,"<path d=\"M%d %d T%d %d %d %d %d %d %d %d ",
|
|
realx1, realy1,
|
|
realx1, realy1,
|
|
realx2, realy2,
|
|
realx3, realy3,
|
|
realx4, realy4
|
|
);
|
|
*/
|
|
sprintf(svgbuf,"<path d=\"M%d %d C%d %d %d %d %d %d",
|
|
realx1, realy1,
|
|
realx2, realy2,
|
|
realx3, realy3,
|
|
realx4, realy4
|
|
);
|
|
inbez = TRUE;
|
|
fprintf(svgfile, svgbuf);
|
|
|
|
polycol.r = linecol.r;
|
|
polycol.g = linecol.g;
|
|
polycol.b = linecol.b;
|
|
}
|
|
} else {
|
|
|
|
sprintf(svgbuf,"<path d=\"M%d %d C%d %d %d %d %d %d",
|
|
realx1, realy1,
|
|
realx2, realy2,
|
|
realx3, realy3,
|
|
realx4, realy4
|
|
);
|
|
|
|
fprintf(svgfile, svgbuf);
|
|
}
|
|
|
|
/*drawbezier(temp,realx1,realy1,
|
|
realx2,realy2,
|
|
realx3,realy3,
|
|
realx4,realy4,
|
|
linecol);
|
|
*/
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
// finish off beziers
|
|
if (vimg->vector[i].type == VT_BEZIER) {
|
|
if (insubobj) {
|
|
/* use colour from subobj */
|
|
sprintf(svgbuf,"\" style=\"fill:rgb(%d,%d,%d);stroke-width:1;stroke:rgb(%d,%d,%d)\"/>\n", subobjfill.r, subobjfill.g, subobjfill.b, linecol.r,linecol.g,linecol.b);
|
|
} else {
|
|
sprintf(svgbuf,"\" style=\"stroke-width:1;stroke:rgb(%d,%d,%d)\"/>\n", linecol.r,linecol.g,linecol.b);
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
int endtext(void) {
|
|
SDL_Rect area;
|
|
int tw,th;
|
|
|
|
/* paste old background */
|
|
if (bg != NULL) {
|
|
area.x = bgx;
|
|
area.y = bgy;
|
|
area.w = bg->w;
|
|
area.h = bg->h;
|
|
SDL_BlitSurface(bg,0,screen, &area);
|
|
SDL_UpdateRect(screen, bgx, bgy, bg->w, bg->h);
|
|
// free it
|
|
SDL_FreeSurface(bg);
|
|
bg = NULL;
|
|
}
|
|
|
|
if (strlen(text) == 0) {
|
|
sprintf(statustext,"Text entry aborted.");
|
|
changestate(S_NONE);
|
|
drawmap(TRUE);
|
|
return TRUE;
|
|
}
|
|
|
|
strcpy(map[curmap].textob[map[curmap].numtext].text, text);
|
|
map[curmap].textob[map[curmap].numtext].anchor = textanchor;
|
|
if (map[curmap].textob[map[curmap].numtext].anchor == -1) {
|
|
/* x,y = normal (ie. offset from 0,0) */
|
|
map[curmap].textob[map[curmap].numtext].x = startx;
|
|
map[curmap].textob[map[curmap].numtext].y = starty;
|
|
} else {
|
|
/* x,y = offset from anchor map[curmap].object's coordinates */
|
|
map[curmap].textob[map[curmap].numtext].x = startx - map[curmap].obj[textanchor].x;
|
|
map[curmap].textob[map[curmap].numtext].y = starty - map[curmap].obj[textanchor].y;
|
|
}
|
|
|
|
/* adjust for grid */
|
|
if (grid) {
|
|
int m;
|
|
|
|
m = map[curmap].textob[map[curmap].numtext].x;
|
|
map[curmap].textob[map[curmap].numtext].x -= (m % gridsize);
|
|
|
|
m = map[curmap].textob[map[curmap].numtext].y;
|
|
map[curmap].textob[map[curmap].numtext].y -= (m % gridsize);
|
|
}
|
|
|
|
|
|
/* calculate width */
|
|
TTF_SizeText(font[DEFTEXTH], text, &tw,&th);
|
|
|
|
|
|
map[curmap].textob[map[curmap].numtext].w = tw;
|
|
map[curmap].textob[map[curmap].numtext].h = DEFTEXTH;
|
|
map[curmap].textob[map[curmap].numtext].c = fgcol;
|
|
map[curmap].textob[map[curmap].numtext].c.unused |= ~(ISFLOW);
|
|
|
|
/* add to 'thing' list */
|
|
map[curmap].thing[map[curmap].numthings].type = T_TEXT;
|
|
map[curmap].thing[map[curmap].numthings].id = map[curmap].numtext;
|
|
|
|
|
|
setmod(TRUE);
|
|
sprintf(statustext,"Added text object #%d: '%s'.",map[curmap].numtext, map[curmap].textob[map[curmap].numtext].text);
|
|
drawstatusbar();
|
|
|
|
map[curmap].numtext++;
|
|
map[curmap].numthings++;
|
|
|
|
|
|
changestate(S_NONE);
|
|
|
|
drawmap(TRUE);
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
int endtextedit(void) {
|
|
SDL_Rect area;
|
|
int tw,th;
|
|
int si;
|
|
|
|
/* paste old background */
|
|
if (bg != NULL) {
|
|
area.x = bgx;
|
|
area.y = bgy;
|
|
area.w = bg->w;
|
|
area.h = bg->h;
|
|
SDL_BlitSurface(bg,0,screen, &area);
|
|
SDL_UpdateRect(screen, bgx, bgy, bg->w, bg->h);
|
|
// free it
|
|
SDL_FreeSurface(bg);
|
|
bg = NULL;
|
|
}
|
|
|
|
if (strlen(text) == 0) {
|
|
return TRUE;
|
|
}
|
|
|
|
si = map[curmap].selecteditem;
|
|
|
|
/* update text */
|
|
strcpy(map[curmap].textob[si].text, text);
|
|
/* anchor, x, y, height don't change */
|
|
//map[curmap].textob[si].anchor = textanchor;
|
|
|
|
//map[curmap].textob[si].x = startx;
|
|
//map[curmap].textob[si].y = starty;
|
|
|
|
/* calculate & update width */
|
|
TTF_SizeText(font[map[curmap].textob[si].h], text, &tw,&th);
|
|
map[curmap].textob[si].w = tw;
|
|
|
|
setmod(TRUE);
|
|
sprintf(statustext,"Updated text object #%d to '%s'\n",si, map[curmap].textob[si].text);
|
|
drawstatusbar();
|
|
|
|
changestate(S_NONE);
|
|
|
|
drawmap(TRUE);
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
int endtextmove(int x, int y) {
|
|
int txoff,tyoff;
|
|
|
|
SDL_FreeSurface(shadow);
|
|
shadow = NULL;
|
|
SDL_FreeSurface(bg);
|
|
bg = NULL;
|
|
|
|
if (map[curmap].textob[map[curmap].curtext].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;
|
|
}
|
|
|
|
|
|
/* check position */
|
|
if ((map[curmap].textob[map[curmap].curtext].x + txoff + x - startx) >= (map[curmap].width - map[curmap].textob[map[curmap].curtext].w)) {
|
|
return -1;
|
|
}
|
|
if ((map[curmap].textob[map[curmap].curtext].y + tyoff + y - starty) >= (map[curmap].height - map[curmap].textob[map[curmap].curtext].h)) {
|
|
return -1;
|
|
}
|
|
if (map[curmap].textob[map[curmap].curtext].x + txoff <= 0) {
|
|
return -1;
|
|
}
|
|
if (map[curmap].textob[map[curmap].curtext].y + tyoff <= 0) {
|
|
return -1;
|
|
}
|
|
|
|
/* adjust for grid */
|
|
if (grid) {
|
|
int m;
|
|
|
|
m = map[curmap].textob[map[curmap].curtext].x + x - startx;
|
|
x = x - (m % gridsize);
|
|
|
|
m = map[curmap].textob[map[curmap].curtext].y + y - starty;
|
|
y = y - (m % gridsize);
|
|
}
|
|
|
|
map[curmap].textob[map[curmap].curtext].x += (x - startx);
|
|
map[curmap].textob[map[curmap].curtext].y += (y - starty);
|
|
|
|
setmod(TRUE);
|
|
return 0;
|
|
}
|
|
|
|
void floodfill(SDL_Surface *dest, int x, int y, SDL_Color fillcol) {
|
|
int testing;
|
|
SDL_Color bgcolor;
|
|
|
|
testing = 0;
|
|
|
|
//XXX: testing
|
|
if (testing) {
|
|
drawpixel(dest, x, y, fillcol);
|
|
} else {
|
|
|
|
getcolor(dest, x,y,&bgcolor);
|
|
|
|
if ((bgcolor.r == fillcol.r) && (bgcolor.g == fillcol.g) && (bgcolor.b == fillcol.b)) {
|
|
return;
|
|
}
|
|
floodfill4(dest, x, y, fillcol, bgcolor);
|
|
}
|
|
|
|
}
|
|
|
|
void push(int x, int y) {
|
|
fillstack[fillstackptr].x = x;
|
|
fillstack[fillstackptr].y = y;
|
|
fillstackptr++;
|
|
}
|
|
|
|
void pop(int *x, int *y) {
|
|
fillstackptr--;
|
|
*x = fillstack[fillstackptr].x;
|
|
*y = fillstack[fillstackptr].y;
|
|
}
|
|
|
|
void floodfill4(SDL_Surface *dest, int x, int y, SDL_Color fillcol, SDL_Color bgcol) {
|
|
SDL_Color curcolor;
|
|
|
|
push(x,y);
|
|
|
|
while (fillstackptr != 0) {
|
|
pop(&x,&y);
|
|
|
|
getcolor(dest, x,y,&curcolor);
|
|
if ((curcolor.r == bgcol.r) && (curcolor.g == bgcol.g) && (curcolor.b == bgcol.b)) {
|
|
drawpixel(dest, x, y, fillcol);
|
|
}
|
|
|
|
if (x > 0) {
|
|
getcolor(dest, x-1,y,&curcolor);
|
|
if ((curcolor.r == bgcol.r) && (curcolor.g == bgcol.g) && (curcolor.b == bgcol.b)) {
|
|
push(x-1,y);
|
|
}
|
|
}
|
|
if (y > 0) {
|
|
getcolor(dest, x,y-1,&curcolor);
|
|
if ((curcolor.r == bgcol.r) && (curcolor.g == bgcol.g) && (curcolor.b == bgcol.b)) {
|
|
push(x,y-1);
|
|
}
|
|
}
|
|
if (x < (dest->w -1)) {
|
|
getcolor(dest, x+1,y,&curcolor);
|
|
if ((curcolor.r == bgcol.r) && (curcolor.g == bgcol.g) && (curcolor.b == bgcol.b)) {
|
|
push(x+1,y);
|
|
}
|
|
}
|
|
if (y < (dest->h -1)) {
|
|
getcolor(dest, x,y+1,&curcolor);
|
|
if ((curcolor.r == bgcol.r) && (curcolor.g == bgcol.g) && (curcolor.b == bgcol.b)) {
|
|
push(x,y+1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
int getmousepos (int x,int y) {
|
|
if (isontoolbox(x, y)) {
|
|
return MP_TOOLBOX;
|
|
} else if (isonmapbox(x,y)) {
|
|
if (isonmapname(x,y)) {
|
|
return MP_MAPBOXNAME;
|
|
} else {
|
|
return MP_MAPBOXCHILDREN;
|
|
}
|
|
} else if (isonobox(x,y)) {
|
|
return MP_OBJECTBOX;
|
|
}
|
|
|
|
return MP_NONE;
|
|
}
|
|
|
|
int getcolor(SDL_Surface *dest, int x, int y, SDL_Color *col) {
|
|
Uint32 *pixel;
|
|
int bpp;
|
|
|
|
/* SHOULD ALWAYS BE 2!! */
|
|
bpp = dest->format->BytesPerPixel;
|
|
|
|
if (bpp != 2) {
|
|
printf("bpp isnt 2!!!\n");
|
|
fflush(STDOUT);
|
|
}
|
|
|
|
//pixel = (Uint32 *) (dest->pixels + (y * dest->w) + x) ;
|
|
pixel = (Uint32 *) (dest->pixels + y * dest->pitch + x * bpp);
|
|
|
|
|
|
|
|
SDL_GetRGB(*pixel,dest->format,
|
|
&col->r,
|
|
&col->g,
|
|
&col->b );
|
|
|
|
return 0;
|
|
}
|
|
|
|
void drawyn(char *prompt) {
|
|
SDL_Rect area;
|
|
int promptsize = 40;
|
|
int yesnosize = 99;
|
|
int tw,th;
|
|
|
|
/* clear map to red */
|
|
area.x = 0;
|
|
area.y = 0;
|
|
area.w = screen->w - 1;
|
|
area.h = screen->h - 1;
|
|
SDL_FillRect(screen, &area, SDL_MapRGB(screen->format, 255, 0, 0));
|
|
|
|
drawbox(screen, 0, 200,(screen->w/2)-1,500,blue, NULL);
|
|
drawbox(screen, screen->w/2, 200,screen->w-1,500,blue, NULL);
|
|
|
|
|
|
drawtextat(screen, -1,100,prompt, promptsize, blue);
|
|
|
|
/* draw yes & no */
|
|
TTF_SizeText(font[promptsize], "Yes", &tw,&th);
|
|
drawtextat(screen, ((screen->w-SIDEBARW) / 4) - (tw / 2),300,"Yes", yesnosize, blue);
|
|
|
|
TTF_SizeText(font[promptsize], "No", &tw,&th);
|
|
drawtextat(screen, (((screen->w-SIDEBARW) / 4)*3) - (tw / 2),300,"No", yesnosize, blue);
|
|
|
|
SDL_Flip(screen);
|
|
|
|
}
|
|
|
|
int getyn(int x, int y) {
|
|
if (x >= ((screen->w - SIDEBARW)/2)) {
|
|
return NO;
|
|
} else {
|
|
return YES;
|
|
}
|
|
return MAYBE;
|
|
}
|
|
|
|
void goback(void) {
|
|
if (numhistory >= 1) {
|
|
changemap(history[numhistory-1]);
|
|
numhistory--;
|
|
sprintf(statustext, "Drilled back to #%d (%s) - current depth is %d.",curmap,map[curmap].name, numhistory);
|
|
drawmap(TRUE);
|
|
} else {
|
|
seterror(255);
|
|
sprintf(statustext, "Already at top level!");
|
|
drawstatusbar();
|
|
}
|
|
}
|
|
|
|
int linelen(int x1,int y1,int x2,int y2) {
|
|
int deltax, deltay;
|
|
int numpixels;
|
|
int d;
|
|
int dinc1,dinc2,xinc1,xinc2,yinc1,yinc2;
|
|
|
|
deltax = (x2 - x1);
|
|
if (deltax < 0) deltax = -deltax;
|
|
deltay = (y2 - y1);
|
|
if (deltay < 0) deltay = -deltay;
|
|
|
|
if (deltax >= deltay) {
|
|
numpixels = deltax + 1;
|
|
d = (deltay*2) - deltax;
|
|
dinc1 = deltay << 1;
|
|
dinc2 = (deltay-deltax) << 1;
|
|
xinc1 = 1;
|
|
xinc2 = 1;
|
|
yinc1 = 0;
|
|
yinc2 = 1;
|
|
} else {
|
|
numpixels = deltay + 1;
|
|
d = (deltax*2) - deltay;
|
|
dinc1 = deltax << 1;
|
|
dinc2 = (deltax - deltay) << 1;
|
|
xinc1 = 0;
|
|
xinc2 = 1;
|
|
yinc1 = 1;
|
|
yinc2 = 1;
|
|
}
|
|
|
|
return numpixels;
|
|
}
|
|
|
|
int linkat(int x, int y) {
|
|
int i;
|
|
for (i = 0; i < map[curmap].numlinks; i++) {
|
|
/* is (x,y) on the line? */
|
|
if (isonlink(i, x, y)) {
|
|
if (!isflow(i, T_LINK) || (showflows == TRUE)) {
|
|
return i;
|
|
}
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
|
|
int loadmap(void) {
|
|
char filename[BUFLEN];
|
|
FILE *f;
|
|
int namelen;
|
|
int i,n;
|
|
char vers[8], *p;
|
|
|
|
mapobject099a_t tempmapobjects[MAXOBJECTS];
|
|
|
|
|
|
/* TODO: validate */
|
|
strcpy(filename, text);
|
|
|
|
|
|
sprintf(statustext,"Loading map...\n");
|
|
drawstatusbar();
|
|
|
|
f = fopen(filename, "rb");
|
|
if (!f) {
|
|
seterror(255);
|
|
sprintf(statustext,"ERROR: Cannot open '%s'.\n",filename);
|
|
return TRUE;
|
|
}
|
|
|
|
/* TODO: free() variables! */
|
|
|
|
/* TODO: read version string */
|
|
fread(&vers, 8, 1, f);
|
|
/* if no version string, then this is an old version */
|
|
if (vers[0] != 'V') {
|
|
strcpy(vers, "OLD");
|
|
/* go back to start of file */
|
|
fseek(f, 0, SEEK_SET);
|
|
} else {
|
|
/* if we found a version string, remove trailling spaces */
|
|
for (p = vers; *p != '\0' ; p++) {
|
|
if (*p == ' ') {
|
|
*p = '\0';
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (!strcmp(vers, "OLD")) {
|
|
/* old versions without version string */
|
|
/* 0.99a didn't have the fillcol field in mapobject_t */
|
|
|
|
/* read in number maps */
|
|
fread(&nummaps, sizeof(int), 1, f);
|
|
|
|
for (i = 0; i < nummaps; i++) {
|
|
fread(&map[i].width, sizeof(int), 1, f);
|
|
fread(&map[i].height, sizeof(int), 1, f);
|
|
fread(&map[i].bpp, sizeof(int), 1, f);
|
|
fread(&map[i].bgcol, sizeof(SDL_Color), 1, f);
|
|
fread(&map[i].boxcol, sizeof(SDL_Color), 1, f);
|
|
fread(&map[i].numthings, sizeof(int), 1, f);
|
|
fread(&map[i].numobjects, sizeof(int), 1, f);
|
|
fread(&map[i].numlinks, sizeof(int), 1, f);
|
|
fread(&map[i].numtext, sizeof(int), 1, f);
|
|
map[i].selecteditem = -1;
|
|
map[i].selecteditemtype = -1;
|
|
map[i].selectedlinkpoint = -1;
|
|
map[i].selectedtype = 0;
|
|
map[i].curobj = -1;
|
|
map[i].curlink = -1;
|
|
map[i].curlinkpoint = -1;
|
|
map[i].curtext = -1;
|
|
map[i].startx = -1;
|
|
map[i].starty = -1;
|
|
map[i].textanchor = -1;
|
|
strcpy(map[i].text, "");
|
|
|
|
fread(&namelen, sizeof(int), 1, f);
|
|
fread(&map[i].name, (namelen+1) * sizeof(char), 1, f);
|
|
|
|
/* read objects */
|
|
fread(&map[i].thing, sizeof(thing_t), map[i].numthings, f);
|
|
fread(&map[i].olink, sizeof(link_t), map[i].numlinks, f);
|
|
/* read into temp area, then copy to real structure */
|
|
fread(&tempmapobjects, sizeof(mapobject099a_t), map[i].numobjects, f);
|
|
for (n = 0; n < map[i].numobjects; n++) {
|
|
map[i].obj[n].type = tempmapobjects[n].type;
|
|
map[i].obj[n].x = tempmapobjects[n].x;
|
|
map[i].obj[n].y = tempmapobjects[n].y;
|
|
map[i].obj[n].w = tempmapobjects[n].w;
|
|
map[i].obj[n].h = tempmapobjects[n].h;
|
|
map[i].obj[n].child = tempmapobjects[n].child;
|
|
map[i].obj[n].fillcol = black;
|
|
map[i].obj[n].fillcol.unused &= ~(USECOLOUR);
|
|
}
|
|
fread(&map[i].textob, sizeof(text_t), map[i].numtext, f);
|
|
}
|
|
} else {
|
|
/* read in number maps */
|
|
fread(&nummaps, sizeof(int), 1, f);
|
|
|
|
for (i = 0; i < nummaps; i++) {
|
|
fread(&map[i].width, sizeof(int), 1, f);
|
|
fread(&map[i].height, sizeof(int), 1, f);
|
|
fread(&map[i].bpp, sizeof(int), 1, f);
|
|
fread(&map[i].bgcol, sizeof(SDL_Color), 1, f);
|
|
fread(&map[i].boxcol, sizeof(SDL_Color), 1, f);
|
|
fread(&map[i].numthings, sizeof(int), 1, f);
|
|
fread(&map[i].numobjects, sizeof(int), 1, f);
|
|
fread(&map[i].numlinks, sizeof(int), 1, f);
|
|
fread(&map[i].numtext, sizeof(int), 1, f);
|
|
map[i].selecteditem = -1;
|
|
map[i].selecteditemtype = -1;
|
|
map[i].selectedlinkpoint = -1;
|
|
map[i].selectedtype = 0;
|
|
map[i].curobj = -1;
|
|
map[i].curlink = -1;
|
|
map[i].curlinkpoint = -1;
|
|
map[i].curtext = -1;
|
|
map[i].startx = -1;
|
|
map[i].starty = -1;
|
|
map[i].textanchor = -1;
|
|
strcpy(map[i].text, "");
|
|
|
|
fread(&namelen, sizeof(int), 1, f);
|
|
fread(&map[i].name, (namelen+1) * sizeof(char), 1, f);
|
|
|
|
/* read objects */
|
|
fread(&map[i].thing, sizeof(thing_t), map[i].numthings, f);
|
|
fread(&map[i].olink, sizeof(link_t), map[i].numlinks, f);
|
|
fread(&map[i].obj, sizeof(mapobject_t), map[i].numobjects, f);
|
|
fread(&map[i].textob, sizeof(text_t), map[i].numtext, f);
|
|
}
|
|
}
|
|
|
|
fclose(f);
|
|
|
|
/* do some fixes for common issues (whether due to old map versions or not) */
|
|
for (i = 0; i < nummaps; i++) {
|
|
for (n = 0; n < map[i].numlinks; n++) {
|
|
/* old maps have line thickness = 0, change this to 1 */
|
|
if (map[i].olink[n].style == 0) {
|
|
map[i].olink[n].style = 1;
|
|
}
|
|
/* old maps have fillcol.unused = 99 for NOCOLOUR and 100 for USECOLOUR */
|
|
/* new maps have fillcol.unused&0x01 == 1 for USECOLOUR, == 0 for NOCOLOUR */
|
|
if (map[i].olink[n].col.unused == 99) {
|
|
map[i].olink[n].col.unused = 0;
|
|
}
|
|
if (map[i].olink[n].col.unused == 100) {
|
|
map[i].olink[n].col.unused = 1;
|
|
}
|
|
}
|
|
for (n = 0; n < map[i].numobjects; n++) {
|
|
/* old maps have fillcol.unused = 99 for NOCOLOUR and 100 for USECOLOUR */
|
|
/* new maps have fillcol.unused&0x01 == 1 for USECOLOUR, == 0 for NOCOLOUR */
|
|
if (map[i].obj[n].fillcol.unused == 99) {
|
|
map[i].obj[n].fillcol.unused = 0;
|
|
}
|
|
if (map[i].obj[n].fillcol.unused == 100) {
|
|
map[i].obj[n].fillcol.unused = 1;
|
|
}
|
|
}
|
|
for (n = 0; n < map[i].numtext; n++) {
|
|
/* old maps have fillcol.unused = 99 for NOCOLOUR and 100 for USECOLOUR */
|
|
/* new maps have fillcol.unused&0x01 == 1 for USECOLOUR, == 0 for NOCOLOUR */
|
|
if (map[i].textob[n].c.unused == 99) {
|
|
map[i].textob[n].c.unused = 0;
|
|
}
|
|
if (map[i].textob[n].c.unused == 100) {
|
|
map[i].textob[n].c.unused = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
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);
|
|
|
|
updatewm();
|
|
|
|
drawmap(TRUE);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
void lowerselected(int amt) {
|
|
int i,n;
|
|
int temptype,tempid;
|
|
int target = 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;
|
|
}
|
|
}
|
|
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(TRUE);
|
|
}
|
|
|
|
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)) ) {
|
|
|
|
if (!isflow(i, T_OBJECT) || (showflows == TRUE)) {
|
|
return i;
|
|
}
|
|
}
|
|
|
|
}
|
|
*/
|
|
/* 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;
|
|
}
|
|
|
|
void paste(void) {
|
|
if (copytype == T_MAP) {
|
|
if (copymap == curmap) {
|
|
seterror(255);
|
|
sprintf(statustext,"ERROR: copy source and destination maps are the same!");
|
|
drawstatusbar();
|
|
} else if (copymap < 0) {
|
|
seterror(255);
|
|
sprintf(statustext,"ERROR: No copy source selected!");
|
|
drawstatusbar();
|
|
} else {
|
|
map[curmap] = map[copymap];
|
|
sprintf(map[curmap].name, "Copy of map%d",copymap);
|
|
setmod(TRUE);
|
|
sprintf(statustext,"Map %d ('%s') copied to map %d.", copymap, map[copymap].name, curmap);
|
|
copytype = -1;
|
|
copymap = -1;
|
|
drawmap(TRUE);
|
|
|
|
}
|
|
} else if (copytype == T_TEXT) {
|
|
int tnum;
|
|
/* create new text object */
|
|
if ((map[copymap].textob[copyfrom].x + 10) >= map[curmap].width) {
|
|
startx = map[copymap].textob[copyfrom].x - 10;
|
|
} else {
|
|
startx = map[copymap].textob[copyfrom].x + 10;
|
|
}
|
|
if ((map[copymap].textob[copyfrom].y + 10) >= map[curmap].height) {
|
|
starty = map[copymap].textob[copyfrom].y - 10;
|
|
} else {
|
|
starty = map[copymap].textob[copyfrom].y + 10;
|
|
}
|
|
if (copymap == curmap) {
|
|
textanchor = map[copymap].textob[copyfrom].anchor;
|
|
if (textanchor != -1) {
|
|
startx += map[copymap].obj[textanchor].x;
|
|
starty += map[copymap].obj[textanchor].y;
|
|
}
|
|
} else {
|
|
textanchor = -1;
|
|
}
|
|
strcpy(text, map[copymap].textob[copyfrom].text);
|
|
|
|
/* create it */
|
|
endtext();
|
|
|
|
sprintf(statustext,"Text object pasted at %d,%d.",startx,starty);
|
|
|
|
/* update its size */
|
|
tnum = map[curmap].numtext-1;
|
|
map[curmap].textob[tnum].h = map[copymap].textob[copyfrom].h;
|
|
map[curmap].textob[tnum].w = map[copymap].textob[copyfrom].w;
|
|
map[curmap].textob[tnum].c = map[copymap].textob[copyfrom].c;
|
|
|
|
/* select new item */
|
|
map[curmap].selecteditemtype = T_TEXT;
|
|
map[curmap].selecteditem = tnum;
|
|
|
|
/* clear buffer */
|
|
copytype = -1;
|
|
copymap = -1;
|
|
|
|
drawmap(TRUE);
|
|
} else if (copytype == T_OBJECT) {
|
|
int newtype, newx, newy, n;
|
|
int newnum;
|
|
|
|
newtype = map[copymap].obj[copyfrom].type;
|
|
newx = map[copymap].obj[copyfrom].x + 10;
|
|
newy = map[copymap].obj[copyfrom].y + 10;
|
|
|
|
/* TODO: validate new position */
|
|
|
|
createobject(newtype, newx,newy);
|
|
|
|
/* match size, colour, etc */
|
|
newnum = map[curmap].numobjects-1;
|
|
map[curmap].obj[newnum].w = map[copymap].obj[copyfrom].w;
|
|
map[curmap].obj[newnum].h = map[copymap].obj[copyfrom].h;
|
|
map[curmap].obj[newnum].fillcol = map[copymap].obj[copyfrom].fillcol;
|
|
|
|
/* copy over all attached text */
|
|
|
|
for (n = 0; n < map[copymap].numtext; n++) {
|
|
if (map[copymap].textob[n].anchor == copyfrom) {
|
|
int tnum;
|
|
|
|
/* duplicate it */
|
|
startx = map[copymap].textob[n].x + map[curmap].obj[newnum].x;
|
|
starty = map[copymap].textob[n].y + map[curmap].obj[newnum].y;
|
|
textanchor = newnum;
|
|
strcpy(text, map[copymap].textob[n].text);
|
|
endtext();
|
|
|
|
/* update text size */
|
|
tnum = map[curmap].numtext-1;
|
|
|
|
map[curmap].textob[tnum].h = map[copymap].textob[n].h;
|
|
map[curmap].textob[tnum].w = map[copymap].textob[n].w;
|
|
map[curmap].textob[tnum].c = map[copymap].textob[n].c;
|
|
}
|
|
}
|
|
|
|
/* select new object */
|
|
map[curmap].selecteditemtype = T_OBJECT;
|
|
map[curmap].selecteditem = newnum;
|
|
|
|
sprintf(statustext,"Object pasted at %d,%d.",newx,newy);
|
|
drawmap(TRUE);
|
|
} else {
|
|
seterror(255);
|
|
sprintf(statustext,"Error: No copy source selected!");
|
|
drawstatusbar();
|
|
}
|
|
}
|
|
|
|
void pasteline(SDL_Surface *screen, int *lbuf) {
|
|
int deltax, deltay;
|
|
int numpixels;
|
|
int d;
|
|
int dinc1,dinc2,xinc1,xinc2,yinc1,yinc2;
|
|
int i;
|
|
int x;
|
|
int y;
|
|
SDL_Color bgcol;
|
|
int x1,y1,x2,y2;
|
|
int tlx,tly,w,h;
|
|
|
|
|
|
|
|
x1 = lbuf[0];
|
|
y1 = lbuf[1];
|
|
x2 = lbuf[2];
|
|
y2 = lbuf[3];
|
|
|
|
deltax = (x2 - x1);
|
|
if (deltax < 0) deltax = -deltax;
|
|
deltay = (y2 - y1);
|
|
if (deltay < 0) deltay = -deltay;
|
|
|
|
if (deltax >= deltay) {
|
|
numpixels = deltax + 1;
|
|
d = (deltay*2) - deltax;
|
|
dinc1 = deltay << 1;
|
|
dinc2 = (deltay-deltax) << 1;
|
|
xinc1 = 1;
|
|
xinc2 = 1;
|
|
yinc1 = 0;
|
|
yinc2 = 1;
|
|
} else {
|
|
numpixels = deltay + 1;
|
|
d = (deltax*2) - deltay;
|
|
dinc1 = deltax << 1;
|
|
dinc2 = (deltax - deltay) << 1;
|
|
xinc1 = 0;
|
|
xinc2 = 1;
|
|
yinc1 = 1;
|
|
yinc2 = 1;
|
|
}
|
|
|
|
if (x1 > x2) {
|
|
xinc1 = - xinc1;
|
|
xinc2 = - xinc2;
|
|
}
|
|
if (y1 > y2) {
|
|
yinc1 = - yinc1;
|
|
yinc2 = - yinc2;
|
|
}
|
|
|
|
x = x1; y = y1;
|
|
|
|
for (i = 0; i < numpixels; i++) {
|
|
SDL_GetRGB(lbuf[i+4],screen->format,
|
|
&bgcol.r,
|
|
&bgcol.g,
|
|
&bgcol.b );
|
|
|
|
drawpixel(screen, x, y, bgcol);
|
|
|
|
if (d < 0) {
|
|
d += dinc1;
|
|
x += xinc1;
|
|
y += yinc1;
|
|
} else {
|
|
d += dinc2;
|
|
x += xinc2;
|
|
y += yinc2;
|
|
}
|
|
}
|
|
|
|
|
|
/* update screen */
|
|
x1 = lbuf[0];
|
|
y1 = lbuf[1];
|
|
x2 = lbuf[2];
|
|
y2 = lbuf[3];
|
|
|
|
if (x2 < x1) {
|
|
if (y2 < y1) {
|
|
tlx = x2;
|
|
tly = y2;
|
|
w = x1 - x2;
|
|
h = y1 - y2;
|
|
} else {
|
|
tlx = x2;
|
|
tly = y1;
|
|
w = x1 - x2;
|
|
h = y2 - y1;
|
|
}
|
|
} else {
|
|
if (y2 < y1) {
|
|
tlx = x1;
|
|
tly = y2;
|
|
w = x2 - x1;
|
|
h = y1 - y2;
|
|
} else {
|
|
tlx = x1;
|
|
tly = y1;
|
|
w = x2 - x1;
|
|
h = y2 - y1;
|
|
}
|
|
}
|
|
|
|
|
|
SDL_UpdateRect(screen, tlx, tly,w,h);
|
|
//SDL_Flip(screen);
|
|
|
|
}
|
|
|
|
int initgraphics(void) {
|
|
FILE *f;
|
|
char *p;
|
|
int line;
|
|
int state;
|
|
int n;
|
|
vectorimg_t tempv;
|
|
char buf[BUFLEN];
|
|
int x,y;
|
|
Uint8 data[32];
|
|
Uint8 mask[32];
|
|
int i;
|
|
char file[BUFLEN];
|
|
Uint32 fillcol;
|
|
SDL_Rect area;
|
|
|
|
int x1,x2,y1,y2;
|
|
SDL_Color c;
|
|
SDL_Color fc;
|
|
|
|
if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE)==-1) {
|
|
printf("SDL_Init: %s\n", SDL_GetError());
|
|
exit(1);
|
|
}
|
|
|
|
/* open window */
|
|
//screen = SDL_SetVideoMode(DEFSCREENW, DEFSCREENH, 16, (SDL_SWSURFACE|SDL_DOUBLEBUF|SDL_RESIZABLE));
|
|
screen = SDL_SetVideoMode(DEFSCREENW, DEFSCREENH, 16, (SDL_SWSURFACE|SDL_RESIZABLE));
|
|
|
|
if(!screen) {
|
|
printf("SDL_SetVideoMode: %s\n", SDL_GetError());
|
|
return -1;
|
|
}
|
|
if (screen->flags & SDL_SWSURFACE) {
|
|
printf("SWSurface set ok.\n"); fflush(STDOUT);
|
|
}
|
|
if (screen->flags & SDL_SWSURFACE) {
|
|
printf("HWSurface set ok.\n"); fflush(STDOUT);
|
|
}
|
|
if (screen->flags & SDL_DOUBLEBUF) {
|
|
printf("Doublebuf set ok.\n"); fflush(STDOUT);
|
|
}
|
|
|
|
|
|
|
|
initvars();
|
|
|
|
|
|
/* set up icon */
|
|
sprintf(file, "icon.bmp");
|
|
icon = SDL_LoadBMP(file);
|
|
if (!icon) {
|
|
sprintf(file, "/usr/local/share/netmapr/icon.bmp");
|
|
icon = SDL_LoadBMP(file);
|
|
}
|
|
if (!icon) {
|
|
sprintf(file, "%s/icon.bmp",progdir);
|
|
icon = SDL_LoadBMP(file);
|
|
}
|
|
|
|
if (!icon) {
|
|
printf("Error opening icon.bmp: %s\n", TTF_GetError());
|
|
exit(1);
|
|
}
|
|
SDL_WM_SetIcon(icon, NULL);
|
|
|
|
updatewm();
|
|
|
|
/* load fonts */
|
|
TTF_Init();
|
|
sprintf(file, "/usr/local/share/netmapr/verdana.ttf");
|
|
for (i = 1; i < MAXLETTERHEIGHT; i++) {
|
|
font[i] = TTF_OpenFont(file,i);
|
|
if (!font[i]) {
|
|
sprintf(file, "/usr/local/share/netmapr/verdana.ttf");
|
|
font[i] = TTF_OpenFont(file,i);
|
|
}
|
|
if (!font[i]) {
|
|
sprintf(file, "%s/verdana.ttf",progdir);
|
|
font[i] = TTF_OpenFont(file,i);
|
|
}
|
|
if (!font[i]) {
|
|
printf("Error opening font: %s\n", TTF_GetError());
|
|
exit(1);
|
|
}
|
|
}
|
|
//printf("Font load complete - %d sizes read.\n",MAXLETTERHEIGHT);
|
|
|
|
|
|
/* initialise line styles */
|
|
linemask[LS_SOLID][0] = 1;
|
|
linemask[LS_SOLID][1] = -1;
|
|
|
|
linemask[LS_DOTTED][0] = 1;
|
|
linemask[LS_DOTTED][1] = 0;
|
|
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;
|
|
linemask[LS_BIGDASH][2] = 1;
|
|
linemask[LS_BIGDASH][3] = 0;
|
|
linemask[LS_BIGDASH][4] = 0;
|
|
linemask[LS_BIGDASH][5] = 0;
|
|
linemask[LS_BIGDASH][6] = -1;
|
|
|
|
linemask[LS_DASHDOT][0] = 1;
|
|
linemask[LS_DASHDOT][1] = 1;
|
|
linemask[LS_DASHDOT][2] = 0;
|
|
linemask[LS_DASHDOT][3] = 0;
|
|
linemask[LS_DASHDOT][4] = 0;
|
|
linemask[LS_DASHDOT][5] = 1;
|
|
linemask[LS_DASHDOT][6] = 0;
|
|
linemask[LS_DASHDOT][7] = 0;
|
|
linemask[LS_DASHDOT][8] = 0;
|
|
linemask[LS_DASHDOT][9] = -1;
|
|
|
|
/* initialise mouse cursors */
|
|
|
|
/* regular cursor */
|
|
normalmouse = SDL_GetCursor();
|
|
|
|
/* object placement cursor */
|
|
for (i = 0; i < 32; i++) {
|
|
data[i] = normalmouse->data[i];
|
|
mask[i] = normalmouse->mask[i];
|
|
}
|
|
|
|
|
|
/* add square top+bottom */
|
|
for (x = 10; x < 16; x++) {
|
|
y = 10;
|
|
data[(x/8)+(y*2)] |= (128 >> (x%8));
|
|
mask[(x/8)+(y*2)] |= (128 >> (x%8));
|
|
y = 15;
|
|
data[(x/8)+(y*2)] |= (128 >> (x%8));
|
|
mask[(x/8)+(y*2)] |= (128 >> (x%8));
|
|
}
|
|
/* sides */
|
|
for (y = 10; y < 16; y++) {
|
|
x = 10;
|
|
data[(x/8)+(y*2)] |= (128 >> (x%8));
|
|
mask[(x/8)+(y*2)] |= (128 >> (x%8));
|
|
x = 15;
|
|
data[(x/8)+(y*2)] |= (128 >> (x%8));
|
|
mask[(x/8)+(y*2)] |= (128 >> (x%8));
|
|
}
|
|
|
|
objmouse = SDL_CreateCursor(data, mask, normalmouse->area.w, normalmouse->area.h, 0, 0);
|
|
|
|
|
|
/* text placement cursor */
|
|
for (i = 0; i < 32; i++) {
|
|
data[i] = normalmouse->data[i];
|
|
mask[i] = normalmouse->mask[i];
|
|
}
|
|
|
|
|
|
/* add A crossstroke*/
|
|
for (x = 10; x < 15; x++) {
|
|
y = 13;
|
|
data[(x/8)+(y*2)] |= (128 >> (x%8));
|
|
mask[(x/8)+(y*2)] |= (128 >> (x%8));
|
|
}
|
|
/* downstrokes */
|
|
for (y = 11; y < 16; y++) {
|
|
x = 10;
|
|
data[(x/8)+(y*2)] |= (128 >> (x%8));
|
|
mask[(x/8)+(y*2)] |= (128 >> (x%8));
|
|
x = 14;
|
|
data[(x/8)+(y*2)] |= (128 >> (x%8));
|
|
mask[(x/8)+(y*2)] |= (128 >> (x%8));
|
|
}
|
|
/* pointy bit */
|
|
x = 11; y = 10;
|
|
data[(x/8)+(y*2)] |= (128 >> (x%8));
|
|
mask[(x/8)+(y*2)] |= (128 >> (x%8));
|
|
x = 13; y = 10;
|
|
data[(x/8)+(y*2)] |= (128 >> (x%8));
|
|
mask[(x/8)+(y*2)] |= (128 >> (x%8));
|
|
x = 12; y = 9;
|
|
data[(x/8)+(y*2)] |= (128 >> (x%8));
|
|
mask[(x/8)+(y*2)] |= (128 >> (x%8));
|
|
|
|
|
|
textmouse = SDL_CreateCursor(data, mask, normalmouse->area.w, normalmouse->area.h, 0, 0);
|
|
|
|
updatewm();
|
|
|
|
/* set up toolbox highlight image */
|
|
toolhilite = SDL_CreateRGBSurface(SDL_SWSURFACE,toolbox.gridsize+3, toolbox.gridsize+3,
|
|
screen->format->BitsPerPixel, screen->format->Rmask,
|
|
screen->format->Gmask,screen->format->Bmask,
|
|
screen->format->Amask);
|
|
fillcol = SDL_MapRGB(screen->format, 250, 250, 250);
|
|
|
|
area.x = 0;
|
|
area.y = 0;
|
|
area.w = toolbox.gridsize+1;
|
|
area.h = toolbox.gridsize+1;
|
|
SDL_FillRect(toolhilite, &area, fillcol);
|
|
SDL_SetAlpha(toolhilite, SDL_SRCALPHA, 128);
|
|
|
|
/* initialise buffer */
|
|
buffer = SDL_CreateRGBSurface(SDL_SWSURFACE,screen->w - SIDEBARW,screen->h - STATUSH,
|
|
screen->format->BitsPerPixel, screen->format->Rmask,
|
|
screen->format->Gmask,screen->format->Bmask,
|
|
screen->format->Amask);
|
|
|
|
if (!buffer) {
|
|
printf("Cannot create buffer!\n");
|
|
exit(1);
|
|
}
|
|
|
|
|
|
f = fopen("objects.dat","rt");
|
|
if (!f) {
|
|
sprintf(file, "/usr/local/share/netmapr/objects.dat");
|
|
f = fopen(file,"rt");
|
|
}
|
|
if (!f) {
|
|
sprintf(file, "%s/objects.dat",progdir);
|
|
f = fopen(file,"rt");
|
|
}
|
|
if (!f) {
|
|
printf("Cannot open objects file!\n");
|
|
exit(1);
|
|
}
|
|
|
|
state = 0;
|
|
line = 0;
|
|
numobjtypes = 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 objects file.\n",line); exit(1); }
|
|
if (strcmp(p, "object")) {
|
|
printf("Expecting 'object' on line #%d of objects file (got '%s').\n",line,p);
|
|
exit(1);
|
|
}
|
|
/* name */
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
strncpy(objtype[numobjtypes].name, p, BUFLEN);
|
|
/* width */
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
objtype[numobjtypes].vimg.w = atoi(p);
|
|
/* height */
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
objtype[numobjtypes].vimg.h = atoi(p);
|
|
|
|
/* no vectors to start with */
|
|
objtype[numobjtypes].vimg.vnum = 0;
|
|
objtype[numobjtypes].canscale = TRUE;
|
|
|
|
/* default size is minimum */
|
|
objtype[numobjtypes].defw = MINOBJWIDTH;
|
|
objtype[numobjtypes].defh = MINOBJHEIGHT;
|
|
|
|
state = 1;
|
|
} else if (state == 1) {
|
|
p = strtok(buf, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
if (!strcmp(p, "line")) {
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
x1 = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
y1 = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
x2 = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
y2 = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
c.r = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
c.g = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
c.b = atoi(p);
|
|
|
|
if (addvector(&objtype[numobjtypes].vimg,VT_LINE,x1,y1,x2,y2,&c, NULL)) {
|
|
printf("Too many vectors on line %d of objects file.\n",line);
|
|
exit(1);
|
|
}
|
|
|
|
/*
|
|
} else if (!strcmp(p, "fill")) {
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
x1 = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
y1 = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
fc.r = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
fc.g = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
fc.b = atoi(p);
|
|
fc.unused = 0;
|
|
|
|
c.r = 0;
|
|
c.g = 0;
|
|
c.b = 0;
|
|
c.unused = 0;
|
|
|
|
if (addvector(&objtype[numobjtypes].vimg,VT_FILL,x1,y1,0,0,&c, &fc)) {
|
|
printf("Too many vectors on line %d of objects file.\n",line);
|
|
exit(1);
|
|
}
|
|
*/
|
|
} else if (!strcmp(p, "subobj")) {
|
|
// get r g b fill colour
|
|
p = strtok(NULL, " ");
|
|
|
|
if (p == NULL) { printf("Missing line-R on line #%d of objects file.\n",line); exit(1); }
|
|
if (*p == 'n') {
|
|
fc.r = 0;
|
|
fc.g = 0;
|
|
fc.b = 0;
|
|
fc.unused = 0;
|
|
} else {
|
|
fc.r = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing line-G on line #%d of objects file.\n",line); exit(1); }
|
|
fc.g = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing line-B on line #%d of objects file.\n",line); exit(1); }
|
|
fc.b = atoi(p);
|
|
fc.unused = 0 | USECOLOUR;
|
|
}
|
|
|
|
if (addvector(&objtype[numobjtypes].vimg,VT_SUBOBJ,0,0,0,0,&fc,&fc)) {
|
|
printf("Too many vectors on line %d of objects file.\n",line);
|
|
exit(1);
|
|
}
|
|
} else if (!strcmp(p, "endsub")) {
|
|
fc.r = 0;
|
|
fc.g = 0;
|
|
fc.b = 0;
|
|
fc.unused = 0;
|
|
|
|
if (addvector(&objtype[numobjtypes].vimg,VT_ENDPOLY,0,0,0,0,&fc,&fc)) {
|
|
printf("Too many vectors on line %d of objects file.\n",line);
|
|
exit(1);
|
|
}
|
|
} else if (!strcmp(p, "poly")) {
|
|
int count = 1;
|
|
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing line-R on line #%d of objects file.\n",line); exit(1); }
|
|
c.r = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing line-G on line #%d of objects file.\n",line); exit(1); }
|
|
c.g = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing line-B on line #%d of objects file.\n",line); exit(1); }
|
|
c.b = atoi(p);
|
|
|
|
p = strtok(NULL, " ");
|
|
if (*p != 'p') {
|
|
printf("Invalid syntax on line #%d of objects file - missing 'f'.\n", line);
|
|
exit(1);
|
|
}
|
|
|
|
/* get first point */
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing x1 on line #%d of objects file (polyline #%d).\n",line,count); exit(1); }
|
|
x1 = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing y1 on line #%d of objects file (polyline #%d).\n",line,count); exit(1); }
|
|
y1 = atoi(p);
|
|
|
|
p = strtok(NULL, " ");
|
|
while (*p != 'f') {
|
|
/* get next set of coords */
|
|
if (*p == ',') {
|
|
p = strtok(NULL, " ");
|
|
}
|
|
|
|
|
|
if (p == NULL) { printf("Missing x2 on line #%d of objects file (polyline #%d).\n",line,count); exit(1); }
|
|
x2 = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing y2 on line #%d of objects file (polyline #%d).\n",line,count); exit(1); }
|
|
y2 = atoi(p);
|
|
|
|
/* write to struct */
|
|
if (addvector(&objtype[numobjtypes].vimg,VT_POLY,x1,y1,x2,y2,&c, NULL)) {
|
|
printf("Too many vectors on line %d of objects file.\n",line);
|
|
exit(1);
|
|
}
|
|
|
|
x1 = x2;
|
|
y1 = y2;
|
|
count++;
|
|
p = strtok(NULL, " ");
|
|
}
|
|
|
|
/* get fill details */
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing FILLCOL on line #%d of objects file.\n",line); exit(1); }
|
|
if (*p == 'n') {
|
|
fc.r = 0;
|
|
fc.g = 0;
|
|
fc.b = 0;
|
|
fc.unused = 0;
|
|
} else {
|
|
fc.r = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing fillcol-G on line #%d of objects file.\n",line); exit(1); }
|
|
fc.g = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing fillcol-B on line #%d of objects file.\n",line); exit(1); }
|
|
fc.b = atoi(p);
|
|
fc.unused = 0;
|
|
fc.unused |= USECOLOUR;
|
|
}
|
|
|
|
|
|
if (addvector(&objtype[numobjtypes].vimg,VT_ENDPOLY,0,0,0,0,&fc, &fc)) {
|
|
printf("Too many vectors on line %d of objects file.\n",line);
|
|
exit(1);
|
|
}
|
|
} else if (!strcmp(p, "box")) {
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
x1 = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
y1 = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
x2 = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
y2 = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
c.r = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
c.g = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
c.b = atoi(p);
|
|
|
|
/* fill colour? */
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
if (*p == 'n') { /* no fill */
|
|
fc.r = 0;
|
|
fc.g = 0;
|
|
fc.b = 0;
|
|
fc.unused = 0;
|
|
} else {
|
|
fc.r = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
fc.g = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
fc.b = atoi(p);
|
|
fc.unused = 0;
|
|
fc.unused |= USECOLOUR;
|
|
}
|
|
|
|
if (addvector(&objtype[numobjtypes].vimg,VT_BOX,x1,y1,x2,y2,&c, &fc)) {
|
|
printf("Too many vectors on line %d of objects file.\n",line);
|
|
exit(1);
|
|
}
|
|
} else if (!strcmp(p, "bezier")) {
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
x1 = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
y1 = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
x1 = x1 << 16;
|
|
x1 |= atoi(p); /* store two things in the one int */
|
|
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
y1 = y1 << 16;
|
|
y1 |= atoi(p); /* store two things in the one int */
|
|
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
x2 = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
y2 = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
x2 = x2 << 16;
|
|
x2 |= atoi(p); /* store two things in the one int */
|
|
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
y2 = y2 << 16;
|
|
y2 |= atoi(p); /* store two things in the one int */
|
|
|
|
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
c.r = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
c.g = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
c.b = atoi(p);
|
|
|
|
if (addvector(&objtype[numobjtypes].vimg,VT_BEZIER,x1,y1,x2,y2,&c, NULL)) {
|
|
printf("Too many vectors on line %d of objects file.\n",line);
|
|
exit(1);
|
|
}
|
|
} else if (!strcmp(p, "circle")) {
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
x1 = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
y1 = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
x2 = atoi(p); /* x2 is actually the x radius */
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
y2 = atoi(p); /* y2 is actually the y radius */
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
c.r = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
c.g = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of objects file.\n",line); exit(1); }
|
|
c.b = atoi(p);
|
|
|
|
if (addvector(&objtype[numobjtypes].vimg,VT_ELLIPSE,x1,y1,x2,y2,&c, NULL)) {
|
|
printf("Too many vectors on line %d of objects file.\n",line);
|
|
exit(1);
|
|
}
|
|
} else if (!strcmp(p, "end")) {
|
|
state = 0;
|
|
numobjtypes++;
|
|
if (numobjtypes >= MAXOBJTYPES) {
|
|
printf("FATAL: Too many object types found (max is %d).\n",MAXOBJTYPES);
|
|
exit(1);
|
|
}
|
|
} else {
|
|
printf("Invalid command '%s' on line #%d of objects file.\n",p,line);
|
|
exit(1);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
fgets(buf, BUFLEN, f);
|
|
buf[strlen(buf)-1] = '\0';
|
|
line++;
|
|
}
|
|
fclose(f);
|
|
//printf("Shape load complete - %d objects found.\n",numobjtypes);
|
|
|
|
f = fopen("buttons.dat","rt");
|
|
if (!f) {
|
|
sprintf(file, "/usr/local/share/netmapr/buttons.dat");
|
|
f = fopen(file,"rt");
|
|
}
|
|
if (!f) {
|
|
sprintf(file, "%s/buttons.dat",progdir);
|
|
f = fopen(file,"rt");
|
|
}
|
|
if (!f) {
|
|
printf("Cannot open buttons file!\n");
|
|
exit(1);
|
|
}
|
|
|
|
state = 0;
|
|
line = 0;
|
|
numbuttons = 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 buttons file.\n",line); exit(1); }
|
|
if (strcmp(p, "button")) {
|
|
printf("Expecting 'button' on line #%d of buttons file (got '%s').\n",line,p);
|
|
exit(1);
|
|
}
|
|
/* name */
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of buttons file.\n",line); exit(1); }
|
|
strncpy(button[numbuttons].name, p, BUFLEN);
|
|
/* width */
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of buttons file.\n",line); exit(1); }
|
|
tempv.w = atoi(p);
|
|
/* height */
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of buttons file.\n",line); exit(1); }
|
|
tempv.h = atoi(p);
|
|
|
|
|
|
/* allocate mem */
|
|
button[numbuttons].img = SDL_CreateRGBSurface(SDL_SWSURFACE,toolbox.gridsize-2,toolbox.gridsize-2,
|
|
screen->format->BitsPerPixel, screen->format->Rmask,
|
|
screen->format->Gmask,screen->format->Bmask,
|
|
screen->format->Amask);
|
|
|
|
tempv.vnum = 0;
|
|
|
|
|
|
state = 1;
|
|
} else if (state == 1) {
|
|
p = strtok(buf, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of buttons file.\n",line); exit(1); }
|
|
if (!strcmp(p, "line")) {
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of buttons file.\n",line); exit(1); }
|
|
x1 = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of buttons file.\n",line); exit(1); }
|
|
y1 = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of buttons file.\n",line); exit(1); }
|
|
x2 = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of buttons file.\n",line); exit(1); }
|
|
y2 = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of buttons file.\n",line); exit(1); }
|
|
c.r = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of buttons file.\n",line); exit(1); }
|
|
c.g = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of buttons file.\n",line); exit(1); }
|
|
c.b = atoi(p);
|
|
|
|
if (addvector(&tempv,VT_LINE,x1,y1,x2,y2,&c, NULL)) {
|
|
printf("Too many vectors on line %d of objects file.\n",line);
|
|
exit(1);
|
|
}
|
|
/*
|
|
} else if (!strcmp(p, "fill")) {
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of buttons file.\n",line); exit(1); }
|
|
x1 = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of buttons file.\n",line); exit(1); }
|
|
y1 = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of buttons file.\n",line); exit(1); }
|
|
fc.r = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of buttons file.\n",line); exit(1); }
|
|
fc.g = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of buttons file.\n",line); exit(1); }
|
|
fc.b = atoi(p);
|
|
fc.unused = 0;
|
|
|
|
c.r = 0;
|
|
c.g = 0;
|
|
c.b = 0;
|
|
c.unused = 0;
|
|
|
|
if (addvector(&tempv,VT_FILL,x1,y1,0,0,&c, &fc)) {
|
|
printf("Too many vectors on line %d of objects file.\n",line);
|
|
exit(1);
|
|
}
|
|
*/
|
|
} else if (!strcmp(p, "box")) {
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of buttons file.\n",line); exit(1); }
|
|
x1 = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of buttons file.\n",line); exit(1); }
|
|
y1 = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of buttons file.\n",line); exit(1); }
|
|
x2 = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of buttons file.\n",line); exit(1); }
|
|
y2 = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of buttons file.\n",line); exit(1); }
|
|
c.r = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of buttons file.\n",line); exit(1); }
|
|
c.g = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) { printf("Missing token on line #%d of buttons file.\n",line); exit(1); }
|
|
c.b = atoi(p);
|
|
|
|
if (addvector(&tempv,VT_BOX,x1,y1,x2,y2,&c, NULL)) {
|
|
printf("Too many vectors on line %d of buttons file.\n",line);
|
|
exit(1);
|
|
}
|
|
} else if (!strcmp(p, "end")) {
|
|
/* draw vector image into button's bitmap field */
|
|
drawvector(button[numbuttons].img, &tempv, 1, 1, toolbox.gridsize-2,toolbox.gridsize-2, NULL, NULL);
|
|
|
|
|
|
//printf("Adding button: '%s' (vnum = %d).\n",button[numbuttons].name,tempv.vnum);
|
|
state = 0;
|
|
numbuttons++;
|
|
} else {
|
|
printf("Invalid command '%s' on line #%d of buttons file.\n",p,line);
|
|
exit(1);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
fgets(buf, BUFLEN, f);
|
|
buf[strlen(buf)-1] = '\0';
|
|
line++;
|
|
}
|
|
fclose(f);
|
|
//printf("Button load complete - %d buttons found.\n",numbuttons);
|
|
|
|
////////////////////////////////////////////////////////////
|
|
/// XXX: TESTING ///
|
|
|
|
/*
|
|
x = 10; y = 10;
|
|
for (i = 0; i < numletters; i++) {
|
|
int lw,lh;
|
|
lw = 8;
|
|
lh = 10;
|
|
drawvector(screen, &letter[i].vect, x, y, lw,lh, NULL, NULL);
|
|
x = x + lw + 2;
|
|
if (x >= (map[curmap].width - lw)) {
|
|
x = 0;
|
|
y = y + lh + 2;
|
|
}
|
|
}
|
|
SDL_Flip(screen);
|
|
while(1) {
|
|
while (SDL_PollEvent(&event)) {
|
|
switch (event.type) {
|
|
case SDL_KEYDOWN:
|
|
exit(1);
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
int isinhistory (int mapid) {
|
|
int i;
|
|
int found;
|
|
|
|
found = -1;
|
|
for (i = 0; i < numhistory; i++) {
|
|
if (history[i] == mapid) {
|
|
found = i;
|
|
}
|
|
}
|
|
|
|
return found;
|
|
}
|
|
|
|
int isflow(int oid, int otype) {
|
|
switch (otype) {
|
|
case T_OBJECT:
|
|
if (map[curmap].obj[oid].fillcol.unused & ISFLOW) return TRUE;
|
|
break;
|
|
case T_LINK:
|
|
if (map[curmap].olink[oid].col.unused & ISFLOW) return TRUE;
|
|
break;
|
|
case T_TEXT:
|
|
if (map[curmap].textob[oid].c.unused & ISFLOW) return TRUE;
|
|
break;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
int isonline (int fx, int fy, int x1, int y1, int x2, int y2) {
|
|
int deltax, deltay;
|
|
int numpixels;
|
|
int d;
|
|
int dinc1,dinc2,xinc1,xinc2,yinc1,yinc2;
|
|
int i;
|
|
int x;
|
|
int y;
|
|
|
|
deltax = (x2 - x1);
|
|
if (deltax < 0) deltax = -deltax;
|
|
deltay = (y2 - y1);
|
|
if (deltay < 0) deltay = -deltay;
|
|
|
|
if (deltax >= deltay) {
|
|
numpixels = deltax + 1;
|
|
d = (deltay*2) - deltax;
|
|
dinc1 = deltay << 1;
|
|
dinc2 = (deltay-deltax) << 1;
|
|
xinc1 = 1;
|
|
xinc2 = 1;
|
|
yinc1 = 0;
|
|
yinc2 = 1;
|
|
} else {
|
|
numpixels = deltay + 1;
|
|
d = (deltax*2) - deltay;
|
|
dinc1 = deltax << 1;
|
|
dinc2 = (deltax - deltay) << 1;
|
|
xinc1 = 0;
|
|
xinc2 = 1;
|
|
yinc1 = 1;
|
|
yinc2 = 1;
|
|
}
|
|
|
|
if (x1 > x2) {
|
|
xinc1 = - xinc1;
|
|
xinc2 = - xinc2;
|
|
}
|
|
if (y1 > y2) {
|
|
yinc1 = - yinc1;
|
|
yinc2 = - yinc2;
|
|
}
|
|
|
|
x = x1; y = y1;
|
|
|
|
for (i = 0; i < numpixels; i++) {
|
|
|
|
if ((fx >= (x-LINESELTHRESHOLD)) && (fx <= (x+LINESELTHRESHOLD)) &&
|
|
(fy >= (y-LINESELTHRESHOLD)) && (fy <= (y+LINESELTHRESHOLD))) {
|
|
return TRUE;
|
|
}
|
|
|
|
if (d < 0) {
|
|
d += dinc1;
|
|
x += xinc1;
|
|
y += yinc1;
|
|
} else {
|
|
d += dinc2;
|
|
x += xinc2;
|
|
y += yinc2;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
int isonlink (int linkid, int mx, int my) {
|
|
int i;
|
|
int x,y,x2,y2;
|
|
|
|
x = map[curmap].obj[map[curmap].olink[linkid].srcobj].x + map[curmap].olink[linkid].srcxoff;
|
|
y = map[curmap].obj[map[curmap].olink[linkid].srcobj].y + map[curmap].olink[linkid].srcyoff;
|
|
|
|
for (i = 0; i < map[curmap].olink[linkid].npoints; i++) {
|
|
x2 = map[curmap].olink[linkid].point[i].x;
|
|
y2 = map[curmap].olink[linkid].point[i].y;
|
|
|
|
if (isonline(mx,my,x,y,x2,y2)) return TRUE;
|
|
|
|
x = x2;
|
|
y = y2;
|
|
}
|
|
|
|
/* draw line to final map[curmap].object */
|
|
x2 = map[curmap].obj[map[curmap].olink[linkid].dstobj].x + map[curmap].olink[linkid].dstxoff;
|
|
y2 = map[curmap].obj[map[curmap].olink[linkid].dstobj].y + map[curmap].olink[linkid].dstyoff;
|
|
|
|
if (isonline(mx,my,x,y,x2,y2)) return TRUE;
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
int isonlinkdst(int lineid, int x, int y) {
|
|
int hx1,hy1,hx2,hy2;
|
|
|
|
hx1 = map[curmap].obj[map[curmap].olink[lineid].dstobj].x + map[curmap].olink[lineid].dstxoff - (LINESELHANDLESIZE/2);
|
|
hy1 = map[curmap].obj[map[curmap].olink[lineid].dstobj].y + map[curmap].olink[lineid].dstyoff - (LINESELHANDLESIZE/2);
|
|
hx2 = hx1 + LINESELHANDLESIZE;
|
|
hy2 = hy1 + LINESELHANDLESIZE;
|
|
|
|
if ((x >= hx1) && ( x <= hx2) && (y >= hy1) & (y <= hy2)) {
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
int isonlinkpoint(int lineid, int mx, int my) {
|
|
int i;
|
|
|
|
for (i = 0; i < map[curmap].olink[lineid].npoints; i++) {
|
|
int x,y;
|
|
|
|
x = map[curmap].olink[lineid].point[i].x;
|
|
y = map[curmap].olink[lineid].point[i].y;
|
|
|
|
if ((mx >= (x-LINESELTHRESHOLD)) && (mx <= (x+LINESELTHRESHOLD)) &&
|
|
(my >= (y-LINESELTHRESHOLD)) && (my <= (y+LINESELTHRESHOLD))) {
|
|
return i;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
int isonlinksrc(int lineid, int x, int y) {
|
|
int hx1,hy1,hx2,hy2;
|
|
|
|
hx1 = map[curmap].obj[map[curmap].olink[lineid].srcobj].x + map[curmap].olink[lineid].srcxoff - (LINESELHANDLESIZE/2);
|
|
hy1 = map[curmap].obj[map[curmap].olink[lineid].srcobj].y + map[curmap].olink[lineid].srcyoff - (LINESELHANDLESIZE/2);
|
|
hx2 = hx1 + LINESELHANDLESIZE;
|
|
hy2 = hy1 + LINESELHANDLESIZE;
|
|
|
|
if ((x >= hx1) && ( x <= hx2) && (y >= hy1) & (y <= hy2)) {
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
int isonmap(int x, int y) {
|
|
if ((x >= 0) && ( y >= 0) && (x <= (screen->w - SIDEBARW)) && (y <= (screen->h - STATUSH))) {
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
int isonmapbox(int x, int y) {
|
|
if ((x >= mapbox.x) && ( y >= mapbox.y) && (x <= mapbox.x+mapbox.width) && (y <= mapbox.y+mapbox.height)) {
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
int isonmapboxchildren(int x, int y) {
|
|
if ((x >= mapbox.x) && ( y >= mapbox.y+(TTF_FontHeight(font[MAPBOXTEXTHEIGHT])*2)+2) && (x <= mapbox.x+mapbox.width) && (y <= mapbox.y+mapbox.height)) {
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
int isonmapname(int x, int y) {
|
|
if ((x >= mapbox.x) && ( y >= mapbox.y) && (x <= mapbox.x+mapbox.width) && (y <= mapbox.y+DEFTEXTH+2)) {
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
int isongoback(int x, int y) {
|
|
if ((x >= mapbox.x) && ( y >= (mapbox.y + TTF_FontHeight(font[MAPBOXTEXTHEIGHT])))
|
|
&& (x <= mapbox.x+mapbox.width) && (y <= mapbox.y+(TTF_FontHeight(font[MAPBOXTEXTHEIGHT])*2))) {
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
int isonobox(int x, int y) {
|
|
if ((x >= obox.x) && ( y >= obox.y) && (x <= obox.x+obox.width) && (y <= obox.y+obox.height)) {
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
int isontoolbox(int x, int y) {
|
|
if ((x >= toolbox.x) && ( y >= toolbox.y) && (x <= toolbox.x+toolbox.width) && (y <= toolbox.y+toolbox.height)) {
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
int isonxscrollbar(int x, int y) {
|
|
if ((y >= (screen->h - STATUSH - SBSIZE)) && (y < (screen->h - STATUSH))) {
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
int isonyscrollbar(int x, int y) {
|
|
if ((x >= (screen->w - SIDEBARW - SBSIZE)) && (x < (screen->w - SIDEBARW))) {
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
void initmap(int mapnum) {
|
|
map[mapnum].width = DEFSCREENW - SIDEBARW;
|
|
map[mapnum].height = DEFSCREENH - STATUSH;
|
|
map[mapnum].bpp = 16;
|
|
map[mapnum].bgcol.r = 255;
|
|
map[mapnum].bgcol.g = 255;
|
|
map[mapnum].bgcol.b = 255;
|
|
map[mapnum].boxcol.r = 90;
|
|
map[mapnum].boxcol.g = 90;
|
|
map[mapnum].boxcol.b = 90;
|
|
|
|
map[mapnum].numthings = 0;
|
|
map[mapnum].numobjects = 0;
|
|
map[mapnum].numlinks = 0;
|
|
map[mapnum].numtext = 0;
|
|
|
|
map[mapnum].selecteditem = -1;
|
|
map[mapnum].selecteditemtype = -1;
|
|
map[mapnum].selectedlinkpoint = -1;
|
|
map[mapnum].selectedtype = 0;
|
|
|
|
map[mapnum].curobj = -1; /* map[curmap].object being moved/dragged/etc */
|
|
map[mapnum].curlink = -1; /* link being moved/dragged/etc */
|
|
map[mapnum].curlinkpoint = -1; /* link pomap[mapnum].being moved/dragged/etc */
|
|
map[mapnum].curtext = -1; /* text being moved/dragged/etc */
|
|
map[mapnum].startx = -1;
|
|
map[mapnum].starty = -1;
|
|
map[mapnum].textanchor = -1;
|
|
strcpy(map[mapnum].text, "");
|
|
if (mapnum == 0) {
|
|
sprintf(map[mapnum].name, "Toplevel");
|
|
} else {
|
|
sprintf(map[mapnum].name, "Map #%d",mapnum);
|
|
}
|
|
|
|
setmod(FALSE);
|
|
|
|
|
|
}
|
|
|
|
void initvars(void) {
|
|
nummaps = 1;
|
|
|
|
strcpy(typedesc[0], "None");
|
|
strcpy(typedesc[1], "Object");
|
|
strcpy(typedesc[2], "Link");
|
|
strcpy(typedesc[3], "Text");
|
|
strcpy(typedesc[4], "Linkpoint");
|
|
strcpy(typedesc[5], "Map");
|
|
|
|
strcpy(currentfilename, "");
|
|
|
|
grid = TRUE;
|
|
gridsize = 15;
|
|
|
|
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;
|
|
|
|
obox.x = screen->w - SIDEBARW;
|
|
obox.y = ((screen->h / 4) * 3) - 10;
|
|
obox.width = SIDEBARW;
|
|
obox.height = screen->h - obox.y;
|
|
obox.bgcol = black;
|
|
obox.gridbgcol = grey;
|
|
obox.gridcol = grey;
|
|
obox.gridsize = 30;
|
|
obox.gridrowlen = SIDEBARW / obox.gridsize;
|
|
|
|
toolbox.x = screen->w - SIDEBARW;
|
|
toolbox.y = 0;
|
|
toolbox.width = SIDEBARW;
|
|
toolbox.height = screen->h / 3;
|
|
toolbox.bgcol = black;
|
|
toolbox.gridsize = 30;
|
|
toolbox.gridrowlen = SIDEBARW / toolbox.gridsize;
|
|
|
|
mapbox.x = screen->w - SIDEBARW;
|
|
mapbox.y = toolbox.y+toolbox.height+10;
|
|
mapbox.width = SIDEBARW;
|
|
mapbox.height = obox.y - mapbox.y - 20;
|
|
mapbox.offset = 0;
|
|
|
|
/*
|
|
obox.x = map[curmap].width + 1;
|
|
obox.y = ((map[curmap].height / 4) * 3) - 10;
|
|
obox.width = SIDEBARW;
|
|
obox.height = map[curmap].height - obox.y;
|
|
obox.bgcol = black;
|
|
obox.gridbgcol = grey;
|
|
obox.gridcol = grey;
|
|
obox.gridsize = 30;
|
|
obox.gridrowlen = SIDEBARW / obox.gridsize;
|
|
|
|
toolbox.x = map[curmap].width + 1;
|
|
toolbox.y = 0;
|
|
toolbox.width = SIDEBARW;
|
|
toolbox.height = map[curmap].height / 3;
|
|
toolbox.bgcol = black;
|
|
toolbox.gridsize = 30;
|
|
toolbox.gridrowlen = SIDEBARW / toolbox.gridsize;
|
|
|
|
mapbox.x = map[curmap].width + 1;
|
|
mapbox.y = toolbox.y+toolbox.height+10;
|
|
mapbox.width = SIDEBARW;
|
|
mapbox.height = obox.y - mapbox.y - 20;
|
|
mapbox.offset = 0;
|
|
*/
|
|
|
|
|
|
fgcol = black;
|
|
objfillcol = black;
|
|
objfillcol.unused &= ~(USECOLOUR);
|
|
|
|
}
|
|
|
|
void raiseselected(int amt) {
|
|
int i,n;
|
|
int temptype,tempid;
|
|
int target = 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 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;
|
|
}
|
|
}
|
|
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(TRUE);
|
|
}
|
|
|
|
void seterror (int errnum) {
|
|
infoflash = 0;
|
|
errorflash = errnum;
|
|
|
|
olderrorticks = SDL_GetTicks();
|
|
}
|
|
|
|
void setinfo (int infonum) {
|
|
infoflash = infonum;
|
|
errorflash = 0;
|
|
|
|
oldinfoticks = SDL_GetTicks();
|
|
}
|
|
|
|
void setsearchflash (int num) {
|
|
searchflash = num;
|
|
|
|
oldsearchticks = SDL_GetTicks();
|
|
|
|
/* copy background */
|
|
if (searchbg != NULL) {
|
|
SDL_FreeSurface(searchbg);
|
|
searchbg = NULL;
|
|
}
|
|
if (map[curmap].selecteditem != -1) {
|
|
if (map[curmap].selecteditemtype == T_TEXT) {
|
|
int th;
|
|
SDL_Rect area;
|
|
int txoff,tyoff;
|
|
int anchoreditem;
|
|
|
|
/* calculate text's height */
|
|
th = TTF_FontHeight(font[map[curmap].textob[map[curmap].selecteditem].h]);
|
|
|
|
area.w = map[curmap].textob[map[curmap].selecteditem].w;
|
|
area.h = th;
|
|
|
|
anchoreditem = map[curmap].textob[map[curmap].selecteditem].anchor;
|
|
if (anchoreditem == -1) {
|
|
txoff = 0;
|
|
tyoff = 0;
|
|
} else {
|
|
txoff = map[curmap].obj[anchoreditem].x;
|
|
tyoff = map[curmap].obj[anchoreditem].y;
|
|
}
|
|
area.x = map[curmap].textob[map[curmap].selecteditem].x - screenx + txoff;
|
|
area.y = map[curmap].textob[map[curmap].selecteditem].y - screeny + tyoff;
|
|
|
|
searchbg = SDL_CreateRGBSurface(SDL_SWSURFACE,area.w, area.h,
|
|
screen->format->BitsPerPixel, screen->format->Rmask,
|
|
screen->format->Gmask,screen->format->Bmask,
|
|
screen->format->Amask);
|
|
SDL_BlitSurface(screen, &area, searchbg, NULL);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void setmod(int tf) {
|
|
modified = tf;
|
|
/* can't just set needtocalc to TRUE as we can't guarantee when
|
|
* the screen will next be redrawn */
|
|
calcmapdimensions();
|
|
needtocalc = FALSE;
|
|
updatewm();
|
|
}
|
|
|
|
int savemap(void) {
|
|
char filename[BUFLEN];
|
|
FILE *f;
|
|
int namelen;
|
|
int prevgrid;
|
|
int i;
|
|
int eoff;
|
|
SDL_Surface *exportmap;
|
|
SDL_Rect area;
|
|
char vers[8];
|
|
|
|
/* TODO: validate */
|
|
strcpy(filename, text);
|
|
|
|
|
|
sprintf(statustext,"Saving map...\n");
|
|
drawstatusbar();
|
|
|
|
|
|
|
|
/* is this an export? (use extenstion) */
|
|
if (strlen(filename) >= 5) {
|
|
eoff = strlen(filename)-4;
|
|
/* export to BMP format */
|
|
if ((filename[eoff] == '.') &&
|
|
((filename[eoff+1] == 'b') || (filename[eoff+1] == 'B')) &&
|
|
((filename[eoff+2] == 'm') || (filename[eoff+2] == 'M')) &&
|
|
((filename[eoff+3] == 'p') || (filename[eoff+3] == 'P'))
|
|
) {
|
|
exportmap = SDL_CreateRGBSurface(SDL_SWSURFACE,map[curmap].width, screen->h - STATUSH,
|
|
buffer->format->BitsPerPixel, buffer->format->Rmask,
|
|
buffer->format->Gmask,buffer->format->Bmask,
|
|
buffer->format->Amask);
|
|
|
|
state = S_NONE;
|
|
prevgrid = gridsize;
|
|
setgridsize(0);
|
|
drawmap(FALSE);
|
|
gridsize = prevgrid;
|
|
area.x = 0;
|
|
area.y = 0;
|
|
area.w = map[curmap].width;
|
|
area.h = screen->h - STATUSH;
|
|
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;
|
|
}
|
|
if ((filename[eoff] == '.') &&
|
|
((filename[eoff+1] == 'p') || (filename[eoff+1] == 'P')) &&
|
|
((filename[eoff+2] == 'n') || (filename[eoff+2] == 'N')) &&
|
|
((filename[eoff+3] == 'g') || (filename[eoff+3] == 'G'))
|
|
) {
|
|
exportmap = SDL_CreateRGBSurface(SDL_SWSURFACE,map[curmap].width, screen->h - STATUSH,
|
|
buffer->format->BitsPerPixel, buffer->format->Rmask,
|
|
buffer->format->Gmask,buffer->format->Bmask,
|
|
buffer->format->Amask);
|
|
|
|
state = S_NONE;
|
|
prevgrid = gridsize;
|
|
setgridsize(0);
|
|
drawmap(FALSE);
|
|
gridsize = prevgrid;
|
|
area.x = 0;
|
|
area.y = 0;
|
|
area.w = map[curmap].width;
|
|
area.h = screen->h - STATUSH;
|
|
SDL_BlitSurface(screen,&area,exportmap, 0);
|
|
if (SavePNG(filename, exportmap, TRUE)) {
|
|
seterror(255);
|
|
sprintf(statustext,"ERROR: Could not export to PNG file '%s'.\n",filename);
|
|
drawstatusbar();
|
|
return TRUE;
|
|
}
|
|
setinfo(255);
|
|
sprintf(statustext,"Successfully exported map to PNG file '%s'.\n",filename);
|
|
drawtoolbox();
|
|
drawstatusbar();
|
|
return FALSE;
|
|
}
|
|
/* export to SVG format */
|
|
if ((filename[eoff] == '.') &&
|
|
((filename[eoff+1] == 's') || (filename[eoff+1] == 'S')) &&
|
|
((filename[eoff+2] == 'v') || (filename[eoff+2] == 'V')) &&
|
|
((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;
|
|
}
|
|
|
|
|
|
/* dump version, 8 bytes, right padded with 0s */
|
|
sprintf(vers, "V%-7s", VERSION);
|
|
fwrite(vers, 8, 1, f);
|
|
|
|
/* dump out numbers of map[curmap].objects */
|
|
fwrite(&nummaps, sizeof(int), 1, f);
|
|
|
|
for (i = 0; i < nummaps; i++) {
|
|
fwrite(&map[i].width, sizeof(int), 1, f);
|
|
fwrite(&map[i].height, sizeof(int), 1, f);
|
|
fwrite(&map[i].bpp, sizeof(int), 1, f);
|
|
fwrite(&map[i].bgcol, sizeof(SDL_Color), 1, f);
|
|
fwrite(&map[i].boxcol, sizeof(SDL_Color), 1, f);
|
|
fwrite(&map[i].numthings, sizeof(int), 1, f);
|
|
fwrite(&map[i].numobjects, sizeof(int), 1, f);
|
|
fwrite(&map[i].numlinks, sizeof(int), 1, f);
|
|
fwrite(&map[i].numtext, sizeof(int), 1, f);
|
|
/* selecteditem*/
|
|
/* selecteditemtype*/
|
|
/* selectedlinkpoint*/
|
|
/* selectedtype*/
|
|
/* curobj*/
|
|
/* curlink*/
|
|
/* curlinkpoint*/
|
|
/* curtext*/
|
|
/* startx,starty */
|
|
/* textanchor */
|
|
/* text*/
|
|
namelen = strlen(map[i].name);
|
|
fwrite(&namelen, sizeof(int), 1, f);
|
|
fwrite(&map[i].name, (namelen+1) * sizeof(char), 1, f);
|
|
|
|
/* write objects */
|
|
fwrite(&map[i].thing, sizeof(thing_t), map[i].numthings, f);
|
|
fwrite(&map[i].olink, sizeof(link_t), map[i].numlinks, f);
|
|
fwrite(&map[i].obj, sizeof(mapobject_t), map[i].numobjects, f);
|
|
fwrite(&map[i].textob, sizeof(text_t), map[i].numtext, f);
|
|
}
|
|
|
|
fclose(f);
|
|
|
|
|
|
setmod(FALSE);
|
|
setinfo(255);
|
|
sprintf(statustext,"Successfully saved map to '%s'.\n",filename);
|
|
|
|
/* save filename */
|
|
strcpy(currentfilename, filename);
|
|
|
|
updatewm();
|
|
|
|
return 0;
|
|
}
|
|
|
|
void scrollmaplist(int amt) {
|
|
maplistpos += amt;
|
|
|
|
if (amt < 0) {
|
|
if (maplistpos < 0) maplistpos = 0;
|
|
} else if (amt > 0) {
|
|
if (maplistpos >= nummaps) {
|
|
maplistpos = nummaps - 1;
|
|
}
|
|
}
|
|
|
|
drawmaplist(screen);
|
|
}
|
|
|
|
void scrollobox(int amt) {
|
|
int fitx,fity,fit;
|
|
|
|
if (amt < 0) {
|
|
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);
|
|
fity = ((obox.height+3) / obox.gridsize);
|
|
fit = fitx * fity;
|
|
|
|
/* check if incrementing position is okay or not */
|
|
//if (((obox.pos+amt)*3 + fit) <= (numobjtypes+2)) {
|
|
while (((obox.pos+amt)*3 + fit) > (numobjtypes+2)) {
|
|
amt--;
|
|
}
|
|
obox.pos+= amt;
|
|
drawobox();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
int showfiledialog(void) {
|
|
Uint32 fillcol;
|
|
SDL_Rect area,sarea;
|
|
int y;
|
|
SDL_Color ccol;
|
|
int tw,th;
|
|
char t[BUFLEN];
|
|
|
|
|
|
/* clear map */
|
|
fillcol = SDL_MapRGB(buffer->format, map[curmap].bgcol.r,map[curmap].bgcol.g,map[curmap].bgcol.b);
|
|
SDL_FillRect(buffer, NULL, fillcol);
|
|
|
|
/* */
|
|
switch (state) {
|
|
case S_SAVING:
|
|
strcpy(t,"Enter save filename:");
|
|
break;
|
|
case S_LOADING:
|
|
strcpy(t,"Enter load filename:");
|
|
break;
|
|
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;
|
|
}
|
|
|
|
TTF_SizeText(font[DEFTEXTH*2], t, &tw,&th);
|
|
|
|
drawtextat(buffer, -1, (map[curmap].height / 4), t, DEFTEXTH*2, black);
|
|
if (state == S_SAVING) {
|
|
drawtextat(buffer, -1, (map[curmap].height / 4) + (th*2), "(use extension of .SVG or .BMP to export)", DEFTEXTH*2, black);
|
|
}
|
|
|
|
/* draw outlines */
|
|
drawbox(buffer,0,0,screen->w - SIDEBARW, screen->h - STATUSH, blue, NULL);
|
|
|
|
drawbox(buffer,0,((screen->h-STATUSH)/2)-2,screen->w - SIDEBARW - 1,((screen->h-STATUSH)/2)+th+2,blue, NULL);
|
|
|
|
/* actually draw the text */
|
|
TTF_SizeText(font[DEFTEXTH*2], text, &tw,&th);
|
|
|
|
/* paste old background */
|
|
if (bg != NULL) {
|
|
area.x = bgx;
|
|
area.y = bgy;
|
|
area.w = bg->w;
|
|
area.h = bg->h;
|
|
SDL_BlitSurface(bg,0,screen, &area);
|
|
// free it
|
|
//SDL_UpdateRect(screen,area.x, area.y, area.w, area.h);
|
|
SDL_FreeSurface(bg);
|
|
bg = NULL;
|
|
}
|
|
/* copy new background */
|
|
sarea.x = startx;
|
|
sarea.y = starty;
|
|
sarea.w = tw + CURSORWIDTH; // include space for cursor
|
|
sarea.h = DEFTEXTH*2;
|
|
if (bg != NULL) {
|
|
SDL_FreeSurface(bg);
|
|
bg = NULL;
|
|
}
|
|
bg = SDL_CreateRGBSurface(SDL_SWSURFACE,sarea.w, sarea.h,
|
|
buffer->format->BitsPerPixel, buffer->format->Rmask,
|
|
buffer->format->Gmask,buffer->format->Bmask,
|
|
buffer->format->Amask);
|
|
SDL_BlitSurface(screen,&sarea,bg,0);
|
|
bgx = sarea.x;
|
|
bgy = sarea.y;
|
|
|
|
/* draw text */
|
|
drawtextat(buffer, startx, starty, text, DEFTEXTH*2, black);
|
|
|
|
/* draw cursor (a solid block) */
|
|
ccol = blue;
|
|
for (y = starty ; y < (starty + th); y++ ) {
|
|
drawline(buffer, startx + tw, y, startx + tw + CURSORWIDTH,y,ccol,1);
|
|
}
|
|
|
|
/* blit to screen */
|
|
SDL_BlitSurface(buffer, 0, screen, 0);
|
|
SDL_UpdateRect(screen, 0, 0, screen->w - SIDEBARW, screen->h - STATUSH);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
void startedittext(int o) {
|
|
SDL_Rect area;
|
|
Uint32 bgcol;
|
|
|
|
/* edit text */
|
|
map[curmap].selecteditem = o;
|
|
map[curmap].selecteditemtype = T_TEXT;
|
|
|
|
/* start listening for text input */
|
|
startx = map[curmap].textob[o].x;
|
|
starty = map[curmap].textob[o].y;
|
|
textanchor = map[curmap].textob[o].anchor;
|
|
|
|
strcpy(text, map[curmap].textob[o].text);
|
|
textpos = &text[strlen(text)];
|
|
|
|
updateheight = map[curmap].textob[o].h;
|
|
|
|
bg = NULL;
|
|
/* blank out where the old text was */
|
|
|
|
|
|
if (textanchor != -1) {
|
|
startx += map[curmap].obj[textanchor].x;
|
|
starty += map[curmap].obj[textanchor].y;
|
|
}
|
|
area.x = startx - screenx;
|
|
area.y = starty - screeny;
|
|
area.w = map[curmap].textob[o].w;
|
|
area.h = TTF_FontHeight(font[map[curmap].textob[o].h]);
|
|
bgcol = SDL_MapRGB(screen->format, map[curmap].bgcol.r,map[curmap].bgcol.g,map[curmap].bgcol.b);
|
|
SDL_FillRect(screen, &area, bgcol);
|
|
SDL_UpdateRect(screen, area.x,area.y,area.w,area.h);
|
|
updatetextcursor();
|
|
|
|
changestate(S_EDITTEXT);
|
|
}
|
|
|
|
int startlink(int x, int y) {
|
|
int linex1,liney1,linex2,liney2;
|
|
int len;
|
|
|
|
xoff = (x - screenx) + (map[curmap].obj[map[curmap].curobj].x - screenx);
|
|
yoff = (y - screeny) + (map[curmap].obj[map[curmap].curobj].y - screeny);
|
|
|
|
startx = x ;
|
|
starty = y;
|
|
|
|
if (startx < 0) printf("ERRIR!#@\n");
|
|
|
|
startobj = map[curmap].curobj;
|
|
|
|
changestate(S_DRAWLINK);
|
|
|
|
/* copy line */
|
|
linex1 = startx;
|
|
liney1 = starty;
|
|
linex2 = x;
|
|
liney2 = y;
|
|
|
|
len = linelen(linex1,liney1,linex2,liney2);
|
|
linebg = malloc((len + 4) * sizeof(int));
|
|
|
|
|
|
copyline(screen, linex1,liney1,linex2,liney2, linebg );
|
|
|
|
|
|
sprintf(statustext,"Creating link #%d...\n", map[curmap].numlinks);
|
|
drawstatusbar();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int startlinkdstmove(int x, int y) {
|
|
int linex1,liney1,linex2,liney2;
|
|
int len;
|
|
|
|
startx = x;
|
|
starty = y;
|
|
|
|
changestate(S_LINKDSTMOVE);
|
|
|
|
/* copy background */
|
|
linex1 = map[curmap].obj[map[curmap].olink[map[curmap].curlink].dstobj].x + map[curmap].olink[map[curmap].olink[map[curmap].curlink].dstobj].dstxoff;
|
|
liney1 = map[curmap].obj[map[curmap].olink[map[curmap].curlink].dstobj].y + map[curmap].olink[map[curmap].olink[map[curmap].curlink].dstobj].dstyoff;
|
|
linex2 = map[curmap].obj[map[curmap].olink[map[curmap].curlink].dstobj].x + map[curmap].olink[map[curmap].olink[map[curmap].curlink].dstobj].dstxoff;
|
|
liney2 = map[curmap].obj[map[curmap].olink[map[curmap].curlink].dstobj].y + map[curmap].olink[map[curmap].olink[map[curmap].curlink].dstobj].dstyoff;
|
|
|
|
len = linelen(linex1,liney1,linex2,liney2);
|
|
linebg = malloc((len + 4) * sizeof(int));
|
|
|
|
copyline(screen, linex1,liney1,linex2,liney2, linebg );
|
|
|
|
sprintf(statustext,"Starting dst endpoint move for link #%d...\n", map[curmap].curlink); fflush(STDOUT);
|
|
drawstatusbar();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int startlinkpointmove(int x, int y) {
|
|
int linex1,liney1,linex2,liney2;
|
|
SDL_Rect area;
|
|
|
|
startx = x;
|
|
starty = y;
|
|
|
|
changestate(S_LINKPOINTMOVE);
|
|
|
|
/* copy background */
|
|
linex1 = map[curmap].olink[map[curmap].curlink].point[map[curmap].curlinkpoint].x - (LINESELHANDLESIZE / 2);
|
|
liney1 = map[curmap].olink[map[curmap].curlink].point[map[curmap].curlinkpoint].y - (LINESELHANDLESIZE / 2);
|
|
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;
|
|
|
|
if (bg != NULL) {
|
|
SDL_FreeSurface(bg);
|
|
bg = NULL;
|
|
}
|
|
bg = SDL_CreateRGBSurface(SDL_SWSURFACE, LINESELHANDLESIZE, LINESELHANDLESIZE,
|
|
screen->format->BitsPerPixel, screen->format->Rmask,
|
|
screen->format->Gmask,screen->format->Bmask,
|
|
screen->format->Amask);
|
|
|
|
bgx = linex1;
|
|
bgy = liney1;
|
|
|
|
area.x = linex1;
|
|
area.y = liney1;
|
|
area.w = LINESELHANDLESIZE+4;
|
|
area.h = LINESELHANDLESIZE+4;
|
|
SDL_BlitSurface(screen, &area, bg,0);
|
|
|
|
sprintf(statustext,"Moving link point #%d of link #%d... (%d,%d)\n", map[curmap].curlinkpoint,map[curmap].curlink, x, y);
|
|
drawstatusbar();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int startlinksrcmove(int x, int y) {
|
|
int linex1,liney1,linex2,liney2;
|
|
int len;
|
|
|
|
startx = x;
|
|
starty = y;
|
|
|
|
changestate(S_LINKSRCMOVE);
|
|
|
|
/* copy background */
|
|
linex1 = map[curmap].obj[map[curmap].olink[map[curmap].curlink].srcobj].x + map[curmap].olink[map[curmap].olink[map[curmap].curlink].srcobj].srcxoff;
|
|
liney1 = map[curmap].obj[map[curmap].olink[map[curmap].curlink].srcobj].y + map[curmap].olink[map[curmap].olink[map[curmap].curlink].srcobj].srcyoff;
|
|
linex2 = map[curmap].obj[map[curmap].olink[map[curmap].curlink].dstobj].x + map[curmap].olink[map[curmap].olink[map[curmap].curlink].dstobj].dstxoff;
|
|
liney2 = map[curmap].obj[map[curmap].olink[map[curmap].curlink].dstobj].y + map[curmap].olink[map[curmap].olink[map[curmap].curlink].dstobj].dstyoff;
|
|
|
|
len = linelen(linex1,liney1,linex2,liney2);
|
|
if (len <= 0) {
|
|
printf("ERROR: length is zero or negative - %d\n",len);
|
|
fflush(STDOUT);
|
|
exit(1);
|
|
}
|
|
linebg = malloc((len + 4) * sizeof(int));
|
|
|
|
if (linebg == NULL) {
|
|
printf("ERROR: cannot malloc()\n"); fflush(STDOUT);
|
|
}
|
|
|
|
copyline(screen, linex1,liney1,linex2,liney2, linebg);
|
|
|
|
sprintf(statustext,"Starting src endpoint move for link #%d...\n", map[curmap].curlink); fflush(STDOUT);
|
|
drawstatusbar();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int startlinkmove (int x, int y) {
|
|
int linex1,liney1;
|
|
int linex2,liney2;
|
|
int len;
|
|
|
|
startx = x - screenx;
|
|
starty = y - screeny;
|
|
changestate(S_LINKMOVING);
|
|
/* copy background */
|
|
linex1 = map[curmap].obj[map[curmap].olink[map[curmap].curlink].srcobj].x - screenx + map[curmap].olink[map[curmap].olink[map[curmap].curlink].srcobj].srcxoff;
|
|
liney1 = map[curmap].obj[map[curmap].olink[map[curmap].curlink].srcobj].y - screeny + map[curmap].olink[map[curmap].olink[map[curmap].curlink].srcobj].srcyoff;
|
|
linex2 = map[curmap].obj[map[curmap].olink[map[curmap].curlink].dstobj].x - screenx + map[curmap].olink[map[curmap].olink[map[curmap].curlink].dstobj].dstxoff;
|
|
liney2 = map[curmap].obj[map[curmap].olink[map[curmap].curlink].dstobj].y - screeny + map[curmap].olink[map[curmap].olink[map[curmap].curlink].dstobj].dstyoff;
|
|
|
|
len = linelen(linex1,liney1,linex2,liney2);
|
|
if (len <= 0) {
|
|
printf("ERROR: length is zero or negative - %d\n",len);
|
|
fflush(STDOUT);
|
|
exit(1);
|
|
}
|
|
linebg = malloc((len+4) * sizeof(int));
|
|
if (linebg == NULL) {
|
|
printf("ERROR: cannot malloc()\n"); fflush(STDOUT);
|
|
}
|
|
|
|
copyline(screen, linex1,liney1,linex2,liney2, linebg);
|
|
|
|
sprintf(statustext,"Starting move of link #%d...\n", map[curmap].curlink); fflush(STDOUT);
|
|
drawstatusbar();
|
|
|
|
|
|
return 0;
|
|
}
|
|
|
|
int startobjmove (int x, int y) {
|
|
SDL_Rect area;
|
|
|
|
xoff = map[curmap].obj[map[curmap].curobj].x - x;
|
|
yoff = map[curmap].obj[map[curmap].curobj].y - y;
|
|
|
|
startx = x;
|
|
starty = y;
|
|
changestate(S_OBJMOVING);
|
|
/* copy background */
|
|
if (bg != NULL) {
|
|
SDL_FreeSurface(bg);
|
|
bg = NULL;
|
|
}
|
|
bg = SDL_CreateRGBSurface(SDL_SWSURFACE,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);
|
|
area.x = map[curmap].obj[map[curmap].curobj].x;
|
|
area.y = map[curmap].obj[map[curmap].curobj].y;
|
|
area.w = map[curmap].obj[map[curmap].curobj].w;
|
|
area.h = map[curmap].obj[map[curmap].curobj].h;
|
|
SDL_BlitSurface(screen,&area,bg,0);
|
|
bgx = area.x;
|
|
bgy = area.y;
|
|
bgw = area.w;
|
|
bgh = area.h;
|
|
|
|
/* take a copy of the object itself */
|
|
if (shadow != NULL) {
|
|
SDL_FreeSurface(shadow);
|
|
shadow = NULL;
|
|
}
|
|
shadow = SDL_CreateRGBSurface(SDL_SWSURFACE,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, TRUE);
|
|
/* 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;
|
|
}
|
|
|
|
int startresize (int x, int y) {
|
|
SDL_Rect area;
|
|
|
|
startx = x - screenx;
|
|
starty = y - screeny;
|
|
changestate(S_RESIZING);
|
|
|
|
/* copy background */
|
|
if (bg != NULL) {
|
|
SDL_FreeSurface(bg);
|
|
bg = NULL;
|
|
}
|
|
bg = SDL_CreateRGBSurface(SDL_SWSURFACE,MAXOBJWIDTH+2,MAXOBJHEIGHT+2,
|
|
screen->format->BitsPerPixel, screen->format->Rmask,
|
|
screen->format->Gmask,screen->format->Bmask,
|
|
screen->format->Amask);
|
|
area.x = map[curmap].obj[map[curmap].curobj].x - screenx;
|
|
area.y = map[curmap].obj[map[curmap].curobj].y - screeny;
|
|
area.w = map[curmap].obj[map[curmap].curobj].w+2;
|
|
area.h = map[curmap].obj[map[curmap].curobj].h+2;
|
|
SDL_BlitSurface(screen,&area,bg,0);
|
|
bgx = area.x;
|
|
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[ct].anchor == -1) {
|
|
txoff = 0;
|
|
tyoff = 0;
|
|
} else {
|
|
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 */
|
|
if (bg != NULL) {
|
|
SDL_FreeSurface(bg);
|
|
bg = NULL;
|
|
}
|
|
bg = SDL_CreateRGBSurface(SDL_SWSURFACE,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[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;
|
|
bgw = area.w;
|
|
bgh = area.h;
|
|
return 0;
|
|
}
|
|
|
|
int startSVG(char *svgfilename) {
|
|
if ((svgfile = fopen(svgfilename, "w+")) == NULL) {
|
|
return TRUE;
|
|
}
|
|
|
|
fprintf(svgfile, "<?xml version=\"1.0\" standalone=\"no\"?>\n");
|
|
fprintf(svgfile, "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://nowhere\">\n\n");
|
|
|
|
|
|
fprintf(svgfile, "<svg width=\"%d\" height=\"%d\" version=\"1.1\">\n",map[curmap].width, map[curmap].height);
|
|
|
|
return FALSE;
|
|
}
|
|
void endSVG(void) {
|
|
fprintf(svgfile, "\n</svg>\n");
|
|
fclose(svgfile);
|
|
}
|
|
|
|
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;
|
|
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;
|
|
}
|
|
|
|
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 */
|
|
if (bg != NULL) {
|
|
SDL_FreeSurface(bg);
|
|
bg = NULL;
|
|
}
|
|
bg = SDL_CreateRGBSurface(SDL_SWSURFACE,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 = 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 */
|
|
if (shadow != NULL) {
|
|
SDL_FreeSurface(shadow);
|
|
shadow = NULL;
|
|
}
|
|
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;
|
|
}
|
|
|
|
|
|
int textat(int x, int y) {
|
|
int i,anchor;
|
|
for (i = 0; i < map[curmap].numtext; i++) {
|
|
anchor = map[curmap].textob[i].anchor;
|
|
if (anchor == -1) {
|
|
if ( (x >= map[curmap].textob[i].x ) && (x <= (map[curmap].textob[i].x + map[curmap].textob[i].w)) &&
|
|
(y >= map[curmap].textob[i].y ) && (y <= (map[curmap].textob[i].y + map[curmap].textob[i].h)) ) {
|
|
if (!isflow(i, T_TEXT) || (showflows == TRUE)) {
|
|
return i;
|
|
}
|
|
}
|
|
} else {
|
|
if ( (x >= map[curmap].textob[i].x + map[curmap].obj[anchor].x ) && (x <= (map[curmap].textob[i].x + map[curmap].obj[anchor].x + map[curmap].textob[i].w)) &&
|
|
(y >= map[curmap].textob[i].y + map[curmap].obj[anchor].y ) && (y <= (map[curmap].textob[i].y + map[curmap].obj[anchor].y + map[curmap].textob[i].h)) ) {
|
|
if (!isflow(i, T_TEXT) || (showflows == TRUE)) {
|
|
return i;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
void toggleflow(int oid, int otype) {
|
|
switch (otype) {
|
|
case T_OBJECT:
|
|
map[curmap].obj[oid].fillcol.unused = map[curmap].obj[oid].fillcol.unused ^ ISFLOW;
|
|
break;
|
|
case T_LINK:
|
|
map[curmap].olink[oid].col.unused = map[curmap].olink[oid].col.unused ^ ISFLOW;
|
|
break;
|
|
case T_TEXT:
|
|
map[curmap].textob[oid].c.unused = map[curmap].textob[oid].c.unused ^ ISFLOW;
|
|
break;
|
|
}
|
|
}
|
|
|
|
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.");
|
|
}
|
|
}
|
|
|
|
int thingat(int x, int y) {
|
|
int i;
|
|
int anchor;
|
|
for (i = (map[curmap].numthings-1); i >= 0; i--) {
|
|
switch (map[curmap].thing[i].type) {
|
|
case T_OBJECT:
|
|
if ( (x >= map[curmap].obj[map[curmap].thing[i].id].x ) &&
|
|
(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(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(map[curmap].thing[i].id, T_LINK) || (showflows == TRUE)) {
|
|
return i;
|
|
}
|
|
}
|
|
break;
|
|
case T_TEXT:
|
|
anchor = map[curmap].textob[map[curmap].thing[i].id].anchor;
|
|
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(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(map[curmap].thing[i].id, T_TEXT) || (showflows == TRUE)) {
|
|
return i;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
|
|
int updatefilename(void) {
|
|
int y;
|
|
SDL_Rect sarea;
|
|
SDL_Rect area;
|
|
SDL_Color ccol = blue;
|
|
int tw,th;
|
|
|
|
|
|
/* paste old background */
|
|
if (bg != NULL) {
|
|
area.x = bgx;
|
|
area.y = bgy;
|
|
area.w = bg->w;
|
|
area.h = bg->h;
|
|
SDL_BlitSurface(bg,0,screen, &area);
|
|
SDL_UpdateRect(screen, bgx, bgy, bg->w, bg->h);
|
|
// free it
|
|
SDL_FreeSurface(bg);
|
|
bg = NULL;
|
|
}
|
|
/* copy new background */
|
|
sarea.x = startx;
|
|
sarea.y = starty;
|
|
sarea.w = ((strlen(text)+1) * (DEFTEXTW*2)) +2; // include space for cursor
|
|
sarea.h = DEFTEXTH*2;
|
|
if (bg != NULL) {
|
|
SDL_FreeSurface(bg);
|
|
bg = NULL;
|
|
}
|
|
bg = SDL_CreateRGBSurface(SDL_SWSURFACE,sarea.w, sarea.h,
|
|
screen->format->BitsPerPixel, screen->format->Rmask,
|
|
screen->format->Gmask,screen->format->Bmask,
|
|
screen->format->Amask);
|
|
SDL_BlitSurface(screen,&sarea,bg,0);
|
|
bgx = sarea.x;
|
|
bgy = sarea.y;
|
|
|
|
/* draw text */
|
|
TTF_SizeText(font[DEFTEXTH*2], text, &tw, &th);
|
|
drawtextat(screen, startx, starty, text, DEFTEXTH*2, black);
|
|
|
|
/* draw cursor (a solid block) */
|
|
for (y = starty ; y < (starty + (DEFTEXTH*2)); y++ ) {
|
|
drawline(screen, startx + tw, y, startx + tw + DEFTEXTW*2,y,ccol,1);
|
|
}
|
|
|
|
SDL_UpdateRect(screen, startx, starty, tw + DEFTEXTW*2, DEFTEXTH*2);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
int updatelinkshadow(int x, int y) {
|
|
int len;
|
|
int w,h;
|
|
int tlx,tly;
|
|
int linex1,liney1,linex2,liney2;
|
|
|
|
/* replace old bg */
|
|
pasteline(screen,linebg);
|
|
|
|
/* copy current bg */
|
|
linex1 = startx;
|
|
liney1 = starty;
|
|
linex2 = x;
|
|
liney2 = y;
|
|
|
|
len = linelen(linex1,liney1,linex2,liney2);
|
|
linebg = malloc((len + 4) * sizeof(int));
|
|
|
|
copyline(screen, linex1 - screenx,liney1 - screeny,linex2,liney2, linebg);
|
|
|
|
/* draw line */
|
|
drawline(screen,linex1 - screenx,liney1 - screeny,linex2,liney2, map[curmap].boxcol,1);
|
|
|
|
if (x < startx) {
|
|
if (y < starty) {
|
|
tlx = x;
|
|
tly = y;
|
|
w = startx - x;
|
|
h = starty - y;
|
|
} else {
|
|
tlx = x;
|
|
tly = starty;
|
|
w = startx - x;
|
|
h = y - starty;
|
|
}
|
|
} else {
|
|
if (y < starty) {
|
|
tlx = startx;
|
|
tly = y;
|
|
w = x - startx;
|
|
h = starty - y;
|
|
} else {
|
|
tlx = startx;
|
|
tly = starty;
|
|
w = x - startx;
|
|
h = y - starty;
|
|
}
|
|
}
|
|
SDL_UpdateRect(screen, tlx, tly ,w,h);
|
|
//SDL_Flip(screen);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int updatelinkpointshadow(int x, int y) {
|
|
int linex1,liney1;
|
|
SDL_Rect area;
|
|
|
|
/* paste old bg */
|
|
area.x = bgx;
|
|
area.y = bgy;
|
|
area.w = bg->w;
|
|
area.h = bg->h;
|
|
SDL_BlitSurface(bg, 0, screen, &area);
|
|
|
|
SDL_UpdateRect(screen, area.x, area.y, area.w, area.h);
|
|
|
|
/* adjust for grid */
|
|
if (grid) {
|
|
x = x - (x % gridsize);
|
|
y = y - (y % gridsize);
|
|
}
|
|
|
|
/* copy background */
|
|
linex1 = x - (LINESELHANDLESIZE / 2);
|
|
liney1 = y - (LINESELHANDLESIZE / 2);
|
|
|
|
if (bg != NULL) {
|
|
SDL_FreeSurface(bg);
|
|
bg = NULL;
|
|
}
|
|
bg = SDL_CreateRGBSurface(SDL_SWSURFACE, LINESELHANDLESIZE, LINESELHANDLESIZE,
|
|
screen->format->BitsPerPixel, screen->format->Rmask,
|
|
screen->format->Gmask,screen->format->Bmask,
|
|
screen->format->Amask);
|
|
|
|
bgx = linex1;
|
|
bgy = liney1;
|
|
bgw = LINESELHANDLESIZE+4;
|
|
bgh = LINESELHANDLESIZE+4;
|
|
|
|
area.x = linex1;
|
|
area.y = liney1;
|
|
area.w = LINESELHANDLESIZE;
|
|
area.h = LINESELHANDLESIZE;
|
|
SDL_BlitSurface(screen, &area, bg,0);
|
|
|
|
/* draw link point */
|
|
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;
|
|
}
|
|
|
|
int updatemoveshadow(int x, int y) {
|
|
SDL_Rect area;
|
|
|
|
if ((x + xoff) < 0) xoff = -x;
|
|
if ((y + yoff) < 0) yoff = -y;
|
|
|
|
|
|
x += xoff;
|
|
y += yoff;
|
|
|
|
|
|
/* adjust for grid */
|
|
if (grid) {
|
|
x = x - (x % gridsize);
|
|
y = y - (y % gridsize);
|
|
}
|
|
|
|
/* replace old bg */
|
|
area.x = bgx;
|
|
area.y = bgy;
|
|
area.w = bgw;
|
|
area.h = bgh;
|
|
SDL_BlitSurface(bg, 0, screen, &area);
|
|
SDL_UpdateRect(screen, area.x, area.y, area.w, area.h);
|
|
|
|
|
|
/* copy current bg */
|
|
area.x = x;
|
|
area.y = y;
|
|
area.w = map[curmap].obj[map[curmap].curobj].w;
|
|
area.h = map[curmap].obj[map[curmap].curobj].h;
|
|
SDL_BlitSurface(screen,&area,bg,0);
|
|
bgx = area.x;
|
|
bgy = area.y;
|
|
bgw = area.w;
|
|
bgh = area.h;
|
|
|
|
|
|
/* draw box */
|
|
if ((x > 0) && (y > 0) && (x+map[curmap].obj[map[curmap].curobj].w-1 < screen->w) &&
|
|
(y+map[curmap].obj[map[curmap].curobj].h-1 < screen->h)) {
|
|
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;
|
|
}
|
|
|
|
int updateresizeshadow(int x, int y) {
|
|
SDL_Rect sarea;
|
|
SDL_Rect area;
|
|
int xdiff,ydiff;
|
|
|
|
|
|
xdiff = x - startx;
|
|
ydiff = y - starty;
|
|
|
|
/* adjust for grid */
|
|
if (grid) {
|
|
int m;
|
|
|
|
m = map[curmap].obj[map[curmap].curobj].x + map[curmap].obj[map[curmap].curobj].w + xdiff;
|
|
xdiff -= (m % gridsize);
|
|
m = map[curmap].obj[map[curmap].curobj].y + map[curmap].obj[map[curmap].curobj].h + ydiff;
|
|
ydiff -= (m % gridsize);
|
|
}
|
|
|
|
/* check for maximum object sizes */
|
|
if ((map[curmap].obj[map[curmap].curobj].w + xdiff) > MAXOBJWIDTH) xdiff = MAXOBJWIDTH - map[curmap].obj[map[curmap].curobj].w;
|
|
if ((map[curmap].obj[map[curmap].curobj].h + ydiff) > MAXOBJHEIGHT) ydiff = MAXOBJHEIGHT - map[curmap].obj[map[curmap].curobj].h;
|
|
if ((map[curmap].obj[map[curmap].curobj].w + xdiff) < MINOBJWIDTH) xdiff = MINOBJWIDTH - map[curmap].obj[map[curmap].curobj].w ;
|
|
if ((map[curmap].obj[map[curmap].curobj].h + ydiff) < MINOBJHEIGHT) ydiff = MINOBJHEIGHT - map[curmap].obj[map[curmap].curobj].h ;
|
|
|
|
/* check for edges of screen */
|
|
/*
|
|
if ((map[curmap].obj[map[curmap].curobj].x + map[curmap].obj[map[curmap].curobj].w + xdiff) >= screen->w) {
|
|
xdiff = 0;
|
|
}
|
|
if ((map[curmap].obj[map[curmap].curobj].y + map[curmap].obj[map[curmap].curobj].h + ydiff) >= screen->h) {
|
|
ydiff = 0;
|
|
//ydiff = (map[curmap].height - map[curmap].obj[map[curmap].curobj].h);
|
|
}
|
|
*/
|
|
|
|
/* replace old bg */
|
|
|
|
area.x = bgx;
|
|
area.y = bgy;
|
|
area.w = bgw;
|
|
area.h = bgh;
|
|
|
|
sarea.x = 0;
|
|
sarea.y = 0;
|
|
sarea.w = bgw;
|
|
sarea.h = bgh;
|
|
|
|
SDL_BlitSurface(bg, &sarea, screen, &area);
|
|
SDL_UpdateRect(screen, area.x, area.y, area.w, area.h);
|
|
/* copy current bg */
|
|
area.x = map[curmap].obj[map[curmap].curobj].x - screenx;
|
|
area.y = map[curmap].obj[map[curmap].curobj].y - screeny;
|
|
area.w = map[curmap].obj[map[curmap].curobj].w + xdiff + 2;
|
|
area.h = map[curmap].obj[map[curmap].curobj].h + ydiff + 2;
|
|
if (area.w < MINOBJWIDTH) area.w = MINOBJWIDTH;
|
|
if (area.h < MINOBJHEIGHT) area.h = MINOBJHEIGHT;
|
|
SDL_BlitSurface(screen,&area,bg,0);
|
|
bgx = area.x;
|
|
bgy = area.y;
|
|
bgw = area.w;
|
|
bgh = area.h;
|
|
|
|
/* draw box */
|
|
|
|
drawbox(screen, map[curmap].obj[map[curmap].curobj].x - screenx,
|
|
map[curmap].obj[map[curmap].curobj].y - screeny,
|
|
map[curmap].obj[map[curmap].curobj].x - screenx+map[curmap].obj[map[curmap].curobj].w + xdiff,
|
|
map[curmap].obj[map[curmap].curobj].y - screeny+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;
|
|
}
|
|
|
|
int updateresizetextshadow(int x, int y) {
|
|
SDL_Rect sarea;
|
|
SDL_Rect area;
|
|
int xdiff,ydiff;
|
|
int txoff,tyoff;
|
|
|
|
int textsize;
|
|
char *tp;
|
|
int tw,th;
|
|
int ct;
|
|
|
|
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[ct].anchor].x;
|
|
tyoff = map[curmap].obj[map[curmap].textob[ct].anchor].y;
|
|
}
|
|
|
|
ydiff = y - starty;
|
|
|
|
|
|
/* 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;
|
|
xdiff = tw - map[curmap].textob[map[curmap].curtext].w;
|
|
|
|
|
|
/* replace old bg */
|
|
area.x = bgx;
|
|
area.y = bgy;
|
|
area.w = bgw;
|
|
area.h = bgh;
|
|
|
|
sarea.x = 0;
|
|
sarea.y = 0;
|
|
sarea.w = bgw;
|
|
sarea.h = bgh;
|
|
|
|
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[ct].x + txoff - screenx;
|
|
area.y = map[curmap].textob[ct].y + tyoff - screeny;
|
|
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;
|
|
|
|
SDL_BlitSurface(screen,&area,bg,0);
|
|
bgx = area.x;
|
|
bgy = area.y;
|
|
bgw = area.w;
|
|
bgh = area.h;
|
|
|
|
/* draw box */
|
|
|
|
x1 = map[curmap].textob[ct].x + txoff - screenx;
|
|
y1 = map[curmap].textob[ct].y + tyoff - screeny;
|
|
x2 = map[curmap].textob[ct].x + txoff + tw - screenx;
|
|
y2 = map[curmap].textob[ct].y + tyoff + th - screeny;
|
|
|
|
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;
|
|
}
|
|
|
|
int updatetextcursor(void) {
|
|
int y;
|
|
SDL_Rect sarea;
|
|
SDL_Rect area;
|
|
SDL_Color ccol = blue;
|
|
int tw,th;
|
|
int len;
|
|
//int lenpix;
|
|
int sw,sh;
|
|
int cwid, dummy;
|
|
char tempbuf[BUFLEN];
|
|
|
|
if ((state == S_SAVING) || (state == S_LOADING) || (state == S_MAPNAMING) || (state == S_SEARCH)) {
|
|
showfiledialog();
|
|
return 0;
|
|
}
|
|
|
|
|
|
/* paste old background */
|
|
if (bg != NULL) {
|
|
/*
|
|
area.x = bgx - screenx;
|
|
area.y = bgy - screeny;
|
|
*/
|
|
area.x = bgx;
|
|
area.y = bgy;
|
|
area.w = bg->w;
|
|
area.h = bg->h;
|
|
SDL_BlitSurface(bg,0,screen, &area);
|
|
SDL_UpdateRect(screen, area.x,area.y, area.w, area.h);
|
|
// free it
|
|
SDL_FreeSurface(bg);
|
|
bg = NULL;
|
|
}
|
|
/* copy new background */
|
|
sarea.x = startx - screenx;
|
|
sarea.y = starty - screeny;
|
|
/* calculate text width */
|
|
TTF_SizeText(font[updateheight], text, &tw, &th);
|
|
sarea.w = tw + CURSORWIDTH + 3;
|
|
sarea.h = th;
|
|
//sarea.h = DEFTEXTH;
|
|
//sarea.w = ((strlen(text)+1) * (DEFTEXTW)) +2; // include space for cursor
|
|
if (bg != NULL) {
|
|
SDL_FreeSurface(bg);
|
|
bg = NULL;
|
|
}
|
|
bg = SDL_CreateRGBSurface(SDL_SWSURFACE,sarea.w, sarea.h,
|
|
screen->format->BitsPerPixel, screen->format->Rmask,
|
|
screen->format->Gmask,screen->format->Bmask,
|
|
screen->format->Amask);
|
|
SDL_BlitSurface(screen,&sarea,bg,0);
|
|
bgx = sarea.x;
|
|
bgy = sarea.y;
|
|
|
|
// xxxxxxxxxx
|
|
|
|
// figure out where to draw cursor
|
|
len = textpos - text;
|
|
|
|
sprintf(tempbuf, text);
|
|
tempbuf[len] = '\0';
|
|
TTF_SizeText(font[updateheight], tempbuf, &sw, &sh);
|
|
|
|
// find width of next char
|
|
if (*textpos == '\0') {
|
|
cwid = CURSORWIDTH;
|
|
} else {
|
|
tempbuf[0] = *textpos;
|
|
tempbuf[1] = '\0';
|
|
TTF_SizeText(font[updateheight], tempbuf, &cwid, &dummy);
|
|
}
|
|
|
|
// oooooooooooooooooooooo
|
|
|
|
/* draw cursor (a solid block) */
|
|
for (y = starty ; y < (starty + sh); y++ ) {
|
|
drawline(screen, startx - screenx + sw+1, y - screeny,
|
|
startx - screenx + sw + cwid,y - screeny,ccol,1);
|
|
|
|
}
|
|
|
|
/* draw text */
|
|
drawtextat(screen, startx - screenx, starty - screeny, text, updateheight, fgcol);
|
|
|
|
|
|
// update screen
|
|
SDL_UpdateRect(screen, startx - screenx, starty - screeny,
|
|
startx - screenx + tw + cwid + 3 , th);
|
|
|
|
//SDL_Flip(screen);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
|
|
/*
|
|
endxoff = x - map[curmap].obj[endobj].x;
|
|
endyoff = y - map[curmap].obj[endobj].y;
|
|
*/
|
|
/* centre offsets*/
|
|
xoff = (map[curmap].obj[startobj].w / 2);
|
|
yoff = (map[curmap].obj[startobj].h / 2);
|
|
endxoff = (map[curmap].obj[endobj].w / 2);
|
|
endyoff = (map[curmap].obj[endobj].h / 2);
|
|
|
|
/* adjust for grid */
|
|
if (grid) {
|
|
xoff = xoff - ((map[curmap].obj[startobj].x + xoff) % gridsize);
|
|
yoff = yoff - ((map[curmap].obj[startobj].y + yoff) % gridsize);
|
|
endxoff = endxoff - ((map[curmap].obj[startobj].x + endxoff) % gridsize);
|
|
endyoff = endyoff - ((map[curmap].obj[startobj].y + endyoff) % gridsize);
|
|
}
|
|
|
|
map[curmap].olink[map[curmap].numlinks].srcobj = startobj;
|
|
map[curmap].olink[map[curmap].numlinks].srcxoff = xoff;
|
|
map[curmap].olink[map[curmap].numlinks].srcyoff = yoff;
|
|
|
|
map[curmap].olink[map[curmap].numlinks].dstobj = endobj;
|
|
map[curmap].olink[map[curmap].numlinks].dstxoff = endxoff;
|
|
map[curmap].olink[map[curmap].numlinks].dstyoff = endyoff;
|
|
|
|
map[curmap].olink[map[curmap].numlinks].col = fgcol;
|
|
map[curmap].olink[map[curmap].numlinks].col.unused &= ~(ISFLOW);
|
|
|
|
map[curmap].olink[map[curmap].numlinks].npoints = 0;
|
|
|
|
arrow = defarrow;
|
|
style = defstyle;
|
|
thickness = defthickness;
|
|
|
|
map[curmap].olink[map[curmap].numlinks].style = (arrow << 16) | (style << 8) | (thickness);
|
|
|
|
/* add to 'thing' list */
|
|
/* links start below their endpoints but above other things */
|
|
/* shuffle all things up */
|
|
|
|
/* 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[insertpoint].type = T_LINK;
|
|
map[curmap].thing[insertpoint].id = map[curmap].numlinks;
|
|
|
|
setmod(TRUE);
|
|
sprintf(statustext,"Link #%d created (from object #%d to object #%d).\n", map[curmap].numlinks, startobj, endobj);
|
|
map[curmap].numlinks++;
|
|
map[curmap].numthings++;
|
|
drawstatusbar();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int endlinkdstmove(int x, int y) {
|
|
int o;
|
|
|
|
/* free variable */
|
|
if (linebg) free(linebg);
|
|
|
|
|
|
/* find which map[curmap].object it's over */
|
|
o = objat(x, y);
|
|
|
|
if (o == -1) {
|
|
/* if it's not over an map[curmap].object, abort the move */
|
|
changestate(S_NONE);
|
|
map[curmap].curlink = -1;
|
|
|
|
sprintf(statustext,"Move of link #%d dst endpoint aborted.\n",map[curmap].curlink);
|
|
} else if (o == map[curmap].olink[map[curmap].curlink].dstobj) {
|
|
/* if over the same map[curmap].object, update offsets */
|
|
map[curmap].olink[map[curmap].curlink].dstxoff = x - map[curmap].obj[o].x;
|
|
map[curmap].olink[map[curmap].curlink].dstyoff = y - map[curmap].obj[o].y;
|
|
|
|
setmod(TRUE);
|
|
sprintf(statustext,"Link #%d dst endpoint moved to offset (+%d,+%d).\n",map[curmap].curlink, map[curmap].olink[map[curmap].curlink].dstxoff,map[curmap].olink[map[curmap].curlink].dstyoff);
|
|
} else {
|
|
/* else if over a new map[curmap].object, update map[curmap].objid and offsets */
|
|
map[curmap].olink[map[curmap].curlink].dstobj = o;
|
|
map[curmap].olink[map[curmap].curlink].dstxoff = x - map[curmap].obj[o].x;
|
|
map[curmap].olink[map[curmap].curlink].dstyoff = y - map[curmap].obj[o].y;
|
|
|
|
setmod(TRUE);
|
|
sprintf(statustext,"Link #%d dst endpoint moved to object %d(+%d,+%d).\n",map[curmap].curlink,o, map[curmap].olink[map[curmap].curlink].dstxoff,map[curmap].olink[map[curmap].curlink].dstyoff);
|
|
}
|
|
drawstatusbar();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int endlinkpointmove(int x, int y) {
|
|
/* free variable */
|
|
if (bg) {
|
|
SDL_FreeSurface(bg);
|
|
bg = NULL;
|
|
}
|
|
|
|
|
|
/* adjust for grid */
|
|
if (grid) {
|
|
x = x - (x % gridsize);
|
|
y = y - (y % gridsize);
|
|
}
|
|
|
|
map[curmap].olink[map[curmap].curlink].point[map[curmap].curlinkpoint].x = x;
|
|
map[curmap].olink[map[curmap].curlink].point[map[curmap].curlinkpoint].y = y;
|
|
|
|
setmod(TRUE);
|
|
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;
|
|
}
|
|
|
|
int endlinksrcmove(int x, int y) {
|
|
int o;
|
|
|
|
/* free variable */
|
|
if (linebg) free(linebg);
|
|
|
|
/* find which map[curmap].object it's over */
|
|
o = objat(x, y);
|
|
|
|
if (o == -1) {
|
|
/* if it's not over an map[curmap].object, abort the move */
|
|
changestate(S_NONE);
|
|
map[curmap].curlink = -1;
|
|
|
|
sprintf(statustext,"Move of link #%d src endpoint aborted.\n",map[curmap].curlink);
|
|
} else if (o == map[curmap].olink[map[curmap].curlink].srcobj) {
|
|
/* if over the same map[curmap].object, update offsets */
|
|
map[curmap].olink[map[curmap].curlink].srcxoff = x - map[curmap].obj[o].x;
|
|
map[curmap].olink[map[curmap].curlink].srcyoff = y - map[curmap].obj[o].y;
|
|
|
|
setmod(TRUE);
|
|
sprintf(statustext,"Link #%d src endpoint moved to offset (+%d,+%d).\n",map[curmap].curlink, map[curmap].olink[map[curmap].curlink].srcxoff,map[curmap].olink[map[curmap].curlink].srcyoff);
|
|
} else {
|
|
/* else if over a new map[curmap].object, update map[curmap].objid and offsets */
|
|
map[curmap].olink[map[curmap].curlink].srcobj = o;
|
|
map[curmap].olink[map[curmap].curlink].srcxoff = x - map[curmap].obj[o].x;
|
|
map[curmap].olink[map[curmap].curlink].srcyoff = y - map[curmap].obj[o].y;
|
|
|
|
setmod(TRUE);
|
|
sprintf(statustext,"Link #%d src endpoint moved to object %d(+%d,+%d).\n",map[curmap].curlink,o, map[curmap].olink[map[curmap].curlink].srcxoff,map[curmap].olink[map[curmap].curlink].srcyoff);
|
|
}
|
|
drawstatusbar();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int endlinkmove(int x, int y) {
|
|
/* free variable */
|
|
//printf("about to free linebg (0x%x)\n",linebg); fflush(STDOUT);
|
|
if (linebg) free(linebg);
|
|
|
|
|
|
setmod(TRUE);
|
|
/* TODO: move the line */
|
|
|
|
return 0;
|
|
}
|
|
|
|
void drillto(int mapnum) {
|
|
if (mapnum == C_NONE) {
|
|
if (nummaps < (MAXMAPS-1)) {
|
|
/* push current map */
|
|
history[numhistory] = curmap;
|
|
numhistory++;
|
|
|
|
/* change child */
|
|
map[curmap].obj[map[curmap].selecteditem].child = nummaps;
|
|
|
|
/* create a new map */
|
|
initmap(nummaps);
|
|
|
|
/* select the new map */
|
|
changemap(nummaps);
|
|
|
|
nummaps++;
|
|
setinfo(255);
|
|
sprintf(statustext,"Drilled down (new map created).");
|
|
|
|
startx = 1;
|
|
starty = ((screen->h - STATUSH)/2)-2;
|
|
bg = NULL;
|
|
strcpy(text, map[curmap].name);
|
|
changestate(S_MAPNAMING);
|
|
|
|
drawmap(TRUE);
|
|
} else {
|
|
seterror(255);
|
|
sprintf(statustext, "ERROR: Maximum number of maps reached.");
|
|
drawstatusbar();
|
|
}
|
|
} else if (mapnum == C_SCROLLUP) {
|
|
mapbox.offset--;
|
|
drawmapbox();
|
|
} else if (mapnum == C_SCROLLDOWN) {
|
|
mapbox.offset++;
|
|
drawmapbox();
|
|
} else {
|
|
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);
|
|
|
|
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(TRUE);
|
|
}
|
|
}
|
|
|
|
int endobjmove(int x, int y) {
|
|
int newx, newy;
|
|
|
|
SDL_FreeSurface(bg);
|
|
bg = NULL;
|
|
SDL_FreeSurface(shadow);
|
|
shadow = NULL;
|
|
|
|
/* check position */
|
|
/*if ((map[curmap].obj[map[curmap].curobj].x + x - startx) >= (map[curmap].width - map[curmap].obj[map[curmap].curobj].w)) {
|
|
return -1;
|
|
}
|
|
if ((map[curmap].obj[map[curmap].curobj].y + y - starty) >= (map[curmap].height - map[curmap].obj[map[curmap].curobj].h)) {
|
|
return -1;
|
|
}
|
|
*/
|
|
if (map[curmap].obj[map[curmap].curobj].y + y - starty <= 0) {
|
|
return -1;
|
|
}
|
|
if (map[curmap].obj[map[curmap].curobj].x + x - startx <= 0) {
|
|
return -1;
|
|
}
|
|
|
|
|
|
setmod(TRUE);
|
|
newx = map[curmap].obj[map[curmap].curobj].x + (x - startx);
|
|
newy = map[curmap].obj[map[curmap].curobj].y + (y - starty);
|
|
|
|
/* adjust for grid */
|
|
if (grid) {
|
|
newx = newx - (newx % gridsize);
|
|
newy = newy - (newy % gridsize);
|
|
}
|
|
|
|
|
|
map[curmap].obj[map[curmap].curobj].x = newx;
|
|
map[curmap].obj[map[curmap].curobj].y = newy;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int endresize(int x, int y) {
|
|
int origw,origh;
|
|
int neww,newh;
|
|
int i;
|
|
float xscale,yscale;
|
|
|
|
|
|
SDL_FreeSurface(bg);
|
|
bg = NULL;
|
|
|
|
origw = map[curmap].obj[map[curmap].curobj].w;
|
|
origh = map[curmap].obj[map[curmap].curobj].h;
|
|
neww = map[curmap].obj[map[curmap].curobj].w;
|
|
newh = map[curmap].obj[map[curmap].curobj].h;
|
|
|
|
|
|
if (map[curmap].obj[map[curmap].curobj].w + (x - startx) > 0) {
|
|
neww = map[curmap].obj[map[curmap].curobj].w + (x - startx);
|
|
}
|
|
if (map[curmap].obj[map[curmap].curobj].h + (y - starty) > 0) {
|
|
newh = map[curmap].obj[map[curmap].curobj].h + (y - starty);
|
|
}
|
|
|
|
if (neww < MINOBJWIDTH) neww = MINOBJWIDTH;
|
|
if (newh < MINOBJHEIGHT) newh = MINOBJHEIGHT;
|
|
if (neww > MAXOBJWIDTH) neww = MAXOBJWIDTH;
|
|
if (newh > MAXOBJHEIGHT) newh = MAXOBJHEIGHT;
|
|
|
|
if (map[curmap].obj[map[curmap].curobj].x + neww >= map[curmap].width) {
|
|
neww = map[curmap].width - map[curmap].obj[map[curmap].curobj].x-1;
|
|
}
|
|
if (map[curmap].obj[map[curmap].curobj].y + newh >= map[curmap].height) {
|
|
newh = map[curmap].height - map[curmap].obj[map[curmap].curobj].y-1;
|
|
}
|
|
|
|
/* adjust for grid */
|
|
if (grid) {
|
|
int m;
|
|
|
|
m = map[curmap].obj[map[curmap].curobj].x + neww;
|
|
neww -= (m % gridsize);
|
|
|
|
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 */
|
|
/* 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;
|
|
}
|
|
}
|
|
|
|
|
|
/* 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) {
|
|
map[curmap].textob[i].x = map[curmap].textob[i].x * xscale;
|
|
map[curmap].textob[i].y = map[curmap].textob[i].y * yscale;
|
|
}
|
|
}
|
|
|
|
setmod(TRUE);
|
|
drawmap(TRUE);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int endtextresize(int x, int y) {
|
|
int origw,origh;
|
|
int neww,newh;
|
|
|
|
char *tp;
|
|
int tw,th;
|
|
|
|
SDL_FreeSurface(bg);
|
|
bg = NULL;
|
|
|
|
origw = map[curmap].textob[map[curmap].curtext].w;
|
|
origh = map[curmap].textob[map[curmap].curtext].h;
|
|
neww = map[curmap].textob[map[curmap].curtext].w;
|
|
newh = map[curmap].textob[map[curmap].curtext].h;
|
|
|
|
|
|
if (map[curmap].textob[map[curmap].curtext].h + (y - starty) > 0) {
|
|
newh = map[curmap].textob[map[curmap].curtext].h + (y - starty);
|
|
}
|
|
|
|
/* check for valid height */
|
|
if (newh < MINLETTERHEIGHT) newh = MINLETTERHEIGHT;
|
|
if (newh >= MAXLETTERHEIGHT) newh = MAXLETTERHEIGHT-1;
|
|
if ((map[curmap].textob[map[curmap].curtext].y + newh) >= map[curmap].height ) newh = map[curmap].height - map[curmap].textob[map[curmap].curtext].y - 1;
|
|
|
|
/* calculate new width based on height */
|
|
tp = map[curmap].textob[map[curmap].curtext].text;
|
|
TTF_SizeText(font[newh], tp, &tw, &th);
|
|
|
|
neww = tw;
|
|
|
|
if ((map[curmap].textob[map[curmap].curtext].x + neww) >= map[curmap].width ) neww = map[curmap].width - map[curmap].textob[map[curmap].curtext].x - 1;
|
|
|
|
map[curmap].textob[map[curmap].curtext].w = neww;
|
|
map[curmap].textob[map[curmap].curtext].h = newh;
|
|
|
|
/* update default text size */
|
|
/* TODO: is this useful? */
|
|
/*
|
|
objtype[map[curmap].obj[map[curmap].curobj].type].defw = neww;
|
|
objtype[map[curmap].obj[map[curmap].curobj].type].defh = newh;
|
|
*/
|
|
|
|
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(TRUE);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int updatetextshadow(int x, int y) {
|
|
int th;
|
|
SDL_Rect area;
|
|
|
|
|
|
x += xoff;
|
|
y += yoff;
|
|
|
|
if (x < 0) x = 0;
|
|
if (y < 0) y = 0;
|
|
|
|
/* replace old bg */
|
|
area.x = bgx;
|
|
area.y = bgy;
|
|
area.w = bgw;
|
|
area.h = bgh;
|
|
SDL_BlitSurface(bg, 0, screen, &area);
|
|
SDL_UpdateRect(screen, area.x, area.y, area.w, area.h);
|
|
|
|
/* adjust for grid */
|
|
if (grid) {
|
|
x = x - (x % gridsize);
|
|
y = y - (y % gridsize);
|
|
}
|
|
|
|
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 = th+5;
|
|
SDL_BlitSurface(screen,&area,bg,0);
|
|
bgx = area.x;
|
|
bgy = area.y;
|
|
bgw = area.w;
|
|
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;
|
|
}
|
|
|
|
void updatewm(void) {
|
|
char progname[SMALLBUFLEN];
|
|
char verstring[BUFLEN];
|
|
char filestring[BUFLEN];
|
|
|
|
if (readonly) {
|
|
sprintf(progname, "netmapr viewer");
|
|
} else {
|
|
sprintf(progname, "netmapr");
|
|
}
|
|
|
|
if (!strcmp(currentfilename,"")) {
|
|
strcpy(filestring, "(no file)");
|
|
} else {
|
|
strcpy(filestring, currentfilename);
|
|
}
|
|
|
|
sprintf(verstring, "%s v%s - %s %s", progname, VERSION, filestring,
|
|
modified ? "*" : "");
|
|
SDL_WM_SetCaption(verstring, progname);
|
|
}
|