OSDN Git Service

wwww
[proj16/16.git] / 16 / v2 / source / MAPED / TILEED.C
1 /*\r
2 Copyright (C) 1998 BJ Eirich (aka vecna)\r
3 This program is free software; you can redistribute it and/or\r
4 modify it under the terms of the GNU General Public License\r
5 as published by the Free Software Foundation; either version 2\r
6 of the License, or (at your option) any later version.\r
7 This program is distributed in the hope that it will be useful,\r
8 but WITHOUT ANY WARRANTY; without even the implied warranty of\r
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\r
10 See the GNU General Public Lic\r
11 See the GNU General Public License for more details.\r
12 You should have received a copy of the GNU General Public License\r
13 along with this program; if not, write to the Free Software\r
14 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
15 */\r
16 \r
17 // Additional code by Richard Lau (aka Ric)\r
18 \r
19 /* Date started: 08/Jul/98 */\r
20 /* -- 29/Jul/98 --\r
21  * Heh, I've actually done quite a lot of work on this even though I intend\r
22  * to replace it. Oh well :)\r
23  *\r
24  * I've now made clicking on the mask indicator button (labelled with a small\r
25  * "m") drop back to draw mode if you're in select mode (since it makes no\r
26  * sense to select an area with the mask turned off). Holding down shift\r
27  * and dragging the mouse when you're in select mode will allow you to select\r
28  * a rectangle. The PgUp/PgDn colour shifters will now work in paste mode\r
29  * (affecting the image in the copy buffer).\r
30  *\r
31  * The fill routine is now in place and I've put a button in for the pick\r
32  * colour/eyedropper tool so that I don't get asked to put in a function for\r
33  * like I continuously did with ACE. Due to the extra buttons I've had to\r
34  * shift some of the other buttons around to make them all fit onto the\r
35  * screen. It's probably not the best arrangement but if anyone comes up with\r
36  * a better layout I'm open to suggestions.\r
37  *\r
38  * The wierd button labelling problem I had last time has been corrected - the\r
39  * problem was traced back to the pixels routine in SMALFONT.C. Aen pointed\r
40  * out that I wasn't allocating space for the NULL terminator for all the\r
41  * strings so that has now been fixed (by adding 1 to strlen).\r
42  *\r
43  * - Ric\r
44  */\r
45 /*\r
46  * Keys:\r
47  *      CTRL/S + mouse click - (over edit window) Pick up colour under mouse\r
48  *      SHIFT+mb down+drag mouse - select rectangle (select mode only)\r
49  *      SPACEBAR    - toggle between draw mode and select mode\r
50  *      CTRL+Z or U - one level undo\r
51  *      CTRL+A      - select all\r
52  *      CTRL+U      - unselect all\r
53  *      CTRL+C      - copy selected area\r
54  *      CTRL+X      - cut selected area\r
55  *      CTRL+V      - paste\r
56  *      DEL         - clears selected area\r
57  *      CTRL+R      - reverts the tile to the original (like undo in maped 1)\r
58  *                    (self note: modify to ask for confirmation)\r
59  *      G           - toggles grid on/off\r
60  *      H           - toggles hilight on/off\r
61  *      M           - toggles mask on/off\r
62  *      I           - inverts mask\r
63  *      X           - mirrors image\r
64  *      Y           - flips image\r
65  *      L/R         - Rotates tile 90 degrees anti-clockwise/clockwise\r
66  *      Q/W         - Steps through animation (in tile edit mode) if any\r
67  *      A/Z and S/X - changes the left or right drawing colours\r
68  *      PGUP/PGDN   - Colour shift up/down\r
69  *      [ and ]     - toggle screen resolutions\r
70  *      ALT+X       - quits to DOS\r
71  */\r
72 /* -- 26/Jul/98 --\r
73  * I've actually decided to start the editor over in a new file so that the\r
74  * code is a bit more elegant. As it stands some bits of this are messy but\r
75  * it currently works ;). Anyway I've decided that what I'll do is to in\r
76  * effect write two tile editors - continuing work on this one and working\r
77  * on the rewrite as a "side project". The eventual aim will be to replace\r
78  * this editor with the rewrite but if factors intervene preventing me from\r
79  * completing the rewrite then there'll always be this editor to fall back on.\r
80  *\r
81  * New in this release is a copy/cut/paste system. New buttons have been added.\r
82  * For some reason I haven't figured out yet I can't call the two rotate\r
83  * buttons "Rotate ACW" and "Rotate CW" (it causes MapEd to crash) so I've had\r
84  * to resort to calling them "Turn_L" and "Turn_R".\r
85  * - Ric\r
86  */\r
87 \r
88 #include <string.h>\r
89 #include <malloc.h>\r
90 \r
91 #include "config.h"\r
92 #include "guicomp.h"\r
93 #include "keyboard.h"\r
94 #include "maped.h"\r
95 #include "mouse.h"\r
96 #include "render.h"\r
97 #include "vdriver.h"\r
98 \r
99 #include "smalfont.h"\r
100 \r
101 #undef free\r
102 \r
103 #define TRUE  1\r
104 #define FALSE 0\r
105 // #define NULL ((void *)0)\r
106 \r
107 #define MOUSENONE    0    // No mouse buttons pressed\r
108 #define MOUSERELEASE 1    // Mouse button released\r
109 #define MOUSEPRESSED 2    // Mouse button held down\r
110 #define MOUSECLICKED 4    // Mouse button pressed\r
111 \r
112 // Setup some defines for the regions/areas/windows where everything goes\r
113 #define MAX_REGIONS 29    // Number of regions\r
114 #define BASEREG 0         // Window coords + title\r
115 #define HELPBAR 1         // Helpbar - put helpful messages here :)\r
116 #define PALETTE 2         // The palette\r
117 #define EDITREG 3         // Main edit window\r
118 #define PREVIEW 4         // Preview of image being edited\r
119 #define SCOLBOX 5         // Selected colour box\r
120 #define SCTXTBX 6         // Text box to show info on the selected colours\r
121 #define QUITBUT 7         // Quit button\r
122 #define DRAWBUT 8         // Draw mode indicator\r
123 #define FILLBUT 9         // Fill mode indicator\r
124 #define PICKBUT 10        // Pick mode indicator\r
125 #define MASKBUT 11        // Mask mode indicator\r
126 #define PSTEBUT 12        // Paste mode indicator\r
127 #define EDMDFRM 13        // Frame for edit mode radio buttons\r
128 #define MASKIND 14        // Indicator showing if mask is shown\r
129 #define GRIDIND 15        // Indicator showing if grid is shown\r
130 #define ANIMIND 16        // Indicator showing if animations are shown\r
131 #define PXHLIND 17        // Indicator showing if pixel highlight shown\r
132 #define IND_FRM 18        // Frame for indicators (push buttons)\r
133 #define BUT_FRM 19        // Frame for buttons\r
134 #define UNDOBUT 20        // Undo button\r
135 #define COPYBUT 21        // Copy button\r
136 #define CUT_BUT 22        // Cut button\r
137 #define CLR_BUT 23        // Clear button\r
138 #define TOOLFRM 24        // Frame for tools\r
139 #define FLIPBUT 25        // Flip image button\r
140 #define MIRRBUT 26        // Mirror image button\r
141 #define RIACBUT 27        // Rotate anticlockwise button\r
142 #define RIC_BUT 28        // Rotate clockwise button\r
143 \r
144 // Define TEbitflags values\r
145 #define TEQUITCUR 1\r
146 #define TEANIMATE 2\r
147 #define TEGRID    4\r
148 #define TEHILIGHT 8\r
149 #define TESHOWMSK 16\r
150 \r
151 // Define TEREGION->bitflags values\r
152 #define REGVISIBLE  1\r
153 #define REGACTIVE   2\r
154 #define REGNOCLICK  4\r
155 #define REGTWOCLICK 8          // wait for a second click\r
156 \r
157 // TEeditmode defs\r
158 #define EDDRAW  1\r
159 #define EDFILL  2\r
160 #define EDPICK  4\r
161 #define EDMASK  8\r
162 #define EDPASTE 16\r
163 \r
164 // TEtype defs\r
165 #define TEUNKNOWN 0\r
166 #define TETILE    1\r
167 \r
168 // DATABUTTON buttontypes:\r
169 #define CLICKBUTTON 1          // normal button\r
170 #define PUSHBUTTON  2          // can be pushed in/out (toggle bit bitvalue)\r
171 #define RADIOBUTTON 4          // for button banks (set *bitflag=bitvalue)\r
172 \r
173 // DATABASEREGION windowtypes:\r
174 #define DBRSTDWINDOW 0         // window and title bar\r
175 #define DBRPANEL     1         // no title bar\r
176 \r
177 // INFOTYPEs:\r
178 #define DITREGION     1\r
179 #define DITBASEREGION 2\r
180 #define DITBUTTON     4\r
181 #define DITEDITREG    8\r
182 \r
183 // Button flag action - has this button been clicked?\r
184 #define BFANONE   0\r
185 #define BFAUNDO   1\r
186 #define BFACOPY   2\r
187 #define BFACUT    4\r
188 #define BFACLEAR  8\r
189 #define BFARIAC   16\r
190 #define BFARIC    32\r
191 #define BFAMIRROR 64\r
192 #define BFAFLIP   128\r
193 \r
194 // Variables\r
195 typedef struct TEREGION\r
196   {\r
197   int infotype;                 // type of struct\r
198   unsigned int x1, x2, y1, y2;  // bounding coordinates\r
199   char *caption;                // helpbar text\r
200   int bitflags;                 // see defines above\r
201   void (*drawproc)(struct TEREGION *);  // region's draw procedure\r
202                                         // - allows nice and short RenderTileEdit proc ;)\r
203   void *data;        // extended information\r
204   } TEREGION;\r
205 typedef struct DATABASEREGION\r
206   {\r
207   int infotype;                 // type of struct\r
208   int numofregs;                // total number of regions (including base)\r
209   int windowtype;               // type of window to draw\r
210   } DATABASEREGION;\r
211 typedef struct DATABUTTON\r
212   {\r
213   int infotype;                 // type of struct\r
214   int *bitflag;                 // address of bitflag\r
215   char *text;                   // addition text (eg helptext)\r
216   int bitvalue;                 // 1st bit/value\r
217   int buttontype;               // type\r
218   } DATABUTTON;\r
219 typedef struct DATAEDITREG\r
220   {\r
221   int infotype;                 // type of struct\r
222   int firstx, firsty;           // first coords for two-click operation\r
223   } DATAEDITREG;\r
224 \r
225 \r
226 static TEREGION *TEregs=NULL;       // pointer to the regions\r
227 static unsigned char lcolor=255;    // left  mouse colour\r
228 static unsigned char rcolor=0;      // right mouse colour\r
229 static TEREGION *TEOldReg=NULL;\r
230 static unsigned int MBStatus[3]={MOUSENONE,MOUSENONE,MOUSENONE};\r
231 static int TEanimstrand=0;        // Animation strand\r
232 static int TEbitflags=TEANIMATE;  // Set default bitflags\r
233 static int TEbfa=BFANONE;         // Set default button action flags\r
234 static int TEeditmode=EDDRAW;     // Default edit region mode\r
235 static int TExoffs=16;            // X offset for region "windows"\r
236 static int TEyoffs=16;            // Y offset for region "windows"\r
237 unsigned int TEtype=TEUNKNOWN;    // type of graphic being edited\r
238 unsigned int TEtile; // tile to edit - may possibly expand this to an array for simultaneous editing\r
239 unsigned int TExsize=0;   // width of graphic being edited\r
240 unsigned int TEysize=0;   // height of graphic being edited\r
241 unsigned int TEcopyxsize=0;   // width of copy buffer\r
242 unsigned int TEcopyysize=0;   // height of copy buffer\r
243 unsigned char *TEsource=NULL; // pointer to original image being edited\r
244 static unsigned char *TEimage=NULL;  // pointer to image being edited\r
245 static unsigned char *TEmask=NULL;   // pointer to image mask\r
246 static unsigned char *TEundo=NULL;   // pointer to undo buffer\r
247 static unsigned char *TEcopy=NULL;   // pointer to copy buffer\r
248 static unsigned char *TEcmsk=NULL;   // pointer to copy mask\r
249 static char TEtempstr[256];          // Temporary string buffer\r
250 \r
251 // Function prototypes\r
252 static void *TEAlloc(unsigned long amount, char *whatfor);\r
253 \r
254 #define TEFree(ptr) if (ptr) free(ptr); ptr=NULL;\r
255 #define TEFreeReg(ptr) DestroyRegions(&ptr); if (ptr) free(ptr); ptr=NULL;\r
256 #define TENewText(text, whatfor) (char *) strcpy(TEAlloc(strlen(text)+1, whatfor), text);\r
257 //static void TEFree(void *TETmpBuf);\r
258 static void MBClickHandler(TEREGION *TEBaseReg);\r
259 static void AboutTE(void);\r
260 static void DestroyRegions(TEREGION **TEBaseReg);\r
261 static void SetupRegions(void);\r
262 static void InitTEImage(void);\r
263 static void DeinitTEImage(void);\r
264 static int  MouseOverTEreg(TEREGION *TEr);\r
265 static void RenderTileEdit(TEREGION *TEBaseReg);\r
266 static void RestartTileEditor(void);\r
267 static void SetCaption(TEREGION *TEr, char *helptext);\r
268 static void TEDrawHilight(int x1, int y1, int width, int height, unsigned char colour);\r
269 static void TEDrawCheckeredBox(int x1, int y1, int width, int height, unsigned char colour);\r
270 static void TERegFill(TEREGION *TEr, int colour);\r
271 static void TERegText(TEREGION *TEr, char *message);\r
272 static void TEClearImage(void);\r
273 static void TECopyImage(void);\r
274 static void TEFlipImage(unsigned char *TERILsrc, int TERILxsize, int TERILysize);\r
275 static void TEMirrorImage(unsigned char *TERILsrc, int TERILxsize, int TERILysize);\r
276 static void TERotateImageAntiClockwise(unsigned char *TERILsrc, int TERILxsize, int TERILysize);\r
277 static void TERotateImageClockwise(unsigned char *TERILsrc, int TERILxsize, int TERILysize);\r
278 static void TEFillImage(char *TEFIimage, char *TEFImask, int TEFIxsize, int TEFIysize, int TEFIx, int TEFIy, char TEFIcolour);\r
279 static void TERFillImage(char *TERFIimage, char *TERFImask, int TERFIxsize, int TERFIysize, int TERFIx, int TERFIy);\r
280 static void TEShiftColours(char *TESCimage, char *TESCmask, int TESCxsize, int TESCysize, int amount);\r
281 static void TEUndo(void);\r
282 static void DrawButton(TEREGION *TEr);\r
283 static void DrawEditReg(TEREGION *TEr);\r
284 static void DrawHelpBar(TEREGION *TEr);\r
285 static void DrawPalette(TEREGION *TEr);\r
286 static void DrawPreview(TEREGION *TEr);\r
287 static void DrawSColBox(TEREGION *TEr);\r
288 static void DrawSCTxtBx(TEREGION *TEr);\r
289 static void DrawSunkRegion(TEREGION *TEr);\r
290 void TileEdit(void);\r
291 \r
292 \r
293 static int MouseOverTEreg(TEREGION *TEr)\r
294   {\r
295   unsigned int testx=mx-TExoffs;\r
296   unsigned int testy=my-TEyoffs;\r
297   unsigned int width=(TEr->x2)-(TEr->x1);\r
298   unsigned int height=(TEr->y2)-(TEr->y1);\r
299   testx-=(TEr->x1);\r
300   testy-=(TEr->y1);\r
301 \r
302   if (testx >= width || testy >= height) return FALSE;\r
303   return TRUE;\r
304   }\r
305 \r
306 static void DrawButton(TEREGION *TEr)\r
307 // -- ric: 20/Jul/98 - generic button routine\r
308   {\r
309   unsigned int x=TEr->x1+TExoffs;\r
310   unsigned int y=TEr->y1+TEyoffs;\r
311   unsigned int width=(TEr->x2)-(TEr->x1);\r
312   unsigned int height=(TEr->y2)-(TEr->y1);\r
313 \r
314   strcpy(TEtempstr,"Button data not declared.");\r
315   if (!TEr->data)\r
316     err(TEtempstr);\r
317   if (((struct DATABUTTON *)(TEr->data))->infotype!=DITBUTTON)\r
318     err(TEtempstr);\r
319 \r
320   // draw raised button\r
321   stdwindow(x-1, y-1, x+width+1, y+height+1);\r
322   if (TEr->caption)\r
323     {\r
324     GotoXY(x+(width-(pixels(TEr->caption)))/2, y+(height-6)/2);\r
325     printstring(TEr->caption);\r
326     }\r
327   switch (((struct DATABUTTON *)(TEr->data))->buttontype)\r
328     {\r
329     case CLICKBUTTON:\r
330       if (MouseOverTEreg(TEr) && TEr->bitflags&REGACTIVE)\r
331         {\r
332         if (((struct DATABUTTON *)(TEr->data))->text)\r
333           SetCaption(&TEregs[HELPBAR], (((struct DATABUTTON *)(TEr->data))->text));\r
334 \r
335         // Handle mouse clicks\r
336         if (TEOldReg==TEr)\r
337           {\r
338           if ((MBStatus[0]|MBStatus[1])==MOUSEPRESSED)\r
339             {\r
340             // draw button down\r
341             FilledBox(x, y, width, height, winbg);\r
342             HLine(x, y, width, darkw);\r
343             VLine(x, y, height, darkw);\r
344             if (TEr->caption)\r
345               {\r
346               GotoXY(x+1+(width-(pixels(TEr->caption)))/2, y+1+(height-6)/2);\r
347               printstring(TEr->caption);\r
348               }\r
349             }\r
350           if ((MBStatus[0]|MBStatus[1])==MOUSERELEASE)\r
351             {\r
352             *(((struct DATABUTTON *)(TEr->data))->bitflag)^=((struct DATABUTTON *)(TEr->data))->bitvalue;\r
353             }\r
354           }\r
355         }\r
356       break;\r
357     case PUSHBUTTON:\r
358       if (*(((struct DATABUTTON *)(TEr->data))->bitflag)&(((struct DATABUTTON *)(TEr->data))->bitvalue))\r
359         {\r
360         // draw button down\r
361         FilledBox(x, y, width, height, winbg);\r
362         HLine(x, y, width, darkw);\r
363         VLine(x, y, height, darkw);\r
364         if (TEr->caption)\r
365           {\r
366           GotoXY(x+1+(width-(pixels(TEr->caption)))/2, y+1+(height-6)/2);\r
367           printstring(TEr->caption);\r
368           }\r
369         }\r
370       if (MouseOverTEreg(TEr) && TEr->bitflags&REGACTIVE)\r
371         {\r
372         if (((struct DATABUTTON *)(TEr->data))->text)\r
373           {\r
374           sprintf(TEtempstr, "Toggle %s on/off", ((struct DATABUTTON *)(TEr->data))->text);\r
375           SetCaption(&TEregs[HELPBAR], TEtempstr);\r
376           }\r
377 \r
378         // Handle mouse clicks\r
379         if (TEOldReg==TEr)\r
380           {\r
381           if ((MBStatus[0]|MBStatus[1])==MOUSECLICKED)\r
382             {\r
383             *(((struct DATABUTTON *)(TEr->data))->bitflag)^=((struct DATABUTTON *)(TEr->data))->bitvalue;\r
384             }\r
385           }\r
386         }\r
387       break;\r
388     case RADIOBUTTON:\r
389       if (*(((struct DATABUTTON *)(TEr->data))->bitflag)==((struct DATABUTTON *)(TEr->data))->bitvalue)\r
390         {\r
391         // draw button down\r
392         FilledBox(x, y, width, height, winbg);\r
393         HLine(x, y, width, darkw);\r
394         VLine(x, y, height, darkw);\r
395         if (TEr->caption)\r
396           {\r
397           GotoXY(x+1+(width-(pixels(TEr->caption)))/2, y+1+(height-6)/2);\r
398           printstring(TEr->caption);\r
399           }\r
400         }\r
401       if (MouseOverTEreg(TEr) && TEr->bitflags&REGACTIVE)\r
402         {\r
403         if (((struct DATABUTTON *)(TEr->data))->text)\r
404           SetCaption(&TEregs[HELPBAR], (((struct DATABUTTON *)(TEr->data))->text));\r
405 \r
406         // Handle mouse clicks\r
407         if (TEOldReg==TEr)\r
408           {\r
409           if ((MBStatus[0]|MBStatus[1])==MOUSECLICKED)\r
410             {\r
411             *(((struct DATABUTTON *)(TEr->data))->bitflag)=((struct DATABUTTON *)(TEr->data))->bitvalue;\r
412             }\r
413           }\r
414         }\r
415       break;\r
416     }\r
417   }\r
418 \r
419 static void DrawSunkRegion(TEREGION *TEr)\r
420   {\r
421   unsigned int x=TEr->x1+TExoffs;\r
422   unsigned int y=TEr->y1+TEyoffs;\r
423   unsigned int width=(TEr->x2)-(TEr->x1);\r
424   unsigned int height=(TEr->y2)-(TEr->y1);\r
425 \r
426 //  FilledBox(x, y, width, height, black);\r
427   HLine(x, y, width, darkw);\r
428   VLine(x, y, height, darkw);\r
429   HLine(x+1, y+height-1, width-1, brightw);\r
430   VLine(x+width-1, y+1, height-1, brightw);\r
431   }\r
432 \r
433 static void DrawEditReg(TEREGION *TEr)\r
434   {\r
435   int i,j,i2,j2,c;\r
436   int minx,miny,maxx,maxy;\r
437   int blocksize=8;\r
438   int visblocksize=blocksize;\r
439   char *img;\r
440   TEREGION tempr;\r
441   tempr.x1=TEr->x1+2;\r
442   tempr.x2=TEr->x2-2;\r
443   tempr.y1=TEr->y1+2;\r
444   tempr.y2=TEr->y2-2;\r
445 \r
446   img=TEimage; //vsp+(256*TEtile);\r
447 \r
448   TERegFill(TEr, black);\r
449   DrawSunkRegion(TEr);\r
450   FilledBox(TEr->x1+TExoffs+2, TEr->y1+TEyoffs+2, (blocksize<<4), (blocksize<<4), titlebg);\r
451 \r
452   if (TEbitflags&TEGRID) visblocksize-=1;\r
453 \r
454   for (j=0; j<TEysize; j++)\r
455     for (i=0; i<TExsize; i++)\r
456       {\r
457       FilledBox(TEr->x1+TExoffs+2+i*blocksize, TEr->y1+TEyoffs+2+j*blocksize, visblocksize, visblocksize, *img++);\r
458       if (TEbitflags&TESHOWMSK && !TEmask[j*TExsize+i])\r
459         TEDrawCheckeredBox(TEr->x1+TExoffs+2+i*blocksize, TEr->y1+TEyoffs+2+j*blocksize, visblocksize, visblocksize, titlebg);\r
460       }\r
461 \r
462   img=TEimage;\r
463   if (TEr->bitflags&REGACTIVE && !(MouseOverTEreg(&tempr)) && (MBStatus[0]|MBStatus[1])==MOUSERELEASE)\r
464     if (TEr->bitflags&REGTWOCLICK) TEr->bitflags^=REGTWOCLICK;\r
465   if (MouseOverTEreg(&tempr) && TEr->bitflags&REGACTIVE)\r
466     {\r
467     i=(mx-TExoffs-(tempr.x1))/blocksize;\r
468     j=(my-TEyoffs-(tempr.y1))/blocksize;\r
469     c=img[(j*TExsize)+i];\r
470     sprintf(TEtempstr, "Tile: %d, (%02d, %02d), Color: %03d (rgb: %03d/%03d/%03d)", TEtile, i, j, c, pal[(c*3)], pal[(c*3)+1], pal[(c*3)+2]);\r
471     SetCaption(&TEregs[HELPBAR], TEtempstr);\r
472     if (TEbitflags&TEHILIGHT)\r
473       TEDrawHilight(TExoffs+i*blocksize+tempr.x1, TEyoffs+j*blocksize+tempr.y1, visblocksize, visblocksize, white);\r
474 \r
475     // if pasting draw the image being pasted\r
476     if (TEeditmode==EDPASTE)\r
477       {\r
478       for (j2=0; j2<TEcopyysize; j2++)\r
479         if ((j+j2)<TEysize)\r
480           for (i2=0; i2<TEcopyxsize; i2++)\r
481             if ((i+i2)<TExsize)\r
482               if (TEcmsk[j2*TEcopyxsize+i2])\r
483                 if (!(TEbitflags&TESHOWMSK))\r
484                   FilledBox(TEr->x1+TExoffs+2+(i+i2)*blocksize, TEr->y1+TEyoffs+2+(j+j2)*blocksize, visblocksize, visblocksize, TEcopy[j2*TEcopyxsize+i2]);\r
485                 else\r
486                   if (TEmask[(j+j2)*TExsize+i+i2])\r
487                     FilledBox(TEr->x1+TExoffs+2+(i+i2)*blocksize, TEr->y1+TEyoffs+2+(j+j2)*blocksize, visblocksize, visblocksize, TEcopy[j2*TEcopyxsize+i2]);\r
488       }\r
489     if (TEeditmode==EDMASK)\r
490       {\r
491       // draw reg\r
492       if (TEr->bitflags&REGTWOCLICK)\r
493         for (j2=0; j2<TEysize; j2++)\r
494           for (i2=0; i2<TEysize; i2++)\r
495             if (((j2>=j && j2<=((struct DATAEDITREG *)(TEr->data))->firsty) ||\r
496                 (j2>=((struct DATAEDITREG *)(TEr->data))->firsty && j2<=j)) &&\r
497                 ((i2>=i && i2<=((struct DATAEDITREG *)(TEr->data))->firstx) ||\r
498                 (i2>=((struct DATAEDITREG *)(TEr->data))->firstx && i2<=i)))\r
499               TEDrawCheckeredBox(TEr->x1+TExoffs+2+i2*blocksize, TEr->y1+TEyoffs+2+j2*blocksize, visblocksize, visblocksize, darkred);\r
500 \r
501       if ((MBStatus[0]|MBStatus[1])==MOUSECLICKED && (key[SCAN_LSHIFT] || key[SCAN_RSHIFT]) && !(TEr->bitflags&REGTWOCLICK))\r
502         {\r
503         ((struct DATAEDITREG *)(TEr->data))->firstx=i;\r
504         ((struct DATAEDITREG *)(TEr->data))->firsty=j;\r
505         TEr->bitflags^=REGTWOCLICK;\r
506         }\r
507       if ((MBStatus[0]|MBStatus[1])==MOUSERELEASE && TEr->bitflags&REGTWOCLICK)\r
508         {\r
509         if (MBStatus[1]==MOUSERELEASE) c=0x0;\r
510         else c=0xf;\r
511         miny=j;\r
512         maxy=((struct DATAEDITREG *)(TEr->data))->firsty;\r
513         minx=i;\r
514         maxx=((struct DATAEDITREG *)(TEr->data))->firstx;\r
515         if (j>((struct DATAEDITREG *)(TEr->data))->firsty)\r
516           {\r
517           maxy=j;\r
518           miny=((struct DATAEDITREG *)(TEr->data))->firsty;\r
519           }\r
520         if (i>((struct DATAEDITREG *)(TEr->data))->firstx)\r
521           {\r
522           maxx=i;\r
523           minx=((struct DATAEDITREG *)(TEr->data))->firstx;\r
524           }\r
525         for (j2=miny; j2<=maxy; j2++)\r
526           for (i2=minx; i2<=maxx; i2++)\r
527             TEmask[j2*TExsize+i2]=(char)c;\r
528         TEr->bitflags^=REGTWOCLICK;\r
529         }\r
530       }\r
531     // Handle mouse clicks\r
532 \r
533 #ifdef JUNK\r
534     if ((MBStatus[0]|MBStatus[1])==MOUSECLICKED && (key[SCAN_CTRL]||key[SCAN_S]))\r
535       {\r
536       // put code to lock out draw mode here\r
537       }\r
538 #endif\r
539     if (TEOldReg==TEr)\r
540       {\r
541       // Update undo buffer\r
542       if ((MBStatus[0]|MBStatus[1])==MOUSECLICKED && TEeditmode!=EDMASK && TEeditmode!=EDPICK && !(key[SCAN_CTRL]||key[SCAN_S]))\r
543         memcpy(TEundo, TEimage, TExsize*TEysize);\r
544       if (MBStatus[0]==MOUSECLICKED && TEeditmode==EDFILL)\r
545         TEFillImage(TEimage, (TEbitflags&TESHOWMSK ? TEmask : NULL), TExsize, TEysize, i, j, lcolor);\r
546       if (MBStatus[1]==MOUSECLICKED && TEeditmode==EDFILL)\r
547         TEFillImage(TEimage, (TEbitflags&TESHOWMSK ? TEmask : NULL), TExsize, TEysize, i, j, rcolor);\r
548 \r
549       // Draw\r
550       if ((MBStatus[0]|MBStatus[1])==MOUSEPRESSED)\r
551         {\r
552         if (TEeditmode==EDPASTE)\r
553           {\r
554           for (j2=0; j2<TEcopyysize; j2++)\r
555             if ((j+j2)<TEysize)\r
556               for (i2=0; i2<TEcopyxsize; i2++)\r
557                 if ((i+i2)<TExsize)\r
558                   if (TEcmsk[j2*TEcopyxsize+i2])\r
559                     if (!(TEbitflags&TESHOWMSK))\r
560                       TEimage[(j+j2)*TExsize+i+i2]=TEcopy[j2*TEcopyxsize+i2];\r
561                     else\r
562                       if (TEmask[(j+j2)*TExsize+i+i2])\r
563                         TEimage[(j+j2)*TExsize+i+i2]=TEcopy[j2*TEcopyxsize+i2];\r
564           }\r
565         }\r
566       if (MBStatus[0]==MOUSEPRESSED)\r
567         if (key[SCAN_CTRL]||key[SCAN_S]||(TEeditmode==EDPICK))\r
568           lcolor=TEimage[(j*TExsize)+i];\r
569         else\r
570           if ((TEeditmode==EDDRAW)&&!(TEbitflags&TESHOWMSK && !TEmask[j*TExsize+i]))\r
571             TEimage[(j*TExsize)+i]=lcolor;\r
572           else\r
573             if (TEeditmode==EDMASK && !(TEr->bitflags&REGTWOCLICK))\r
574               TEmask[(j*TExsize)+i]=0xf;\r
575       if (MBStatus[1]==MOUSEPRESSED)\r
576         if (key[SCAN_CTRL]||key[SCAN_S]||(TEeditmode==EDPICK))\r
577           rcolor=TEimage[(j*TExsize)+i];\r
578         else\r
579           if ((TEeditmode==EDDRAW)&&!(TEbitflags&TESHOWMSK && !TEmask[j*TExsize+i]))\r
580             TEimage[(j*TExsize)+i]=rcolor;\r
581           else\r
582             if (TEeditmode==EDMASK && !(TEr->bitflags&REGTWOCLICK))\r
583               TEmask[(j*TExsize)+i]=0x0;\r
584       }\r
585     }\r
586   }\r
587 \r
588 static void DrawHelpBar(TEREGION *TEr)\r
589   {\r
590   //int i, htext=0;\r
591   TERegFill(TEr, black);\r
592   DrawSunkRegion(TEr);\r
593   if (TEr->caption) TERegText(TEr, TEr->caption);\r
594   TEFree(TEr->caption);               // Blank caption\r
595   //TEr->caption=NULL;                  // why doesn't this work in TEFree?\r
596 #ifdef JUNK\r
597   i=MAX_REGIONS;\r
598   do\r
599     {\r
600     i--;\r
601     if (MouseOverTEreg(&TEregs[i])) htext=i;\r
602     } while (i>0);\r
603   if (htext && TEregs[htext].helptext) TERegText(TEr, TEr->caption);\r
604 #endif\r
605   }\r
606 \r
607 static void DrawPalette(TEREGION *TEr)\r
608   {\r
609   int i,j;\r
610   unsigned int width=(TEr->x2)-(TEr->x1);\r
611   unsigned int height=(TEr->y2)-(TEr->y1);\r
612   int xscale=(width-4)>>6;\r
613   int yscale=(height-4)>>2;\r
614   int x=(TEr->x1)+TExoffs;\r
615   int y=(TEr->y1)+TEyoffs;\r
616   TEREGION tempr;\r
617   tempr.x1=TEr->x1+2;\r
618   tempr.x2=TEr->x2-2;\r
619   tempr.y1=TEr->y1+2;\r
620   tempr.y2=TEr->y2-2;\r
621 \r
622   x+=2;\r
623   y+=2;\r
624   TERegFill(TEr, black);\r
625   DrawSunkRegion(TEr);\r
626   i=64;\r
627   do\r
628     {\r
629     i--;\r
630     FilledBox(x+(i*xscale), y, xscale, yscale, i);\r
631     FilledBox(x+(i*xscale), y+yscale, xscale, yscale, i+64);\r
632     FilledBox(x+(i*xscale), y+yscale*2, xscale, yscale, i+128);\r
633     FilledBox(x+(i*xscale), y+yscale*3, xscale, yscale, i+192);\r
634     } while (i>0);\r
635 \r
636   i=lcolor&63;\r
637   j=lcolor>>6;\r
638   TEDrawHilight(x+i*xscale, y+j*yscale, xscale, yscale, titlebg);\r
639 \r
640   i=rcolor&63;\r
641   j=rcolor>>6;\r
642   TEDrawHilight(x+i*xscale, y+j*yscale, xscale, yscale, titlebg);\r
643 \r
644   if (MouseOverTEreg(&tempr) && TEr->bitflags&REGACTIVE)\r
645     {\r
646     i=(mx-TExoffs-(tempr.x1))/xscale;\r
647     j=(my-TExoffs-(tempr.y1))/yscale;\r
648     i+=(j<<6);\r
649     j=i*3;\r
650     sprintf(TEtempstr, "Color: %03d (rgb: %03d/%03d/%03d)", i, pal[j], pal[j+1], pal[j+2]);\r
651     SetCaption(&TEregs[HELPBAR], TEtempstr);\r
652     // Handle mouse clicks\r
653     if (TEOldReg==TEr)\r
654       {\r
655       if (MBStatus[0]==MOUSEPRESSED) lcolor=i;\r
656       if (MBStatus[1]==MOUSEPRESSED) rcolor=i;\r
657       }\r
658     }\r
659   }\r
660 \r
661 static void DrawPreview(TEREGION *TEr)\r
662   {\r
663   char *img;\r
664   int i;\r
665   TERegFill(TEr, black);\r
666   DrawSunkRegion(TEr);\r
667 //  img=vsp+(256*TEtile);\r
668   img=TEimage;\r
669   i=tileidx[TEtile];\r
670   if ((TEbitflags&TEANIMATE) && i!=TEtile) img=vsp+(256*i);\r
671   CopyTile(TEr->x1+TExoffs+2, TEr->y1+TEyoffs+2, img);\r
672 \r
673   if (MouseOverTEreg(TEr) && TEr->bitflags&REGACTIVE)\r
674     {\r
675     strcpy(TEtempstr, (TEbitflags&TEANIMATE ? "Click to halt animation" : "Click to animate tile"));\r
676     SetCaption(&TEregs[HELPBAR], TEtempstr);\r
677 \r
678     // Handle mouse clicks\r
679     if (TEOldReg==TEr)\r
680       if ((MBStatus[0]|MBStatus[1])==MOUSECLICKED && MouseOverTEreg(TEr))\r
681         TEbitflags^=TEANIMATE;\r
682     }\r
683   }\r
684 \r
685 static void DrawSColBox(TEREGION *TEr)\r
686 // -- ric: 15/Jul/98 - Draw selected colour box\r
687   {\r
688   int halfwidth=TEr->x2-TEr->x1-4;\r
689   int height=TEr->y2-TEr->y1-4;\r
690   char DSCBtempcolor;\r
691   TERegFill(TEr, black);\r
692   DrawSunkRegion(TEr);\r
693   FilledBox(TExoffs+2+TEr->x1, TEyoffs+2+TEr->y1, halfwidth, height, titlebg);\r
694   height-=2;\r
695   halfwidth-=2;\r
696   halfwidth>>=1;\r
697   FilledBox(TExoffs+3+TEr->x1, TEyoffs+3+TEr->y1, halfwidth, height, lcolor);\r
698   FilledBox(TExoffs+3+TEr->x1+halfwidth, TEyoffs+3+TEr->y1, halfwidth, height, rcolor);\r
699 \r
700   if (MouseOverTEreg(TEr) && TEr->bitflags&REGACTIVE)\r
701     {\r
702     strcpy(TEtempstr, "Click to swap colors");\r
703     SetCaption(&TEregs[HELPBAR], TEtempstr);\r
704 \r
705     // Handle mouse clicks\r
706     if (TEOldReg==TEr)\r
707     if ((MBStatus[0]|MBStatus[1])==MOUSECLICKED && MouseOverTEreg(TEr))\r
708       {\r
709       DSCBtempcolor=lcolor;\r
710       lcolor=rcolor;\r
711       rcolor=DSCBtempcolor;\r
712       }\r
713     }\r
714   }\r
715 \r
716 static void DrawSCTxtBx(TEREGION *TEr)\r
717 // -- ric: 15/Jul/98 - Draw selected colour text box\r
718   {\r
719 //  char DSCTBTextBuf[256];\r
720   int i;\r
721   int DSCTBx=TEr->x1+TExoffs+2;\r
722   int DSCTBy=TEr->y1+TEyoffs+2;\r
723   TERegFill(TEr, black);\r
724   DrawSunkRegion(TEr);\r
725   i=lcolor*3;\r
726   sprintf(TEtempstr, "Left: %03d (rgb: %03d/%03d/%03d)", lcolor, pal[i], pal[i+1], pal[i+2]);\r
727   GotoXY(DSCTBx, DSCTBy);\r
728   printstring(TEtempstr);\r
729   i=rcolor*3;\r
730   sprintf(TEtempstr, "Right: %03d (rgb: %03d/%03d/%03d)", rcolor, pal[i], pal[i+1], pal[i+2]);\r
731   GotoXY(DSCTBx, DSCTBy+7);\r
732   printstring(TEtempstr);\r
733   }\r
734 \r
735 static void SetCaption(TEREGION *TEr, char *helptext)\r
736   {\r
737   TEFree(TEr->caption);\r
738   TEr->caption=(char *)strcpy((char *)TEAlloc(strlen(helptext)+1,helptext), helptext);\r
739   }\r
740 \r
741 static void TEDrawHilight(int x1, int y1, int width, int height, unsigned char colour)\r
742 // -- ric: 15/Jul/98 - Draws hilight around given rectangle\r
743   {\r
744   VLine(x1-1, y1, height, colour);\r
745   VLine(x1+width, y1, height, colour);\r
746   HLine(x1-1, y1-1, width+2, colour);\r
747   HLine(x1-1, y1+height, width+2, colour);\r
748   }\r
749 \r
750 static void TEDrawCheckeredBox(int x1, int y1, int width, int height, unsigned char colour)\r
751 // -- ric: 17/Jul/98 - Draws a checkered box\r
752   {\r
753   int i,j;\r
754   unsigned char c;\r
755   for (j=0; j<height; j++)\r
756    {\r
757    c=(y1+j+1)&1;\r
758    if (c) c=colour;\r
759    for (i=0; i<width; i++)\r
760      {\r
761      if (c) screen[(y1+j)*tsx+x1+i]=c;\r
762      c^=colour;\r
763      }\r
764    }\r
765   }\r
766 \r
767 static void TERegFill(TEREGION *TEr, int colour)\r
768 // -- ric: 20/Jul/98 - Fills region with colour (colour==-1 for transparent)\r
769   {\r
770   if (colour>-1)\r
771     FilledBox(TEr->x1+TExoffs, TEr->y1+TEyoffs, (TEr->x2)-(TEr->x1), (TEr->y2)-(TEr->y1), colour);\r
772   }\r
773 \r
774 static void TERegText(TEREGION *TEr, char *message)\r
775 // Prints given message in the specified region\r
776   {\r
777   int tempx, tempy;\r
778   tempx=(TEr->x1)+TExoffs+2;\r
779 \r
780   tempy=(TEr->y2)-(TEr->y1);\r
781   tempy>>=1;\r
782   tempy+=(TEr->y1)-3;\r
783 \r
784   GotoXY(tempx,tempy+TEyoffs);\r
785   printstring(message);\r
786 \r
787   }\r
788 \r
789 static void TEClearImage(void)\r
790 // -- ric: 26/Jul/98 - clear selected image\r
791   {\r
792   int j;\r
793   if (TEbitflags&TESHOWMSK)\r
794     {\r
795     j=TEysize*TExsize;\r
796     memcpy(TEundo, TEimage, j); // backup image to undo buffer\r
797     do\r
798       {\r
799       j--;\r
800       if (*(TEmask+j)) *(TEimage+j)=rcolor;\r
801       } while (j>0);\r
802     }\r
803   }\r
804 \r
805 static void TECopyImage(void)\r
806 // -- ric: 26/Jul/98 - copy selected image to copy buffer\r
807   {\r
808   int i, j, TECIxstart, TECIystart, TECIxsize, TECIysize;\r
809   if (TEbitflags&TESHOWMSK)  // only makes sense if selected region is shown\r
810     {\r
811     TECIxstart=TExsize;\r
812     TECIystart=TEysize;\r
813     TECIxsize=-1;\r
814     TECIysize=-1;\r
815     // loop through image to find the starting and ending x and y coords\r
816     // of the image to copy\r
817     for (j=0; j<TEysize; j++)\r
818       for (i=0; i<TExsize; i++)\r
819         {\r
820         if (TEmask[j*TExsize+i])   // selected\r
821           {\r
822           if (i<TECIxstart) TECIxstart=i;\r
823           if (i>TECIxsize) TECIxsize=i;\r
824           if (j<TECIystart) TECIystart=j;\r
825           if (j>TECIysize) TECIysize=j;\r
826           }\r
827         }\r
828 \r
829     TECIxsize-=TECIxstart-1;\r
830     TECIysize-=TECIystart-1;\r
831 \r
832     if (TECIxsize>0 && TECIysize>0)\r
833       {\r
834       // free and create TEcopy and TEcmsk buffers\r
835       TEFree(TEcopy);\r
836       TEFree(TEcmsk);\r
837 \r
838       // make copy buffer square (allows for rotation)\r
839       TEcopyxsize=TECIysize;\r
840       TEcopyysize=TECIysize;\r
841       if (TECIxsize>TECIysize)\r
842         {\r
843         TEcopyxsize=TECIxsize;\r
844         TEcopyysize=TECIxsize;\r
845         }\r
846       TEcopy=(char *)TEAlloc(TEcopyxsize*TEcopyysize, "copy buffer");\r
847       TEcmsk=(char *)TEAlloc(TEcopyxsize*TEcopyysize, "copy mask");\r
848 \r
849       // copy image into buffer\r
850       for (j=0; j<TECIysize; j++)\r
851         for (i=0; i<TECIxsize; i++)\r
852           {\r
853           if (TEmask[(j+TECIystart)*TExsize+(i+TECIxstart)])\r
854             {\r
855             TEcopy[j*TEcopyxsize+i]=TEimage[(j+TECIystart)*TExsize+(i+TECIxstart)];\r
856             TEcmsk[j*TEcopyxsize+i]=0xf;\r
857             }\r
858           }\r
859       }\r
860     }\r
861   }\r
862 \r
863 static void TERotateImageAntiClockwise(unsigned char *TERILsrc, int TERILxsize, int TERILysize)\r
864 // -- ric: 15/Jul/98 - rotates image (must be square) 90 degrees anti-clockwise\r
865   {\r
866 //  unsigned char *TERILsrc=TEimage;\r
867   unsigned char *TERILimg=NULL;\r
868   int i, j, amount;\r
869   if (TERILxsize==TERILysize)\r
870     {\r
871     amount=TERILxsize*TERILysize;\r
872     TERILimg=(char *) TEAlloc(amount, "temporary image buffer for TERotateImageAntiClockwise");\r
873     memcpy(TERILimg, TERILsrc, amount);\r
874     j=TERILysize;\r
875     do\r
876       {\r
877       j--;\r
878       i=TERILxsize;\r
879       do\r
880         {\r
881         i--;\r
882         TERILsrc[(j*TERILxsize)+i]=TERILimg[(i*TERILxsize)+(TERILysize-1-j)];\r
883         } while (i>0);\r
884       } while (j>0);\r
885     TEFree(TERILimg);\r
886     }\r
887   }\r
888 \r
889 static void TERotateImageClockwise(unsigned char *TERILsrc, int TERILxsize, int TERILysize)\r
890 // -- ric: 16/Jul/98 - rotates image (must be square) 90 degrees clockwise\r
891   {\r
892   unsigned char *TERILimg=NULL;\r
893   int i, j, amount;\r
894   if (TERILxsize==TERILysize)\r
895     {\r
896     amount=TERILxsize*TERILysize;\r
897     TERILimg=(char *) TEAlloc(amount, "temporary image buffer for TERotateImageClockwise");\r
898     memcpy(TERILimg, TERILsrc, amount);\r
899     j=TERILysize;\r
900     do\r
901       {\r
902       j--;\r
903       i=TERILxsize;\r
904       do\r
905         {\r
906         i--;\r
907         TERILsrc[(j*TERILxsize)+i]=TERILimg[((TERILxsize-1-i)*TERILxsize)+(j)];\r
908         } while (i>0);\r
909       } while (j>0);\r
910     TEFree(TERILimg);\r
911     }\r
912   }\r
913 \r
914 static void TEFlipImage(unsigned char *TERILsrc, int TERILxsize, int TERILysize)\r
915 // -- ric: 15/Jul/98 - flips image\r
916   {\r
917   unsigned char *TERILimg=NULL;\r
918   int i, j, amount;\r
919   amount=TERILxsize*TERILysize;\r
920   TERILimg=(char *) TEAlloc(amount, "temporary image buffer for TEFlipImage");\r
921   memcpy(TERILimg, TERILsrc, amount);\r
922   j=TERILysize;\r
923   do\r
924     {\r
925     j--;\r
926     i=TERILxsize;\r
927     do\r
928       {\r
929       i--;\r
930       TERILsrc[(j*TERILxsize)+i]=TERILimg[((TERILysize-1-j)*TERILxsize)+i];\r
931       } while (i>0);\r
932     } while (j>0);\r
933   TEFree(TERILimg);\r
934   }\r
935 \r
936 static void TEMirrorImage(unsigned char *TERILsrc, int TERILxsize, int TERILysize)\r
937 // -- ric: 15/Jul/98 - mirrors image\r
938   {\r
939   unsigned char *TERILimg=NULL;\r
940   int i, j, amount;\r
941   amount=TERILxsize*TERILysize;\r
942   TERILimg=(char *) TEAlloc(amount, "temporary image buffer for TEMirrorImage");\r
943   memcpy(TERILimg, TERILsrc, amount);\r
944   j=TERILysize;\r
945   do\r
946     {\r
947     j--;\r
948     i=TERILxsize;\r
949     do\r
950       {\r
951       i--;\r
952       TERILsrc[(j*TERILxsize)+i]=TERILimg[(j*TERILxsize)+(TERILxsize-1-i)];\r
953       } while (i>0);\r
954     } while (j>0);\r
955   TEFree(TERILimg);\r
956   }\r
957 \r
958 static void TEFillImage(char *TEFIimage, char *TEFImask, int TEFIxsize, int TEFIysize, int TEFIx, int TEFIy, char TEFIcolour)\r
959 // -- ric: 29/Jul/98 - Fill procedure - sets up and calls recursive procedure below\r
960   {\r
961   int i,j;\r
962   unsigned char *TEFIfillmask=NULL;  // will eventually contain 0 for ignore and 1 for fill\r
963   TEFIfillmask=(char *) TEAlloc(TEFIxsize*TEFIysize, "temporary fill buffer for TEFillImage");\r
964   TERFillImage(TEFIimage, TEFIfillmask, TEFIxsize, TEFIysize, TEFIx, TEFIy);\r
965 \r
966   if (TEFImask)\r
967     for (j=0; j<TEFIysize; j++)\r
968       for (i=0; i<TEFIxsize; i++)\r
969         TEFIfillmask[j*TEFIxsize+i]&=TEFImask[j*TEFIxsize+i];\r
970 \r
971   for (j=0; j<TEFIysize; j++)\r
972     for (i=0; i<TEFIxsize; i++)\r
973       if (TEFIfillmask[j*TEFIxsize+i]) TEFIimage[j*TEFIxsize+i]=TEFIcolour;\r
974   TEFree(TEFIfillmask);\r
975   }\r
976 \r
977 static void TERFillImage(char *TERFIimage, char *TERFImask, int TERFIxsize, int TERFIysize, int TERFIx, int TERFIy)\r
978 // -- ric: 29/Jul/98 - Recursive fill procedure\r
979   {\r
980   int x,y;\r
981   char TERFIcc;\r
982   TERFImask[TERFIy*TERFIxsize+TERFIx]=0xf;\r
983   TERFIcc=TERFIimage[TERFIy*TERFIxsize+TERFIx];\r
984   x=TERFIx-1;\r
985   y=TERFIy;\r
986   if (x>=0 && x<TERFIxsize && y>=0 && y<TERFIysize)\r
987     if (!(TERFImask[y*TERFIxsize+x]) && TERFIimage[y*TERFIxsize+x]==TERFIcc)\r
988       TERFillImage(TERFIimage, TERFImask, TERFIxsize, TERFIysize, x, y);\r
989   x=TERFIx;\r
990   y=TERFIy-1;\r
991   if (x>=0 && x<TERFIxsize && y>=0 && y<TERFIysize)\r
992     if (!(TERFImask[y*TERFIxsize+x]) && TERFIimage[y*TERFIxsize+x]==TERFIcc)\r
993       TERFillImage(TERFIimage, TERFImask, TERFIxsize, TERFIysize, x, y);\r
994   x=TERFIx+1;\r
995   y=TERFIy;\r
996   if (x>=0 && x<TERFIxsize && y>=0 && y<TERFIysize)\r
997     if (!(TERFImask[y*TERFIxsize+x]) && TERFIimage[y*TERFIxsize+x]==TERFIcc)\r
998       TERFillImage(TERFIimage, TERFImask, TERFIxsize, TERFIysize, x, y);\r
999   x=TERFIx;\r
1000   y=TERFIy+1;\r
1001   if (x>=0 && x<TERFIxsize && y>=0 && y<TERFIysize)\r
1002     if (!(TERFImask[y*TERFIxsize+x]) && TERFIimage[y*TERFIxsize+x]==TERFIcc)\r
1003       TERFillImage(TERFIimage, TERFImask, TERFIxsize, TERFIysize, x, y);\r
1004   }\r
1005 \r
1006 static void TEShiftColours(char *TESCimage, char *TESCmask, int TESCxsize, int TESCysize, int amount)\r
1007 // -- ric: 17/Jul/98 - Colour shift idea by McGrue and Tarkuss\r
1008   {\r
1009   int i,j;\r
1010   j=TESCysize;\r
1011   do\r
1012     {\r
1013     j--;\r
1014     i=TESCxsize;\r
1015     do\r
1016       {\r
1017       i--;\r
1018       if (!(TESCmask))\r
1019         TESCimage[j*TESCxsize+i]+=amount;\r
1020       else\r
1021         if (TESCmask[j*TESCxsize+i])\r
1022           TESCimage[j*TESCxsize+i]+=amount;\r
1023       } while (i>0);\r
1024     } while (j>0);\r
1025   }\r
1026 \r
1027 \r
1028 static void TEUndo (void)\r
1029   {\r
1030   unsigned char *tempimg=TEimage;\r
1031   TEimage=TEundo;\r
1032   TEundo=tempimg;\r
1033   }\r
1034 \r
1035 static void *TEAlloc(unsigned long amount, char *whatfor)\r
1036 // -- ric: 14/Jul/98 - TE's custom, error-handling memory allocation routine\r
1037   {\r
1038   char *TETmpBuf=NULL;\r
1039 \r
1040   amount += 3; // aen\r
1041   amount &= ~3;\r
1042 \r
1043 //  static char DebugBuf[256];\r
1044   TETmpBuf=(char *) malloc(amount);\r
1045   if (!TETmpBuf)\r
1046     {\r
1047     sprintf(TEtempstr, "Unable to allocate %ld bytes for %s.", amount, whatfor);\r
1048     err(TEtempstr);\r
1049     }\r
1050   memset(TETmpBuf,0, amount); // Clear allocated mem\r
1051   /*\r
1052   __asm {  // aen\r
1053     mov edi,TETmpBuf\r
1054     mov ecx,amount\r
1055     shr ecx,2\r
1056     xor eax,eax\r
1057     cld\r
1058     rep stosd\r
1059     } ;\r
1060   */\r
1061   return TETmpBuf;\r
1062   }\r
1063 \r
1064 #ifdef JUNK\r
1065 static void TEFree(void *TETmpBuf)\r
1066 // -- ric: 14/Jul/98 - TE's custom memory freeing routine\r
1067   {\r
1068   if (TETmpBuf) free(TETmpBuf);  // Only free memory if previously allocated\r
1069   TETmpBuf=NULL;                 // Set freed memory to point to NULL\r
1070   }\r
1071 #endif\r
1072 \r
1073 static void MBClickHandler(TEREGION *TEBaseReg)\r
1074 // -- ric: 20/Jul/98 - Mouse button click handler\r
1075   {\r
1076   int i,j;\r
1077   ReadMouse();\r
1078   if (TEBaseReg)\r
1079     {\r
1080     if (!TEBaseReg->data) err("No region data defined.");\r
1081     if (((struct DATABASEREGION *)TEBaseReg->data)->infotype!=DITBASEREGION)\r
1082       err("MBClickHandler called with invalid base region.");\r
1083     }\r
1084 \r
1085   for (i=0; i<3; ++i)\r
1086     {\r
1087     if (mb & (i+1))\r
1088       {\r
1089       if (MBStatus[i] == MOUSECLICKED)\r
1090         MBStatus[i]=MOUSEPRESSED;\r
1091       else if (MBStatus[i] == MOUSENONE)\r
1092         {\r
1093         MBStatus[i] = MOUSECLICKED;\r
1094         if (TEBaseReg)\r
1095           {\r
1096           TEOldReg = NULL;\r
1097           for (j=0; j<((struct DATABASEREGION *)TEBaseReg->data)->numofregs; ++j)\r
1098             if (MouseOverTEreg(TEBaseReg+j)&&!((TEBaseReg+j)->bitflags&REGNOCLICK))\r
1099               TEOldReg = TEBaseReg+j;\r
1100           }\r
1101         }\r
1102       }\r
1103     else\r
1104       {\r
1105       if (MBStatus[i] <= MOUSERELEASE)\r
1106         MBStatus[i] = MOUSENONE;\r
1107       else if (MBStatus[i]>MOUSERELEASE)\r
1108         MBStatus[i] = MOUSERELEASE;\r
1109       }\r
1110     }\r
1111   }\r
1112 \r
1113 static void AboutTE (void)\r
1114 // Just here to test the mouse input loop - remove this later\r
1115   {\r
1116   TEREGION *TEr=NULL;\r
1117   TEREGION *TEaboutwin=NULL;\r
1118 //  int amxsize=150, amysize=82;\r
1119   int amxofs=60, amyofs=60;\r
1120   int i,i2,j,j2;\r
1121   int QuitAW=FALSE;\r
1122   int moving=FALSE;\r
1123 \r
1124   // Allocate memory\r
1125   TEaboutwin=(struct TEREGION *) TEAlloc((sizeof (struct TEREGION))*4,"about window regions");\r
1126   TEr=TEaboutwin;\r
1127   TEr->infotype=DITREGION;\r
1128   TEr->x1=amxofs;\r
1129   TEr->x2=TEr->x1+150;\r
1130   TEr->y1=amyofs;\r
1131   TEr->y2=TEr->y1+82;\r
1132   TEr->bitflags=REGACTIVE|REGVISIBLE|REGNOCLICK;\r
1133 //  TEr->drawproc=NULL;\r
1134   sprintf(strbuf, "About MapEd %s Tile Editor", ME2_VERSION);\r
1135   TEr->caption=TENewText(strbuf, "About window");\r
1136   TEr->data=(struct DATABASEREGION *) TEAlloc(sizeof (struct DATABASEREGION), "base region data");\r
1137   ((struct DATABASEREGION *)(TEr->data))->infotype=DITBASEREGION;\r
1138   ((struct DATABASEREGION *)(TEr->data))->numofregs=4;\r
1139   ((struct DATABASEREGION *)(TEr->data))->windowtype=DBRSTDWINDOW;\r
1140 \r
1141   TEr+=1;\r
1142   TEr->infotype=DITREGION;\r
1143   TEr->x1=0;\r
1144   TEr->x2=TEaboutwin->x2-TEaboutwin->x1-9;\r
1145   TEr->y1=0;\r
1146   TEr->y2=8;\r
1147   TEr->bitflags=REGACTIVE;\r
1148 //  TEr->drawproc=NULL;\r
1149 //  TEr->caption=NULL;\r
1150 \r
1151   TEr+=1;\r
1152   TEr->infotype=DITREGION;\r
1153   TEr->x1=TEaboutwin->x2-TEaboutwin->x1-9;\r
1154   TEr->x2=TEaboutwin->x2-TEaboutwin->x1-3;\r
1155   TEr->y1=3;\r
1156   TEr->y2=6;\r
1157   TEr->bitflags=REGACTIVE|REGVISIBLE;\r
1158   TEr->drawproc=&DrawButton;\r
1159 //  TEr->caption=NULL;\r
1160   TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "quit button data");\r
1161   ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON;\r
1162   ((struct DATABUTTON *)(TEr->data))->text=NULL;\r
1163   ((struct DATABUTTON *)(TEr->data))->buttontype=CLICKBUTTON;\r
1164   ((struct DATABUTTON *)(TEr->data))->bitflag=&QuitAW;\r
1165   ((struct DATABUTTON *)(TEr->data))->bitvalue=TRUE;\r
1166 \r
1167   TEr+=1;\r
1168   TEr->infotype=DITREGION;\r
1169   TEr->x1=60;\r
1170   TEr->x2=90;\r
1171   TEr->y1=62;\r
1172   TEr->y2=72;\r
1173   TEr->bitflags=REGACTIVE|REGVISIBLE;\r
1174   TEr->drawproc=&DrawButton;\r
1175   TEr->caption=TENewText("ok","ok button caption");\r
1176   TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "quit button data");\r
1177   ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON;\r
1178   ((struct DATABUTTON *)(TEr->data))->text=NULL;\r
1179   ((struct DATABUTTON *)(TEr->data))->buttontype=CLICKBUTTON;\r
1180   ((struct DATABUTTON *)(TEr->data))->bitflag=&QuitAW;\r
1181   ((struct DATABUTTON *)(TEr->data))->bitvalue=TRUE;\r
1182   TEr=TEaboutwin+1; // point to title bar area\r
1183 \r
1184   while (!QuitAW)\r
1185     {\r
1186     // Mouse button click handler routines\r
1187     MBClickHandler(TEaboutwin);\r
1188 \r
1189     amxofs=TEaboutwin->x1;\r
1190     amyofs=TEaboutwin->y1;\r
1191     if ((MBStatus[0]|MBStatus[1])==MOUSERELEASE)\r
1192       moving=FALSE;\r
1193 \r
1194     // Draw loop\r
1195     RenderTileEdit(TEregs);\r
1196     RenderTileEdit(TEaboutwin);\r
1197 \r
1198     sprintf(strbuf, "MapEd v.%s", ME2_VERSION);\r
1199     GotoXY(amxofs+52, amyofs+16); printstring(strbuf);\r
1200     GotoXY(amxofs+31, amyofs+22); printstring("Copyright (C) 1998 vecna");\r
1201     GotoXY(amxofs+40, amyofs+28); printstring("All Rights Reserved");\r
1202     sprintf(strbuf, "MapEd v.%s Tile Editor", ME2_VERSION);\r
1203     GotoXY(amxofs+29, amyofs+41); printstring(strbuf);\r
1204     GotoXY(amxofs+20, amyofs+47); printstring("Additional code by Richard Lau");\r
1205     DrawMouse();\r
1206     ShowPage();\r
1207 \r
1208     // Move window?\r
1209     if (MouseOverTEreg(TEr) && TEOldReg==TEr)\r
1210       {\r
1211       if ((MBStatus[0]|MBStatus[1])==MOUSECLICKED)\r
1212         {\r
1213         i2=TEaboutwin->x2-TEaboutwin->x1;\r
1214         j2=TEaboutwin->y2-TEaboutwin->y1;\r
1215         i=mx-TEaboutwin->x1;\r
1216         j=my-TEaboutwin->y1;\r
1217         moving=TRUE;\r
1218         }\r
1219       }\r
1220       if ((MBStatus[0]|MBStatus[1])==MOUSEPRESSED && moving)\r
1221         {\r
1222         if (((mx-i)<16)) TEaboutwin->x1=16;\r
1223         else if (((mx-i+i2)>=(16+sx))) TEaboutwin->x1=16+(sx-i2);\r
1224         else TEaboutwin->x1=mx-i;\r
1225         if (((my-j)<16)) TEaboutwin->y1=16;\r
1226         else if (((my-j+j2)>=(16+sy))) TEaboutwin->y1=16+(sy-j2);\r
1227         else TEaboutwin->y1=my-j;\r
1228         TEaboutwin->x2=TEaboutwin->x1+i2;\r
1229         TEaboutwin->y2=TEaboutwin->y1+j2;\r
1230         }\r
1231 \r
1232     if (key[SCAN_ESC])\r
1233       {\r
1234       key[SCAN_ESC]=0;\r
1235       QuitAW=TRUE;\r
1236       }\r
1237 \r
1238     }\r
1239   // free TEaboutwin\r
1240   TEFreeReg(TEaboutwin);\r
1241   }\r
1242 \r
1243 static void RestartTileEditor(void)\r
1244 // -- ric: 17/Jul/98 - reinit the tile editor\r
1245   {\r
1246   int i,j, amount;\r
1247   unsigned char *TERTEmask=NULL;\r
1248 \r
1249   switch (TEtype)\r
1250     {\r
1251     case TETILE:                 // edit tile TEtile\r
1252           i=TExsize;\r
1253           j=TEysize;\r
1254           amount=i*j;\r
1255           TERTEmask=(unsigned char *) TEAlloc(amount, "tile editor mask backup buffer");\r
1256 \r
1257           // backup mask\r
1258           memcpy(TERTEmask, TEmask, amount);\r
1259 \r
1260           // Restart editor\r
1261           DeinitTEImage();\r
1262           TEFreeReg(TEregs);\r
1263           TEtype=TETILE;\r
1264           TExsize=i;\r
1265           TEysize=j;\r
1266           TEsource=vsp+(256*TEtile);\r
1267           InitTEImage();\r
1268           SetupRegions();\r
1269 \r
1270           // Restore mask\r
1271           memcpy(TEmask, TERTEmask, amount);\r
1272           TEFree(TERTEmask);\r
1273           break;\r
1274     }\r
1275   }\r
1276 \r
1277 static void InitTEImage (void)\r
1278 // Copy the image data being edited and allocate memory for the image buffers\r
1279   {\r
1280   int i;\r
1281   int amount=TExsize*TEysize;\r
1282   if (TEtype==TEUNKNOWN) err("Unrecognised tile editor graphics type.");\r
1283   if (!TEsource) err("Invalid input image.");\r
1284   TEimage=(unsigned char *) TEAlloc(amount, "tile editor image buffer");\r
1285   TEmask=(unsigned char *) TEAlloc(amount, "tile editor mask buffer");\r
1286   TEundo=(unsigned char *) TEAlloc(amount, "tile editor undo buffer");\r
1287 //  if (!TEimage || !TEundo) err("Cannot allocate memory for tile editor image buffers.");\r
1288   memcpy(TEimage, TEsource, amount); // copy original image into edit buffer\r
1289   memcpy(TEundo, TEimage, amount);   // copy original image into undo buffer\r
1290 \r
1291   // if editing tile find the animation strand (if any) tile belongs to\r
1292   TEanimstrand=0;       // Does not belong to an animation strand\r
1293   if (TEtype==TETILE)\r
1294     {\r
1295     i=100;\r
1296     do\r
1297       {\r
1298       i--;\r
1299       if (vspanim[i].delay && TEtile<=vspanim[i].finish && TEtile>=vspanim[i].start)\r
1300         TEanimstrand=i+1;\r
1301       } while (i>0);\r
1302     }\r
1303   }\r
1304 \r
1305 static void DeinitTEImage(void)\r
1306 // Unallocate allocated image buffers - copy edited buffer into original\r
1307   {\r
1308   memcpy(TEsource, TEimage, (TExsize*TEysize));\r
1309   TEFree(TEimage);\r
1310   TEFree(TEmask);\r
1311   TEFree(TEundo);\r
1312   TEtype=TEUNKNOWN;         // Clear type info for error checking purposes\r
1313   TExsize=0;\r
1314   TEysize=0;\r
1315   }\r
1316 \r
1317 static void SetupRegions (void)\r
1318   {\r
1319   int temp;\r
1320   TEREGION *TEr=NULL;\r
1321 \r
1322   // Allocate memory\r
1323   TEregs=(struct TEREGION *) TEAlloc((sizeof (struct TEREGION))*MAX_REGIONS,"tile edit regions");\r
1324 \r
1325   TEr=TEregs+BASEREG;\r
1326   TEr->infotype=DITREGION;\r
1327   TEr->x1=16;\r
1328   TEr->x2=TEr->x1+sx;\r
1329   TEr->y1=16;\r
1330   TEr->y2=TEr->y1+sy;\r
1331   TEr->bitflags=REGACTIVE|REGVISIBLE|REGNOCLICK;\r
1332   TEr->drawproc=NULL;\r
1333   TEr->caption=NULL;\r
1334   switch (TEtype)\r
1335     {\r
1336     case TETILE:\r
1337       sprintf(TEtempstr, "MapEd %s Tile Editor - Tile: %d", ME2_VERSION, TEtile);\r
1338       if (TEanimstrand)\r
1339         sprintf(TEtempstr, "MapEd %s Tile Editor - Tile: %d (anim strand: %d, frame: %d/%d)",\r
1340           ME2_VERSION,\r
1341           TEtile, TEanimstrand-1, TEtile-vspanim[TEanimstrand-1].start+1,\r
1342           vspanim[TEanimstrand-1].finish-vspanim[TEanimstrand-1].start+1);\r
1343       SetCaption(TEr, TEtempstr);\r
1344       break;\r
1345     }\r
1346   TEr->data=(struct DATABASEREGION *) TEAlloc(sizeof (struct DATABASEREGION), "base region data");\r
1347   ((struct DATABASEREGION *)(TEr->data))->infotype=DITBASEREGION;\r
1348   ((struct DATABASEREGION *)(TEr->data))->numofregs=MAX_REGIONS;\r
1349   ((struct DATABASEREGION *)(TEr->data))->windowtype=DBRSTDWINDOW;\r
1350 \r
1351   TEr=TEregs+HELPBAR;\r
1352   TEr->infotype=DITREGION;\r
1353   TEr->x1=3;\r
1354   TEr->x2=TEregs->x2-TEregs->x1-3;\r
1355   TEr->y1=TEregs->y2-TEregs->y1-13;\r
1356   TEr->y2=TEregs->y2-TEregs->y1-3;\r
1357   TEr->bitflags=REGACTIVE|REGVISIBLE|REGNOCLICK;\r
1358   TEr->drawproc=&DrawHelpBar;\r
1359   TEr->caption=NULL;\r
1360   TEr->data=NULL;\r
1361 \r
1362   temp=(((TEregs->x2-TEregs->x1-8)>>6)<<5)+2;\r
1363   TEr=TEregs+PALETTE;\r
1364   TEr->infotype=DITREGION;\r
1365   TEr->x1=((TEregs->x2-TEregs->x1)>>1)-temp;\r
1366   TEr->x2=((TEregs->x2-TEregs->x1)>>1)+temp;\r
1367   TEr->y1=TEregs->y2-TEregs->y1-36;\r
1368   TEr->y2=TEregs->y2-TEregs->y1-16;\r
1369   TEr->bitflags=REGACTIVE|REGVISIBLE;\r
1370   TEr->drawproc=&DrawPalette;\r
1371   TEr->caption=NULL;\r
1372   TEr->data=NULL;\r
1373 \r
1374   TEr=TEregs+EDITREG;\r
1375   TEr->infotype=DITREGION;\r
1376   TEr->x1=3;\r
1377   TEr->x2=3+128+4;\r
1378   TEr->y1=10;\r
1379   TEr->y2=10+128+4;\r
1380   TEr->bitflags=REGACTIVE|REGVISIBLE;\r
1381   TEr->drawproc=&DrawEditReg;\r
1382   TEr->caption=NULL;\r
1383   TEr->data=(struct DATAEDITREG *) TEAlloc(sizeof (struct DATAEDITREG), "edit region data");\r
1384   ((struct DATAEDITREG *)(TEr->data))->infotype=DITEDITREG;\r
1385 \r
1386   TEr=TEregs+PREVIEW;\r
1387   TEr->infotype=DITREGION;\r
1388   TEr->x1=TEregs->x2-TEregs->x1-23;\r
1389   TEr->x2=TEregs->x2-TEregs->x1-3;\r
1390   TEr->y1=10;\r
1391   TEr->y2=10+20;\r
1392   TEr->bitflags=REGACTIVE|REGVISIBLE;\r
1393   TEr->drawproc=&DrawPreview;\r
1394   TEr->caption=NULL;\r
1395   TEr->data=NULL;\r
1396 \r
1397   TEr=TEregs+SCOLBOX;\r
1398   TEr->infotype=DITREGION;\r
1399   TEr->x1=TEregs[EDITREG].x1;\r
1400   TEr->x2=TEr->x1+20;\r
1401   TEr->y1=TEregs[EDITREG].y2+2;\r
1402   TEr->y2=TEr->y1+16;\r
1403   TEr->bitflags=REGACTIVE|REGVISIBLE;\r
1404   TEr->drawproc=&DrawSColBox;\r
1405   TEr->caption=NULL;\r
1406   TEr->data=NULL;\r
1407 \r
1408   TEr=TEregs+SCTXTBX;\r
1409   TEr->infotype=DITREGION;\r
1410   TEr->x1=TEregs[SCOLBOX].x2+2;\r
1411   TEr->x2=TEregs[EDITREG].x2;\r
1412   TEr->y1=TEregs[SCOLBOX].y1;\r
1413   TEr->y2=TEregs[SCOLBOX].y2;\r
1414   TEr->bitflags=REGACTIVE|REGVISIBLE|REGNOCLICK;\r
1415   TEr->drawproc=&DrawSCTxtBx;\r
1416   TEr->caption=NULL;\r
1417   TEr->data=NULL;\r
1418 \r
1419   TEr=TEregs+QUITBUT;\r
1420   TEr->infotype=DITREGION;\r
1421   TEr->x1=TEregs->x2-TEregs->x1-9;\r
1422   TEr->x2=TEregs->x2-TEregs->x1-3;\r
1423   TEr->y1=3;\r
1424   TEr->y2=6;\r
1425   TEr->bitflags=REGACTIVE|REGVISIBLE;\r
1426   TEr->drawproc=&DrawButton;\r
1427   TEr->caption=NULL;\r
1428   TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "quit button data");\r
1429   ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON;\r
1430   ((struct DATABUTTON *)(TEr->data))->text=TENewText("Exit", "quit button text");\r
1431   ((struct DATABUTTON *)(TEr->data))->buttontype=CLICKBUTTON;\r
1432   ((struct DATABUTTON *)(TEr->data))->bitflag=&TEbitflags;\r
1433   ((struct DATABUTTON *)(TEr->data))->bitvalue=TEQUITCUR;\r
1434 \r
1435   TEr=TEregs+EDMDFRM;\r
1436   TEr->infotype=DITREGION;\r
1437   TEr->x1=TEregs[EDITREG].x2+3;\r
1438   TEr->x2=TEr->x1+34;\r
1439   TEr->y1=TEregs[EDITREG].y1;\r
1440   TEr->y2=TEr->y1+11*5+3;     // 10*number of buttons\r
1441   TEr->bitflags=REGACTIVE|REGVISIBLE|REGNOCLICK;\r
1442   TEr->drawproc=&DrawSunkRegion;\r
1443   TEr->caption=NULL;\r
1444   TEr->data=NULL;\r
1445 \r
1446   TEr=TEregs+DRAWBUT;\r
1447   TEr->infotype=DITREGION;\r
1448   TEr->x1=TEregs[EDMDFRM].x1+2;\r
1449   TEr->x2=TEregs[EDMDFRM].x2-2;\r
1450   TEr->y1=TEregs[EDMDFRM].y1+2;\r
1451   TEr->y2=TEr->y1+10;\r
1452   TEr->bitflags=REGACTIVE|REGVISIBLE;\r
1453   TEr->drawproc=&DrawButton;\r
1454   TEr->caption=NULL;\r
1455   SetCaption(TEr,"Draw");\r
1456   TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "draw button data");\r
1457   ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON;\r
1458   ((struct DATABUTTON *)(TEr->data))->text=TENewText("Draw mode", "draw button text");\r
1459   ((struct DATABUTTON *)(TEr->data))->buttontype=RADIOBUTTON;\r
1460   ((struct DATABUTTON *)(TEr->data))->bitflag=&TEeditmode;\r
1461   ((struct DATABUTTON *)(TEr->data))->bitvalue=EDDRAW;\r
1462 \r
1463   TEr=TEregs+FILLBUT;\r
1464   TEr->infotype=DITREGION;\r
1465   TEr->x1=TEregs[EDMDFRM].x1+2;\r
1466   TEr->x2=TEregs[EDMDFRM].x2-2;\r
1467   TEr->y1=TEregs[EDMDFRM].y1+2+11;\r
1468   TEr->y2=TEr->y1+10;\r
1469   TEr->bitflags=REGACTIVE|REGVISIBLE;\r
1470   TEr->drawproc=&DrawButton;\r
1471   TEr->caption=NULL;\r
1472   SetCaption(TEr,"Fill");\r
1473   TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "fill button data");\r
1474   ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON;\r
1475   ((struct DATABUTTON *)(TEr->data))->text=TENewText("Fill mode", "fill button text");\r
1476   ((struct DATABUTTON *)(TEr->data))->buttontype=RADIOBUTTON;\r
1477   ((struct DATABUTTON *)(TEr->data))->bitflag=&TEeditmode;\r
1478   ((struct DATABUTTON *)(TEr->data))->bitvalue=EDFILL;\r
1479 \r
1480   TEr=TEregs+PICKBUT;\r
1481   TEr->infotype=DITREGION;\r
1482   TEr->x1=TEregs[EDMDFRM].x1+2;\r
1483   TEr->x2=TEregs[EDMDFRM].x2-2;\r
1484   TEr->y1=TEregs[EDMDFRM].y1+2+22;\r
1485   TEr->y2=TEr->y1+10;\r
1486   TEr->bitflags=REGACTIVE|REGVISIBLE;\r
1487   TEr->drawproc=&DrawButton;\r
1488   TEr->caption=NULL;\r
1489   SetCaption(TEr,"Pick");\r
1490   TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "pick button data");\r
1491   ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON;\r
1492   ((struct DATABUTTON *)(TEr->data))->text=TENewText("Pick color mode", "pick button text");\r
1493   ((struct DATABUTTON *)(TEr->data))->buttontype=RADIOBUTTON;\r
1494   ((struct DATABUTTON *)(TEr->data))->bitflag=&TEeditmode;\r
1495   ((struct DATABUTTON *)(TEr->data))->bitvalue=EDPICK;\r
1496 \r
1497   TEr=TEregs+MASKBUT;\r
1498   TEr->infotype=DITREGION;\r
1499   TEr->x1=TEregs[EDMDFRM].x1+2;\r
1500   TEr->x2=TEregs[EDMDFRM].x2-2;\r
1501   TEr->y1=TEregs[EDMDFRM].y1+2+33;\r
1502   TEr->y2=TEr->y1+10;\r
1503   TEr->bitflags=REGACTIVE|REGVISIBLE;\r
1504   TEr->drawproc=&DrawButton;\r
1505   TEr->caption=NULL;\r
1506   SetCaption(TEr,"Select");\r
1507   TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "select button data");\r
1508   ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON;\r
1509   ((struct DATABUTTON *)(TEr->data))->text=TENewText("Select mode", "select button text");\r
1510   ((struct DATABUTTON *)(TEr->data))->buttontype=RADIOBUTTON;\r
1511   ((struct DATABUTTON *)(TEr->data))->bitflag=&TEeditmode;\r
1512   ((struct DATABUTTON *)(TEr->data))->bitvalue=EDMASK;\r
1513 \r
1514   TEr=TEregs+PSTEBUT;\r
1515   TEr->infotype=DITREGION;\r
1516   TEr->x1=TEregs[EDMDFRM].x1+2;\r
1517   TEr->x2=TEregs[EDMDFRM].x2-2;\r
1518   TEr->y1=TEregs[EDMDFRM].y1+2+44;\r
1519   TEr->y2=TEr->y1+10;\r
1520   TEr->bitflags=REGACTIVE|REGVISIBLE;\r
1521   TEr->drawproc=&DrawButton;\r
1522   TEr->caption=NULL;\r
1523   SetCaption(TEr,"Paste");\r
1524   TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "paste button data");\r
1525   ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON;\r
1526   ((struct DATABUTTON *)(TEr->data))->text=TENewText("Paste mode", "paste button text");\r
1527   ((struct DATABUTTON *)(TEr->data))->buttontype=RADIOBUTTON;\r
1528   ((struct DATABUTTON *)(TEr->data))->bitflag=&TEeditmode;\r
1529   ((struct DATABUTTON *)(TEr->data))->bitvalue=EDPASTE;\r
1530 \r
1531   TEr=TEregs+IND_FRM;\r
1532   TEr->infotype=DITREGION;\r
1533   TEr->x1=TEregs[SCTXTBX].x2+2;\r
1534   TEr->x2=TEr->x1+12*4-1; // 10*number of buttons\r
1535   TEr->y1=TEregs[SCTXTBX].y1;\r
1536   TEr->y2=TEr->y1+13;\r
1537   TEr->bitflags=REGACTIVE|REGVISIBLE|REGNOCLICK;\r
1538   TEr->drawproc=&DrawSunkRegion;\r
1539   TEr->caption=NULL;\r
1540   TEr->data=NULL;\r
1541 \r
1542   TEr=TEregs+MASKIND;\r
1543   TEr->infotype=DITREGION;\r
1544   TEr->x1=TEregs[IND_FRM].x1+2;\r
1545   TEr->x2=TEr->x1+10;\r
1546   TEr->y1=TEregs[IND_FRM].y1+2;\r
1547   TEr->y2=TEregs[IND_FRM].y2-2;\r
1548   TEr->bitflags=REGACTIVE|REGVISIBLE;\r
1549   TEr->drawproc=&DrawButton;\r
1550   TEr->caption=NULL;\r
1551   SetCaption(TEr,"m");\r
1552   TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "mask indicator data");\r
1553   ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON;\r
1554   ((struct DATABUTTON *)(TEr->data))->text=TENewText("mask", "mask indicator text");\r
1555   ((struct DATABUTTON *)(TEr->data))->buttontype=PUSHBUTTON;\r
1556   ((struct DATABUTTON *)(TEr->data))->bitflag=&TEbitflags;\r
1557   ((struct DATABUTTON *)(TEr->data))->bitvalue=TESHOWMSK;\r
1558 \r
1559   TEr=TEregs+GRIDIND;\r
1560   TEr->infotype=DITREGION;\r
1561   TEr->x1=TEregs[MASKIND].x2+1;\r
1562   TEr->x2=TEr->x1+10;\r
1563   TEr->y1=TEregs[IND_FRM].y1+2;\r
1564   TEr->y2=TEregs[IND_FRM].y2-2;\r
1565   TEr->bitflags=REGACTIVE|REGVISIBLE;\r
1566   TEr->drawproc=&DrawButton;\r
1567   TEr->caption=NULL;\r
1568   SetCaption(TEr,"g");\r
1569   TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "grid button data");\r
1570   ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON;\r
1571   ((struct DATABUTTON *)(TEr->data))->text=TENewText("grid", "grid indicator text");\r
1572   ((struct DATABUTTON *)(TEr->data))->buttontype=PUSHBUTTON;\r
1573   ((struct DATABUTTON *)(TEr->data))->bitflag=&TEbitflags;\r
1574   ((struct DATABUTTON *)(TEr->data))->bitvalue=TEGRID;\r
1575 \r
1576   TEr=TEregs+ANIMIND;\r
1577   TEr->infotype=DITREGION;\r
1578   TEr->x1=TEregs[GRIDIND].x2+1;\r
1579   TEr->x2=TEr->x1+10;\r
1580   TEr->y1=TEregs[IND_FRM].y1+2;\r
1581   TEr->y2=TEregs[IND_FRM].y2-2;\r
1582   TEr->bitflags=REGACTIVE|REGVISIBLE;\r
1583   TEr->drawproc=&DrawButton;\r
1584   TEr->caption=NULL;\r
1585   SetCaption(TEr,"a");\r
1586   TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "animation button data");\r
1587   ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON;\r
1588   ((struct DATABUTTON *)(TEr->data))->text=TENewText("animation", "animation indicator text");\r
1589   ((struct DATABUTTON *)(TEr->data))->buttontype=PUSHBUTTON;\r
1590   ((struct DATABUTTON *)(TEr->data))->bitflag=&TEbitflags;\r
1591   ((struct DATABUTTON *)(TEr->data))->bitvalue=TEANIMATE;\r
1592 \r
1593   TEr=TEregs+PXHLIND;\r
1594   TEr->infotype=DITREGION;\r
1595   TEr->x1=TEregs[ANIMIND].x2+1;\r
1596   TEr->x2=TEr->x1+10;\r
1597   TEr->y1=TEregs[IND_FRM].y1+2;\r
1598   TEr->y2=TEregs[IND_FRM].y2-2;\r
1599   TEr->bitflags=REGACTIVE|REGVISIBLE;\r
1600   TEr->drawproc=&DrawButton;\r
1601   TEr->caption=NULL;\r
1602   SetCaption(TEr,"h");\r
1603   TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "highlight button data");\r
1604   ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON;\r
1605   ((struct DATABUTTON *)(TEr->data))->text=TENewText("pixel highlight", "highlight indicator text");\r
1606   ((struct DATABUTTON *)(TEr->data))->buttontype=PUSHBUTTON;\r
1607   ((struct DATABUTTON *)(TEr->data))->bitflag=&TEbitflags;\r
1608   ((struct DATABUTTON *)(TEr->data))->bitvalue=TEHILIGHT;\r
1609 \r
1610   TEr=TEregs+BUT_FRM;\r
1611   TEr->infotype=DITREGION;\r
1612   TEr->x1=TEregs[EDMDFRM].x1;\r
1613   TEr->x2=TEregs[EDMDFRM].x2;\r
1614   TEr->y1=TEregs[EDMDFRM].y2+2;\r
1615   TEr->y2=TEr->y1+11*4+3;     // 10*number of buttons\r
1616   TEr->bitflags=REGACTIVE|REGVISIBLE|REGNOCLICK;\r
1617   TEr->drawproc=&DrawSunkRegion;\r
1618   TEr->caption=NULL;\r
1619   TEr->data=NULL;\r
1620 \r
1621   TEr=TEregs+UNDOBUT;\r
1622   TEr->infotype=DITREGION;\r
1623   TEr->x1=TEregs[BUT_FRM].x1+2;\r
1624   TEr->x2=TEregs[BUT_FRM].x2-2;\r
1625   TEr->y1=TEregs[BUT_FRM].y1+2;\r
1626   TEr->y2=TEr->y1+10;\r
1627   TEr->bitflags=REGACTIVE|REGVISIBLE;\r
1628   TEr->drawproc=&DrawButton;\r
1629   TEr->caption=NULL;\r
1630   SetCaption(TEr, "Undo");\r
1631   TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "undo button data");\r
1632   ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON;\r
1633   ((struct DATABUTTON *)(TEr->data))->text=TENewText("Undo last action", "undo button text");\r
1634   ((struct DATABUTTON *)(TEr->data))->buttontype=CLICKBUTTON;\r
1635   ((struct DATABUTTON *)(TEr->data))->bitflag=&TEbfa;\r
1636   ((struct DATABUTTON *)(TEr->data))->bitvalue=BFAUNDO;\r
1637 \r
1638   TEr=TEregs+COPYBUT;\r
1639   TEr->infotype=DITREGION;\r
1640   TEr->x1=TEregs[BUT_FRM].x1+2;\r
1641   TEr->x2=TEregs[BUT_FRM].x2-2;\r
1642   TEr->y1=TEregs[BUT_FRM].y1+2+11;\r
1643   TEr->y2=TEr->y1+10;\r
1644   TEr->bitflags=REGACTIVE|REGVISIBLE;\r
1645   TEr->drawproc=&DrawButton;\r
1646   TEr->caption=NULL;\r
1647   SetCaption(TEr, "Copy");\r
1648   TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "copy button data");\r
1649   ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON;\r
1650   ((struct DATABUTTON *)(TEr->data))->text=TENewText("Copy selected area", "copy button text");\r
1651   ((struct DATABUTTON *)(TEr->data))->buttontype=CLICKBUTTON;\r
1652   ((struct DATABUTTON *)(TEr->data))->bitflag=&TEbfa;\r
1653   ((struct DATABUTTON *)(TEr->data))->bitvalue=BFACOPY;\r
1654 \r
1655   TEr=TEregs+CUT_BUT;\r
1656   TEr->infotype=DITREGION;\r
1657   TEr->x1=TEregs[BUT_FRM].x1+2;\r
1658   TEr->x2=TEregs[BUT_FRM].x2-2;\r
1659   TEr->y1=TEregs[BUT_FRM].y1+2+22;\r
1660   TEr->y2=TEr->y1+10;\r
1661   TEr->bitflags=REGACTIVE|REGVISIBLE;\r
1662   TEr->drawproc=&DrawButton;\r
1663   TEr->caption=NULL;\r
1664   SetCaption(TEr, "Cut");\r
1665   TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "cut button data");\r
1666   ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON;\r
1667   ((struct DATABUTTON *)(TEr->data))->text=TENewText("Cut selected area", "cut button text");\r
1668   ((struct DATABUTTON *)(TEr->data))->buttontype=CLICKBUTTON;\r
1669   ((struct DATABUTTON *)(TEr->data))->bitflag=&TEbfa;\r
1670   ((struct DATABUTTON *)(TEr->data))->bitvalue=BFACUT;\r
1671 \r
1672   TEr=TEregs+CLR_BUT;\r
1673   TEr->infotype=DITREGION;\r
1674   TEr->x1=TEregs[BUT_FRM].x1+2;\r
1675   TEr->x2=TEregs[BUT_FRM].x2-2;\r
1676   TEr->y1=TEregs[BUT_FRM].y1+2+33;\r
1677   TEr->y2=TEr->y1+10;\r
1678   TEr->bitflags=REGACTIVE|REGVISIBLE;\r
1679   TEr->drawproc=&DrawButton;\r
1680   TEr->caption=NULL;\r
1681   SetCaption(TEr, "Clear");\r
1682   TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "clear button data");\r
1683   ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON;\r
1684   ((struct DATABUTTON *)(TEr->data))->text=TENewText("Clear selected area", "clear button text");\r
1685   ((struct DATABUTTON *)(TEr->data))->buttontype=CLICKBUTTON;\r
1686   ((struct DATABUTTON *)(TEr->data))->bitflag=&TEbfa;\r
1687   ((struct DATABUTTON *)(TEr->data))->bitvalue=BFACLEAR;\r
1688 \r
1689   TEr=TEregs+TOOLFRM;\r
1690   TEr->infotype=DITREGION;\r
1691   TEr->x1=TEregs[BUT_FRM].x2+2;\r
1692   TEr->x2=TEr->x1+34;\r
1693   TEr->y1=TEregs[BUT_FRM].y1;\r
1694   TEr->y2=TEr->y1+11*4+3;     // 10*number of buttons\r
1695   TEr->bitflags=REGACTIVE|REGVISIBLE|REGNOCLICK;\r
1696   TEr->drawproc=&DrawSunkRegion;\r
1697   TEr->caption=NULL;\r
1698   TEr->data=NULL;\r
1699 \r
1700   TEr=TEregs+RIACBUT;\r
1701   TEr->infotype=DITREGION;\r
1702   TEr->x1=TEregs[TOOLFRM].x1+2;\r
1703   TEr->x2=TEregs[TOOLFRM].x2-2;\r
1704   TEr->y1=TEregs[TOOLFRM].y1+2;\r
1705   TEr->y2=TEr->y1+10;\r
1706   TEr->bitflags=REGACTIVE|REGVISIBLE;\r
1707   TEr->drawproc=&DrawButton;\r
1708   TEr->caption=NULL;\r
1709   SetCaption(TEr, "Turn L");\r
1710   TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "rotate button data");\r
1711   ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON;\r
1712   ((struct DATABUTTON *)(TEr->data))->text=TENewText("Rotate anticlockwise", "rotate button text");\r
1713   ((struct DATABUTTON *)(TEr->data))->buttontype=CLICKBUTTON;\r
1714   ((struct DATABUTTON *)(TEr->data))->bitflag=&TEbfa;\r
1715   ((struct DATABUTTON *)(TEr->data))->bitvalue=BFARIAC;\r
1716 \r
1717   TEr=TEregs+RIC_BUT;\r
1718   TEr->infotype=DITREGION;\r
1719   TEr->x1=TEregs[TOOLFRM].x1+2;\r
1720   TEr->x2=TEregs[TOOLFRM].x2-2;\r
1721   TEr->y1=TEregs[TOOLFRM].y1+2+11;\r
1722   TEr->y2=TEr->y1+10;\r
1723   TEr->bitflags=REGACTIVE|REGVISIBLE;\r
1724   TEr->drawproc=&DrawButton;\r
1725   TEr->caption=NULL;\r
1726   SetCaption(TEr, "Turn R");\r
1727   TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "rotate button data");\r
1728   ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON;\r
1729   ((struct DATABUTTON *)(TEr->data))->text=TENewText("Rotate clockwise", "rotate button text");\r
1730   ((struct DATABUTTON *)(TEr->data))->buttontype=CLICKBUTTON;\r
1731   ((struct DATABUTTON *)(TEr->data))->bitflag=&TEbfa;\r
1732   ((struct DATABUTTON *)(TEr->data))->bitvalue=BFARIC;\r
1733 \r
1734   TEr=TEregs+FLIPBUT;\r
1735   TEr->infotype=DITREGION;\r
1736   TEr->x1=TEregs[TOOLFRM].x1+2;\r
1737   TEr->x2=TEregs[TOOLFRM].x2-2;\r
1738   TEr->y1=TEregs[TOOLFRM].y1+2+22;\r
1739   TEr->y2=TEr->y1+10;\r
1740   TEr->bitflags=REGACTIVE|REGVISIBLE;\r
1741   TEr->drawproc=&DrawButton;\r
1742   TEr->caption=NULL;\r
1743   SetCaption(TEr, "Flip");\r
1744   TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "flip button data");\r
1745   ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON;\r
1746   ((struct DATABUTTON *)(TEr->data))->text=TENewText("Flip", "flip button text");\r
1747   ((struct DATABUTTON *)(TEr->data))->buttontype=CLICKBUTTON;\r
1748   ((struct DATABUTTON *)(TEr->data))->bitflag=&TEbfa;\r
1749   ((struct DATABUTTON *)(TEr->data))->bitvalue=BFAFLIP;\r
1750 \r
1751   TEr=TEregs+MIRRBUT;\r
1752   TEr->infotype=DITREGION;\r
1753   TEr->x1=TEregs[TOOLFRM].x1+2;\r
1754   TEr->x2=TEregs[TOOLFRM].x2-2;\r
1755   TEr->y1=TEregs[TOOLFRM].y1+2+33;\r
1756   TEr->y2=TEr->y1+10;\r
1757   TEr->bitflags=REGACTIVE|REGVISIBLE;\r
1758   TEr->drawproc=&DrawButton;\r
1759   TEr->caption=NULL;\r
1760   SetCaption(TEr, "Mirror");\r
1761   TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "mirror button data");\r
1762   ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON;\r
1763   ((struct DATABUTTON *)(TEr->data))->text=TENewText("Mirror", "mirror button text");\r
1764   ((struct DATABUTTON *)(TEr->data))->buttontype=CLICKBUTTON;\r
1765   ((struct DATABUTTON *)(TEr->data))->bitflag=&TEbfa;\r
1766   ((struct DATABUTTON *)(TEr->data))->bitvalue=BFAMIRROR;\r
1767 \r
1768   }\r
1769 \r
1770 static void DestroyRegions (TEREGION **TEBaseReg)\r
1771   {\r
1772   TEREGION *TEr=NULL;\r
1773   int i;\r
1774   if (!(*TEBaseReg)->data) err("No region data defined.");\r
1775   if (((struct DATABASEREGION *)(*TEBaseReg)->data)->infotype!=DITBASEREGION)\r
1776     err("DestroyRegions called with invalid base region.");\r
1777 \r
1778   i=((struct DATABASEREGION *)(*TEBaseReg)->data)->numofregs;\r
1779   do\r
1780     {\r
1781     i--;\r
1782     TEr=(*TEBaseReg)+i;\r
1783     TEFree(TEr->caption);\r
1784     if (TEr->data)\r
1785       {\r
1786       switch (((struct DATABASEREGION *)(TEr->data))->infotype)\r
1787         {\r
1788         case DITBASEREGION:\r
1789           break;\r
1790         case DITBUTTON:\r
1791           TEFree(((struct DATABUTTON *)TEr->data)->text);\r
1792           break;\r
1793         }\r
1794       }\r
1795     TEFree(TEr->data);\r
1796     } while (i>0);\r
1797   TEFree(*TEBaseReg);\r
1798 //  if (*TEBaseReg) err("Not freed");\r
1799   }\r
1800 \r
1801 static void RenderTileEdit (TEREGION *TEBaseReg)\r
1802 // -- ric: 20/Jul/98 - updatedt to be a little more generic ;)\r
1803   {\r
1804   int i;\r
1805   TExoffs=TEBaseReg->x1;\r
1806   TEyoffs=TEBaseReg->y1;\r
1807   if (!TEBaseReg->data) err("No region data defined.");\r
1808   if (((struct DATABASEREGION *)TEBaseReg->data)->infotype!=DITBASEREGION)\r
1809     err("RenderTileEdit called with invalid base region.");\r
1810   switch (((struct DATABASEREGION *)TEBaseReg->data)->windowtype)\r
1811     {\r
1812     case DBRSTDWINDOW:\r
1813       Window(TExoffs,TEyoffs,TEBaseReg->x2,TEBaseReg->y2, ((TEBaseReg->caption) ? TEBaseReg->caption : ""));\r
1814       break;\r
1815     case DBRPANEL:\r
1816       stdwindow(TExoffs,TEyoffs,TEBaseReg->x2,TEBaseReg->y2);\r
1817       break;\r
1818     }\r
1819 \r
1820   i=((struct DATABASEREGION *)TEBaseReg->data)->numofregs;\r
1821   do\r
1822     {\r
1823     i--;\r
1824     if ((TEBaseReg+i)->bitflags&REGVISIBLE) (TEBaseReg+i)->drawproc(TEBaseReg+i);\r
1825     } while (i>1);\r
1826   }\r
1827 \r
1828 void TileEdit (void)\r
1829   {\r
1830   int i,j;\r
1831   int TEoldeditmode=EDDRAW;\r
1832   if (TEbitflags&TEQUITCUR) TEbitflags^=TEQUITCUR;\r
1833 \r
1834   InitTEImage();\r
1835   SetupRegions();\r
1836   TEeditmode=EDDRAW;  // Default to drawing mode\r
1837   if (TEbitflags&TESHOWMSK) TEbitflags^=TESHOWMSK;\r
1838 \r
1839   while (!(TEbitflags&TEQUITCUR))\r
1840     {\r
1841     // Mouse button click handler routines\r
1842     MBClickHandler(TEregs);\r
1843 \r
1844     TEbfa=BFANONE;          // Reset button action flag\r
1845     if (TEeditmode==EDMASK && TEoldeditmode!=EDMASK) TEbitflags|=TESHOWMSK;\r
1846     if (TEeditmode==EDMASK && TEoldeditmode==EDMASK && !(TEbitflags&TESHOWMSK))\r
1847       TEeditmode=EDDRAW;\r
1848     TEoldeditmode=TEeditmode;\r
1849 \r
1850     // Draw loop\r
1851     RenderTileEdit(TEregs);\r
1852     DrawMouse();\r
1853     ShowPage();\r
1854 \r
1855     if (key[SCAN_ESC])\r
1856       {\r
1857       key[SCAN_ESC]=0;\r
1858       TEbitflags|=TEQUITCUR;\r
1859       }\r
1860     if ((key[SCAN_CTRL] && key[SCAN_Z]) || (TEbfa&BFAUNDO) || (key[SCAN_U] && !(key[SCAN_CTRL])) && ((MBStatus[0]|MBStatus[1])==MOUSENONE))\r
1861       {\r
1862       key[SCAN_U]=0;\r
1863       key[SCAN_Z]=0;\r
1864       TEUndo();\r
1865       }\r
1866     if (key[SCAN_CTRL] && key[SCAN_R])\r
1867       {\r
1868       key[SCAN_R]=0;\r
1869       memcpy(TEundo, TEimage, TExsize*TEysize);   // copy image into undo buffer\r
1870       memcpy(TEimage, TEsource, TExsize*TEysize); // copy original image into edit buffer\r
1871       }\r
1872     if (key[SCAN_CTRL] && key[SCAN_A])\r
1873       {\r
1874       key[SCAN_A]=0;\r
1875       j=TEysize*TExsize;\r
1876       memset(TEmask, 0xf, j);\r
1877       }\r
1878     if (key[SCAN_CTRL] && key[SCAN_U])\r
1879       {\r
1880       key[SCAN_U]=0;\r
1881       j=TEysize*TExsize;\r
1882       memset(TEmask, 0x0, j);\r
1883       }\r
1884     if ((TEbfa&BFACOPY) || (key[SCAN_CTRL] && key[SCAN_C]) && ((MBStatus[0]|MBStatus[1])==MOUSENONE))\r
1885       {\r
1886       key[SCAN_C]=0;\r
1887       TECopyImage();\r
1888       }\r
1889     if ((TEbfa&BFACUT) || (key[SCAN_CTRL] && key[SCAN_X]) && ((MBStatus[0]|MBStatus[1])==MOUSENONE))\r
1890       {\r
1891       key[SCAN_X]=0;\r
1892       TECopyImage();\r
1893       TEClearImage();\r
1894       }\r
1895     if (key[SCAN_CTRL] && key[SCAN_V] && ((MBStatus[0]|MBStatus[1])==MOUSENONE))\r
1896       {\r
1897       key[SCAN_V]=0;\r
1898       TEeditmode=EDPASTE;\r
1899       }\r
1900     if ((TEbfa&BFACLEAR) || key[SCAN_DEL] && ((MBStatus[0]|MBStatus[1])==MOUSENONE))\r
1901       {\r
1902       key[SCAN_DEL]=0;\r
1903       TEClearImage();\r
1904       }\r
1905     if (key[SCAN_Q] && ((MBStatus[0]|MBStatus[1])==MOUSENONE))\r
1906       {\r
1907       key[SCAN_Q]=0;\r
1908       if (TEtype==TETILE && TEanimstrand)\r
1909         {\r
1910         if (TEtile>vspanim[TEanimstrand-1].start)\r
1911           {\r
1912           // Change tile index\r
1913           TEtile-=1;\r
1914           i=TExsize;\r
1915           j=TEysize;\r
1916 \r
1917           // Restart editor\r
1918           RestartTileEditor();\r
1919           }\r
1920         }\r
1921       }\r
1922     if (key[SCAN_W] && ((MBStatus[0]|MBStatus[1])==MOUSENONE))\r
1923       {\r
1924       key[SCAN_W]=0;\r
1925       if (TEtype==TETILE && TEanimstrand)\r
1926         {\r
1927         if (TEtile<vspanim[TEanimstrand-1].finish)\r
1928           {\r
1929           // Change tile index\r
1930           TEtile+=1;\r
1931           i=TExsize;\r
1932           j=TEysize;\r
1933 \r
1934           // Restart editor\r
1935           RestartTileEditor();\r
1936           }\r
1937         }\r
1938       }\r
1939 \r
1940     if ((TEbfa&BFARIAC) || key[SCAN_L] && ((MBStatus[0]|MBStatus[1])==MOUSENONE))\r
1941       {\r
1942       key[SCAN_L]=0;\r
1943       switch (TEeditmode)\r
1944         {\r
1945         case EDDRAW:\r
1946           memcpy(TEundo, TEimage, TExsize*TEysize);\r
1947           TERotateImageAntiClockwise(TEimage, TExsize, TEysize);\r
1948           break;\r
1949         case EDMASK:\r
1950           TERotateImageAntiClockwise(TEmask, TExsize, TEysize);\r
1951           break;\r
1952         case EDPASTE:\r
1953           if (TEcopy)\r
1954             {\r
1955             TERotateImageAntiClockwise(TEcopy, TEcopyxsize, TEcopyysize);\r
1956             TERotateImageAntiClockwise(TEcmsk, TEcopyxsize, TEcopyysize);\r
1957             }\r
1958           break;\r
1959         }\r
1960       }\r
1961     if ((TEbfa&BFARIC) || key[SCAN_R] && ((MBStatus[0]|MBStatus[1])==MOUSENONE))\r
1962       {\r
1963       key[SCAN_R]=0;\r
1964       switch (TEeditmode)\r
1965         {\r
1966         case EDDRAW:\r
1967           memcpy(TEundo, TEimage, TExsize*TEysize);\r
1968           TERotateImageClockwise(TEimage, TExsize, TEysize);\r
1969           break;\r
1970         case EDMASK:\r
1971           TERotateImageClockwise(TEmask, TExsize, TEysize);\r
1972           break;\r
1973         case EDPASTE:\r
1974           if (TEcopy)\r
1975             {\r
1976             TERotateImageClockwise(TEcopy, TEcopyxsize, TEcopyysize);\r
1977             TERotateImageClockwise(TEcmsk, TEcopyxsize, TEcopyysize);\r
1978             }\r
1979           break;\r
1980         }\r
1981       }\r
1982     if ((TEbfa&BFAMIRROR) || key[SCAN_X] && ((MBStatus[0]|MBStatus[1])==MOUSENONE))\r
1983       {\r
1984       key[SCAN_X]=0;\r
1985       switch (TEeditmode)\r
1986         {\r
1987         case EDDRAW:\r
1988           memcpy(TEundo, TEimage, TExsize*TEysize);\r
1989           TEMirrorImage(TEimage, TExsize, TEysize);\r
1990           break;\r
1991         case EDMASK:\r
1992           TEMirrorImage(TEmask, TExsize, TEysize);\r
1993           break;\r
1994         case EDPASTE:\r
1995           if (TEcopy)\r
1996             {\r
1997             TEMirrorImage(TEcopy, TEcopyxsize, TEcopyysize);\r
1998             TEMirrorImage(TEcmsk, TEcopyxsize, TEcopyysize);\r
1999             }\r
2000           break;\r
2001         }\r
2002       }\r
2003     if ((TEbfa&BFAFLIP) || key[SCAN_Y] && ((MBStatus[0]|MBStatus[1])==MOUSENONE))\r
2004       {\r
2005       key[SCAN_Y]=0;\r
2006       switch (TEeditmode)\r
2007         {\r
2008         case EDDRAW:\r
2009           memcpy(TEundo, TEimage, TExsize*TEysize);\r
2010           TEFlipImage(TEimage, TExsize, TEysize);\r
2011           break;\r
2012         case EDMASK:\r
2013           TEFlipImage(TEmask, TExsize, TEysize);\r
2014           break;\r
2015         case EDPASTE:\r
2016           if (TEcopy)\r
2017             {\r
2018             TEFlipImage(TEcopy, TEcopyxsize, TEcopyysize);\r
2019             TEFlipImage(TEcmsk, TEcopyxsize, TEcopyysize);\r
2020             }\r
2021           break;\r
2022         }\r
2023       }\r
2024     if (key[SCAN_F1])\r
2025       {\r
2026       key[SCAN_F1]=0;\r
2027 \r
2028       // Deacitvate tile editor\r
2029       for (i=0; i<MAX_REGIONS; i++)\r
2030         if (TEregs[i].bitflags&REGACTIVE) TEregs[i].bitflags^=REGACTIVE;\r
2031 \r
2032       AboutTE();\r
2033 \r
2034       // Reacitvate tile editor\r
2035       for (i=0; i<MAX_REGIONS; i++)\r
2036         TEregs[i].bitflags|=REGACTIVE;\r
2037       }\r
2038     if (key[SCAN_A])\r
2039       {\r
2040       key[SCAN_A]=0;\r
2041       lcolor+=1;\r
2042       lcolor&=255;\r
2043       }\r
2044     if (key[SCAN_D])\r
2045       {\r
2046       key[SCAN_D]=0;\r
2047       rcolor+=1;\r
2048       rcolor&=255;\r
2049       }\r
2050     if (key[SCAN_Z])\r
2051       {\r
2052       key[SCAN_Z]=0;\r
2053       if (!lcolor) lcolor=255;\r
2054       else lcolor-=1;\r
2055       }\r
2056     if (key[SCAN_C])\r
2057       {\r
2058       key[SCAN_C]=0;\r
2059       if (!rcolor) rcolor=255;\r
2060       else rcolor-=1;\r
2061       }\r
2062     if (key[SCAN_G])\r
2063       {\r
2064       key[SCAN_G]=0;\r
2065       TEbitflags^=TEGRID;\r
2066       }\r
2067     if (key[SCAN_H])\r
2068       {\r
2069       key[SCAN_H]=0;\r
2070       TEbitflags^=TEHILIGHT;\r
2071       }\r
2072     if (key[SCAN_I])\r
2073       {\r
2074       key[SCAN_I]=0;\r
2075       j=TEysize*TExsize;\r
2076       do\r
2077         {\r
2078         j--;\r
2079         TEmask[j]^=0xf;\r
2080         } while (j>0);\r
2081       }\r
2082     if (key[SCAN_M])\r
2083       {\r
2084       key[SCAN_M]=0;\r
2085       if (TEeditmode==EDMASK)\r
2086         TEeditmode=EDDRAW;\r
2087       TEbitflags^=TESHOWMSK;\r
2088       }\r
2089     if (key[SCAN_SPACE])\r
2090       {\r
2091       key[SCAN_SPACE]=0;\r
2092       if (TEeditmode==EDDRAW)\r
2093         {\r
2094         TEeditmode=EDMASK;\r
2095         TEbitflags|=TESHOWMSK;\r
2096         }\r
2097       else\r
2098         TEeditmode=EDDRAW;\r
2099       }\r
2100     if (key[SCAN_PGUP])\r
2101       {\r
2102       key[SCAN_PGUP]=0;\r
2103       switch (TEeditmode)\r
2104         {\r
2105         case EDDRAW:\r
2106         case EDMASK:\r
2107           memcpy(TEundo, TEimage, TExsize*TEysize);\r
2108           if (TEbitflags&TESHOWMSK)\r
2109             TEShiftColours(TEimage, TEmask, TExsize, TEysize, 1);\r
2110           else\r
2111             TEShiftColours(TEimage, NULL, TExsize, TEysize, 1);\r
2112           break;\r
2113         case EDPASTE:\r
2114           if (TEcopy)\r
2115             TEShiftColours(TEcopy, TEcmsk, TEcopyxsize, TEcopyysize, 1);\r
2116           break;\r
2117         }\r
2118       }\r
2119     if (key[SCAN_PGDN])\r
2120       {\r
2121       key[SCAN_PGDN]=0;\r
2122       switch (TEeditmode)\r
2123         {\r
2124         case EDDRAW:\r
2125         case EDMASK:\r
2126           memcpy(TEundo, TEimage, TExsize*TEysize);\r
2127           if (TEbitflags&TESHOWMSK)\r
2128             TEShiftColours(TEimage, TEmask, TExsize, TEysize, -1);\r
2129           else\r
2130             TEShiftColours(TEimage, NULL, TExsize, TEysize, -1);\r
2131           break;\r
2132         case EDPASTE:\r
2133           if (TEcopy)\r
2134             TEShiftColours(TEcopy, TEcmsk, TEcopyxsize, TEcopyysize, -1);\r
2135           break;\r
2136         }\r
2137       }\r
2138 \r
2139     if (key[SCAN_LANGLE])\r
2140       {\r
2141       key[SCAN_LANGLE]=0;\r
2142       ShutdownVideo();\r
2143       TEFreeReg(TEregs);\r
2144       vm=0;\r
2145       InitVideo(0);\r
2146       SetupRegions();\r
2147       set_intensity(63);\r
2148       InitMouse();\r
2149       }\r
2150     if (key[SCAN_RANGLE])\r
2151       {\r
2152       key[SCAN_RANGLE]=0;\r
2153       ShutdownVideo();\r
2154       TEFreeReg(TEregs);\r
2155       vm=1;\r
2156       InitVideo(1);\r
2157       SetupRegions();\r
2158       set_intensity(63);\r
2159       InitMouse();\r
2160       }\r
2161     }\r
2162   DeinitTEImage();\r
2163   TEFreeReg(TEregs);\r
2164   }\r