/* Copyright (C) 1998 BJ Eirich (aka vecna) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public Lic See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // Additional code by Richard Lau (aka Ric) /* Date started: 08/Jul/98 */ /* -- 29/Jul/98 -- * Heh, I've actually done quite a lot of work on this even though I intend * to replace it. Oh well :) * * I've now made clicking on the mask indicator button (labelled with a small * "m") drop back to draw mode if you're in select mode (since it makes no * sense to select an area with the mask turned off). Holding down shift * and dragging the mouse when you're in select mode will allow you to select * a rectangle. The PgUp/PgDn colour shifters will now work in paste mode * (affecting the image in the copy buffer). * * The fill routine is now in place and I've put a button in for the pick * colour/eyedropper tool so that I don't get asked to put in a function for * like I continuously did with ACE. Due to the extra buttons I've had to * shift some of the other buttons around to make them all fit onto the * screen. It's probably not the best arrangement but if anyone comes up with * a better layout I'm open to suggestions. * * The wierd button labelling problem I had last time has been corrected - the * problem was traced back to the pixels routine in SMALFONT.C. Aen pointed * out that I wasn't allocating space for the NULL terminator for all the * strings so that has now been fixed (by adding 1 to strlen). * * - Ric */ /* * Keys: * CTRL/S + mouse click - (over edit window) Pick up colour under mouse * SHIFT+mb down+drag mouse - select rectangle (select mode only) * SPACEBAR - toggle between draw mode and select mode * CTRL+Z or U - one level undo * CTRL+A - select all * CTRL+U - unselect all * CTRL+C - copy selected area * CTRL+X - cut selected area * CTRL+V - paste * DEL - clears selected area * CTRL+R - reverts the tile to the original (like undo in maped 1) * (self note: modify to ask for confirmation) * G - toggles grid on/off * H - toggles hilight on/off * M - toggles mask on/off * I - inverts mask * X - mirrors image * Y - flips image * L/R - Rotates tile 90 degrees anti-clockwise/clockwise * Q/W - Steps through animation (in tile edit mode) if any * A/Z and S/X - changes the left or right drawing colours * PGUP/PGDN - Colour shift up/down * [ and ] - toggle screen resolutions * ALT+X - quits to DOS */ /* -- 26/Jul/98 -- * I've actually decided to start the editor over in a new file so that the * code is a bit more elegant. As it stands some bits of this are messy but * it currently works ;). Anyway I've decided that what I'll do is to in * effect write two tile editors - continuing work on this one and working * on the rewrite as a "side project". The eventual aim will be to replace * this editor with the rewrite but if factors intervene preventing me from * completing the rewrite then there'll always be this editor to fall back on. * * New in this release is a copy/cut/paste system. New buttons have been added. * For some reason I haven't figured out yet I can't call the two rotate * buttons "Rotate ACW" and "Rotate CW" (it causes MapEd to crash) so I've had * to resort to calling them "Turn_L" and "Turn_R". * - Ric */ #include #include #include "config.h" #include "guicomp.h" #include "keyboard.h" #include "maped.h" #include "mouse.h" #include "render.h" #include "vdriver.h" #include "smalfont.h" #undef free #define TRUE 1 #define FALSE 0 // #define NULL ((void *)0) #define MOUSENONE 0 // No mouse buttons pressed #define MOUSERELEASE 1 // Mouse button released #define MOUSEPRESSED 2 // Mouse button held down #define MOUSECLICKED 4 // Mouse button pressed // Setup some defines for the regions/areas/windows where everything goes #define MAX_REGIONS 29 // Number of regions #define BASEREG 0 // Window coords + title #define HELPBAR 1 // Helpbar - put helpful messages here :) #define PALETTE 2 // The palette #define EDITREG 3 // Main edit window #define PREVIEW 4 // Preview of image being edited #define SCOLBOX 5 // Selected colour box #define SCTXTBX 6 // Text box to show info on the selected colours #define QUITBUT 7 // Quit button #define DRAWBUT 8 // Draw mode indicator #define FILLBUT 9 // Fill mode indicator #define PICKBUT 10 // Pick mode indicator #define MASKBUT 11 // Mask mode indicator #define PSTEBUT 12 // Paste mode indicator #define EDMDFRM 13 // Frame for edit mode radio buttons #define MASKIND 14 // Indicator showing if mask is shown #define GRIDIND 15 // Indicator showing if grid is shown #define ANIMIND 16 // Indicator showing if animations are shown #define PXHLIND 17 // Indicator showing if pixel highlight shown #define IND_FRM 18 // Frame for indicators (push buttons) #define BUT_FRM 19 // Frame for buttons #define UNDOBUT 20 // Undo button #define COPYBUT 21 // Copy button #define CUT_BUT 22 // Cut button #define CLR_BUT 23 // Clear button #define TOOLFRM 24 // Frame for tools #define FLIPBUT 25 // Flip image button #define MIRRBUT 26 // Mirror image button #define RIACBUT 27 // Rotate anticlockwise button #define RIC_BUT 28 // Rotate clockwise button // Define TEbitflags values #define TEQUITCUR 1 #define TEANIMATE 2 #define TEGRID 4 #define TEHILIGHT 8 #define TESHOWMSK 16 // Define TEREGION->bitflags values #define REGVISIBLE 1 #define REGACTIVE 2 #define REGNOCLICK 4 #define REGTWOCLICK 8 // wait for a second click // TEeditmode defs #define EDDRAW 1 #define EDFILL 2 #define EDPICK 4 #define EDMASK 8 #define EDPASTE 16 // TEtype defs #define TEUNKNOWN 0 #define TETILE 1 // DATABUTTON buttontypes: #define CLICKBUTTON 1 // normal button #define PUSHBUTTON 2 // can be pushed in/out (toggle bit bitvalue) #define RADIOBUTTON 4 // for button banks (set *bitflag=bitvalue) // DATABASEREGION windowtypes: #define DBRSTDWINDOW 0 // window and title bar #define DBRPANEL 1 // no title bar // INFOTYPEs: #define DITREGION 1 #define DITBASEREGION 2 #define DITBUTTON 4 #define DITEDITREG 8 // Button flag action - has this button been clicked? #define BFANONE 0 #define BFAUNDO 1 #define BFACOPY 2 #define BFACUT 4 #define BFACLEAR 8 #define BFARIAC 16 #define BFARIC 32 #define BFAMIRROR 64 #define BFAFLIP 128 // Variables typedef struct TEREGION { int infotype; // type of struct unsigned int x1, x2, y1, y2; // bounding coordinates char *caption; // helpbar text int bitflags; // see defines above void (*drawproc)(struct TEREGION *); // region's draw procedure // - allows nice and short RenderTileEdit proc ;) void *data; // extended information } TEREGION; typedef struct DATABASEREGION { int infotype; // type of struct int numofregs; // total number of regions (including base) int windowtype; // type of window to draw } DATABASEREGION; typedef struct DATABUTTON { int infotype; // type of struct int *bitflag; // address of bitflag char *text; // addition text (eg helptext) int bitvalue; // 1st bit/value int buttontype; // type } DATABUTTON; typedef struct DATAEDITREG { int infotype; // type of struct int firstx, firsty; // first coords for two-click operation } DATAEDITREG; static TEREGION *TEregs=NULL; // pointer to the regions static unsigned char lcolor=255; // left mouse colour static unsigned char rcolor=0; // right mouse colour static TEREGION *TEOldReg=NULL; static unsigned int MBStatus[3]={MOUSENONE,MOUSENONE,MOUSENONE}; static int TEanimstrand=0; // Animation strand static int TEbitflags=TEANIMATE; // Set default bitflags static int TEbfa=BFANONE; // Set default button action flags static int TEeditmode=EDDRAW; // Default edit region mode static int TExoffs=16; // X offset for region "windows" static int TEyoffs=16; // Y offset for region "windows" unsigned int TEtype=TEUNKNOWN; // type of graphic being edited unsigned int TEtile; // tile to edit - may possibly expand this to an array for simultaneous editing unsigned int TExsize=0; // width of graphic being edited unsigned int TEysize=0; // height of graphic being edited unsigned int TEcopyxsize=0; // width of copy buffer unsigned int TEcopyysize=0; // height of copy buffer unsigned char *TEsource=NULL; // pointer to original image being edited static unsigned char *TEimage=NULL; // pointer to image being edited static unsigned char *TEmask=NULL; // pointer to image mask static unsigned char *TEundo=NULL; // pointer to undo buffer static unsigned char *TEcopy=NULL; // pointer to copy buffer static unsigned char *TEcmsk=NULL; // pointer to copy mask static char TEtempstr[256]; // Temporary string buffer // Function prototypes static void *TEAlloc(unsigned long amount, char *whatfor); #define TEFree(ptr) if (ptr) free(ptr); ptr=NULL; #define TEFreeReg(ptr) DestroyRegions(&ptr); if (ptr) free(ptr); ptr=NULL; #define TENewText(text, whatfor) (char *) strcpy(TEAlloc(strlen(text)+1, whatfor), text); //static void TEFree(void *TETmpBuf); static void MBClickHandler(TEREGION *TEBaseReg); static void AboutTE(void); static void DestroyRegions(TEREGION **TEBaseReg); static void SetupRegions(void); static void InitTEImage(void); static void DeinitTEImage(void); static int MouseOverTEreg(TEREGION *TEr); static void RenderTileEdit(TEREGION *TEBaseReg); static void RestartTileEditor(void); static void SetCaption(TEREGION *TEr, char *helptext); static void TEDrawHilight(int x1, int y1, int width, int height, unsigned char colour); static void TEDrawCheckeredBox(int x1, int y1, int width, int height, unsigned char colour); static void TERegFill(TEREGION *TEr, int colour); static void TERegText(TEREGION *TEr, char *message); static void TEClearImage(void); static void TECopyImage(void); static void TEFlipImage(unsigned char *TERILsrc, int TERILxsize, int TERILysize); static void TEMirrorImage(unsigned char *TERILsrc, int TERILxsize, int TERILysize); static void TERotateImageAntiClockwise(unsigned char *TERILsrc, int TERILxsize, int TERILysize); static void TERotateImageClockwise(unsigned char *TERILsrc, int TERILxsize, int TERILysize); static void TEFillImage(char *TEFIimage, char *TEFImask, int TEFIxsize, int TEFIysize, int TEFIx, int TEFIy, char TEFIcolour); static void TERFillImage(char *TERFIimage, char *TERFImask, int TERFIxsize, int TERFIysize, int TERFIx, int TERFIy); static void TEShiftColours(char *TESCimage, char *TESCmask, int TESCxsize, int TESCysize, int amount); static void TEUndo(void); static void DrawButton(TEREGION *TEr); static void DrawEditReg(TEREGION *TEr); static void DrawHelpBar(TEREGION *TEr); static void DrawPalette(TEREGION *TEr); static void DrawPreview(TEREGION *TEr); static void DrawSColBox(TEREGION *TEr); static void DrawSCTxtBx(TEREGION *TEr); static void DrawSunkRegion(TEREGION *TEr); void TileEdit(void); static int MouseOverTEreg(TEREGION *TEr) { unsigned int testx=mx-TExoffs; unsigned int testy=my-TEyoffs; unsigned int width=(TEr->x2)-(TEr->x1); unsigned int height=(TEr->y2)-(TEr->y1); testx-=(TEr->x1); testy-=(TEr->y1); if (testx >= width || testy >= height) return FALSE; return TRUE; } static void DrawButton(TEREGION *TEr) // -- ric: 20/Jul/98 - generic button routine { unsigned int x=TEr->x1+TExoffs; unsigned int y=TEr->y1+TEyoffs; unsigned int width=(TEr->x2)-(TEr->x1); unsigned int height=(TEr->y2)-(TEr->y1); strcpy(TEtempstr,"Button data not declared."); if (!TEr->data) err(TEtempstr); if (((struct DATABUTTON *)(TEr->data))->infotype!=DITBUTTON) err(TEtempstr); // draw raised button stdwindow(x-1, y-1, x+width+1, y+height+1); if (TEr->caption) { GotoXY(x+(width-(pixels(TEr->caption)))/2, y+(height-6)/2); printstring(TEr->caption); } switch (((struct DATABUTTON *)(TEr->data))->buttontype) { case CLICKBUTTON: if (MouseOverTEreg(TEr) && TEr->bitflags®ACTIVE) { if (((struct DATABUTTON *)(TEr->data))->text) SetCaption(&TEregs[HELPBAR], (((struct DATABUTTON *)(TEr->data))->text)); // Handle mouse clicks if (TEOldReg==TEr) { if ((MBStatus[0]|MBStatus[1])==MOUSEPRESSED) { // draw button down FilledBox(x, y, width, height, winbg); HLine(x, y, width, darkw); VLine(x, y, height, darkw); if (TEr->caption) { GotoXY(x+1+(width-(pixels(TEr->caption)))/2, y+1+(height-6)/2); printstring(TEr->caption); } } if ((MBStatus[0]|MBStatus[1])==MOUSERELEASE) { *(((struct DATABUTTON *)(TEr->data))->bitflag)^=((struct DATABUTTON *)(TEr->data))->bitvalue; } } } break; case PUSHBUTTON: if (*(((struct DATABUTTON *)(TEr->data))->bitflag)&(((struct DATABUTTON *)(TEr->data))->bitvalue)) { // draw button down FilledBox(x, y, width, height, winbg); HLine(x, y, width, darkw); VLine(x, y, height, darkw); if (TEr->caption) { GotoXY(x+1+(width-(pixels(TEr->caption)))/2, y+1+(height-6)/2); printstring(TEr->caption); } } if (MouseOverTEreg(TEr) && TEr->bitflags®ACTIVE) { if (((struct DATABUTTON *)(TEr->data))->text) { sprintf(TEtempstr, "Toggle %s on/off", ((struct DATABUTTON *)(TEr->data))->text); SetCaption(&TEregs[HELPBAR], TEtempstr); } // Handle mouse clicks if (TEOldReg==TEr) { if ((MBStatus[0]|MBStatus[1])==MOUSECLICKED) { *(((struct DATABUTTON *)(TEr->data))->bitflag)^=((struct DATABUTTON *)(TEr->data))->bitvalue; } } } break; case RADIOBUTTON: if (*(((struct DATABUTTON *)(TEr->data))->bitflag)==((struct DATABUTTON *)(TEr->data))->bitvalue) { // draw button down FilledBox(x, y, width, height, winbg); HLine(x, y, width, darkw); VLine(x, y, height, darkw); if (TEr->caption) { GotoXY(x+1+(width-(pixels(TEr->caption)))/2, y+1+(height-6)/2); printstring(TEr->caption); } } if (MouseOverTEreg(TEr) && TEr->bitflags®ACTIVE) { if (((struct DATABUTTON *)(TEr->data))->text) SetCaption(&TEregs[HELPBAR], (((struct DATABUTTON *)(TEr->data))->text)); // Handle mouse clicks if (TEOldReg==TEr) { if ((MBStatus[0]|MBStatus[1])==MOUSECLICKED) { *(((struct DATABUTTON *)(TEr->data))->bitflag)=((struct DATABUTTON *)(TEr->data))->bitvalue; } } } break; } } static void DrawSunkRegion(TEREGION *TEr) { unsigned int x=TEr->x1+TExoffs; unsigned int y=TEr->y1+TEyoffs; unsigned int width=(TEr->x2)-(TEr->x1); unsigned int height=(TEr->y2)-(TEr->y1); // FilledBox(x, y, width, height, black); HLine(x, y, width, darkw); VLine(x, y, height, darkw); HLine(x+1, y+height-1, width-1, brightw); VLine(x+width-1, y+1, height-1, brightw); } static void DrawEditReg(TEREGION *TEr) { int i,j,i2,j2,c; int minx,miny,maxx,maxy; int blocksize=8; int visblocksize=blocksize; char *img; TEREGION tempr; tempr.x1=TEr->x1+2; tempr.x2=TEr->x2-2; tempr.y1=TEr->y1+2; tempr.y2=TEr->y2-2; img=TEimage; //vsp+(256*TEtile); TERegFill(TEr, black); DrawSunkRegion(TEr); FilledBox(TEr->x1+TExoffs+2, TEr->y1+TEyoffs+2, (blocksize<<4), (blocksize<<4), titlebg); if (TEbitflags&TEGRID) visblocksize-=1; for (j=0; jx1+TExoffs+2+i*blocksize, TEr->y1+TEyoffs+2+j*blocksize, visblocksize, visblocksize, *img++); if (TEbitflags&TESHOWMSK && !TEmask[j*TExsize+i]) TEDrawCheckeredBox(TEr->x1+TExoffs+2+i*blocksize, TEr->y1+TEyoffs+2+j*blocksize, visblocksize, visblocksize, titlebg); } img=TEimage; if (TEr->bitflags®ACTIVE && !(MouseOverTEreg(&tempr)) && (MBStatus[0]|MBStatus[1])==MOUSERELEASE) if (TEr->bitflags®TWOCLICK) TEr->bitflags^=REGTWOCLICK; if (MouseOverTEreg(&tempr) && TEr->bitflags®ACTIVE) { i=(mx-TExoffs-(tempr.x1))/blocksize; j=(my-TEyoffs-(tempr.y1))/blocksize; c=img[(j*TExsize)+i]; 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]); SetCaption(&TEregs[HELPBAR], TEtempstr); if (TEbitflags&TEHILIGHT) TEDrawHilight(TExoffs+i*blocksize+tempr.x1, TEyoffs+j*blocksize+tempr.y1, visblocksize, visblocksize, white); // if pasting draw the image being pasted if (TEeditmode==EDPASTE) { for (j2=0; j2x1+TExoffs+2+(i+i2)*blocksize, TEr->y1+TEyoffs+2+(j+j2)*blocksize, visblocksize, visblocksize, TEcopy[j2*TEcopyxsize+i2]); else if (TEmask[(j+j2)*TExsize+i+i2]) FilledBox(TEr->x1+TExoffs+2+(i+i2)*blocksize, TEr->y1+TEyoffs+2+(j+j2)*blocksize, visblocksize, visblocksize, TEcopy[j2*TEcopyxsize+i2]); } if (TEeditmode==EDMASK) { // draw reg if (TEr->bitflags®TWOCLICK) for (j2=0; j2=j && j2<=((struct DATAEDITREG *)(TEr->data))->firsty) || (j2>=((struct DATAEDITREG *)(TEr->data))->firsty && j2<=j)) && ((i2>=i && i2<=((struct DATAEDITREG *)(TEr->data))->firstx) || (i2>=((struct DATAEDITREG *)(TEr->data))->firstx && i2<=i))) TEDrawCheckeredBox(TEr->x1+TExoffs+2+i2*blocksize, TEr->y1+TEyoffs+2+j2*blocksize, visblocksize, visblocksize, darkred); if ((MBStatus[0]|MBStatus[1])==MOUSECLICKED && (key[SCAN_LSHIFT] || key[SCAN_RSHIFT]) && !(TEr->bitflags®TWOCLICK)) { ((struct DATAEDITREG *)(TEr->data))->firstx=i; ((struct DATAEDITREG *)(TEr->data))->firsty=j; TEr->bitflags^=REGTWOCLICK; } if ((MBStatus[0]|MBStatus[1])==MOUSERELEASE && TEr->bitflags®TWOCLICK) { if (MBStatus[1]==MOUSERELEASE) c=0x0; else c=0xf; miny=j; maxy=((struct DATAEDITREG *)(TEr->data))->firsty; minx=i; maxx=((struct DATAEDITREG *)(TEr->data))->firstx; if (j>((struct DATAEDITREG *)(TEr->data))->firsty) { maxy=j; miny=((struct DATAEDITREG *)(TEr->data))->firsty; } if (i>((struct DATAEDITREG *)(TEr->data))->firstx) { maxx=i; minx=((struct DATAEDITREG *)(TEr->data))->firstx; } for (j2=miny; j2<=maxy; j2++) for (i2=minx; i2<=maxx; i2++) TEmask[j2*TExsize+i2]=(char)c; TEr->bitflags^=REGTWOCLICK; } } // Handle mouse clicks #ifdef JUNK if ((MBStatus[0]|MBStatus[1])==MOUSECLICKED && (key[SCAN_CTRL]||key[SCAN_S])) { // put code to lock out draw mode here } #endif if (TEOldReg==TEr) { // Update undo buffer if ((MBStatus[0]|MBStatus[1])==MOUSECLICKED && TEeditmode!=EDMASK && TEeditmode!=EDPICK && !(key[SCAN_CTRL]||key[SCAN_S])) memcpy(TEundo, TEimage, TExsize*TEysize); if (MBStatus[0]==MOUSECLICKED && TEeditmode==EDFILL) TEFillImage(TEimage, (TEbitflags&TESHOWMSK ? TEmask : NULL), TExsize, TEysize, i, j, lcolor); if (MBStatus[1]==MOUSECLICKED && TEeditmode==EDFILL) TEFillImage(TEimage, (TEbitflags&TESHOWMSK ? TEmask : NULL), TExsize, TEysize, i, j, rcolor); // Draw if ((MBStatus[0]|MBStatus[1])==MOUSEPRESSED) { if (TEeditmode==EDPASTE) { for (j2=0; j2bitflags®TWOCLICK)) TEmask[(j*TExsize)+i]=0xf; if (MBStatus[1]==MOUSEPRESSED) if (key[SCAN_CTRL]||key[SCAN_S]||(TEeditmode==EDPICK)) rcolor=TEimage[(j*TExsize)+i]; else if ((TEeditmode==EDDRAW)&&!(TEbitflags&TESHOWMSK && !TEmask[j*TExsize+i])) TEimage[(j*TExsize)+i]=rcolor; else if (TEeditmode==EDMASK && !(TEr->bitflags®TWOCLICK)) TEmask[(j*TExsize)+i]=0x0; } } } static void DrawHelpBar(TEREGION *TEr) { //int i, htext=0; TERegFill(TEr, black); DrawSunkRegion(TEr); if (TEr->caption) TERegText(TEr, TEr->caption); TEFree(TEr->caption); // Blank caption //TEr->caption=NULL; // why doesn't this work in TEFree? #ifdef JUNK i=MAX_REGIONS; do { i--; if (MouseOverTEreg(&TEregs[i])) htext=i; } while (i>0); if (htext && TEregs[htext].helptext) TERegText(TEr, TEr->caption); #endif } static void DrawPalette(TEREGION *TEr) { int i,j; unsigned int width=(TEr->x2)-(TEr->x1); unsigned int height=(TEr->y2)-(TEr->y1); int xscale=(width-4)>>6; int yscale=(height-4)>>2; int x=(TEr->x1)+TExoffs; int y=(TEr->y1)+TEyoffs; TEREGION tempr; tempr.x1=TEr->x1+2; tempr.x2=TEr->x2-2; tempr.y1=TEr->y1+2; tempr.y2=TEr->y2-2; x+=2; y+=2; TERegFill(TEr, black); DrawSunkRegion(TEr); i=64; do { i--; FilledBox(x+(i*xscale), y, xscale, yscale, i); FilledBox(x+(i*xscale), y+yscale, xscale, yscale, i+64); FilledBox(x+(i*xscale), y+yscale*2, xscale, yscale, i+128); FilledBox(x+(i*xscale), y+yscale*3, xscale, yscale, i+192); } while (i>0); i=lcolor&63; j=lcolor>>6; TEDrawHilight(x+i*xscale, y+j*yscale, xscale, yscale, titlebg); i=rcolor&63; j=rcolor>>6; TEDrawHilight(x+i*xscale, y+j*yscale, xscale, yscale, titlebg); if (MouseOverTEreg(&tempr) && TEr->bitflags®ACTIVE) { i=(mx-TExoffs-(tempr.x1))/xscale; j=(my-TExoffs-(tempr.y1))/yscale; i+=(j<<6); j=i*3; sprintf(TEtempstr, "Color: %03d (rgb: %03d/%03d/%03d)", i, pal[j], pal[j+1], pal[j+2]); SetCaption(&TEregs[HELPBAR], TEtempstr); // Handle mouse clicks if (TEOldReg==TEr) { if (MBStatus[0]==MOUSEPRESSED) lcolor=i; if (MBStatus[1]==MOUSEPRESSED) rcolor=i; } } } static void DrawPreview(TEREGION *TEr) { char *img; int i; TERegFill(TEr, black); DrawSunkRegion(TEr); // img=vsp+(256*TEtile); img=TEimage; i=tileidx[TEtile]; if ((TEbitflags&TEANIMATE) && i!=TEtile) img=vsp+(256*i); CopyTile(TEr->x1+TExoffs+2, TEr->y1+TEyoffs+2, img); if (MouseOverTEreg(TEr) && TEr->bitflags®ACTIVE) { strcpy(TEtempstr, (TEbitflags&TEANIMATE ? "Click to halt animation" : "Click to animate tile")); SetCaption(&TEregs[HELPBAR], TEtempstr); // Handle mouse clicks if (TEOldReg==TEr) if ((MBStatus[0]|MBStatus[1])==MOUSECLICKED && MouseOverTEreg(TEr)) TEbitflags^=TEANIMATE; } } static void DrawSColBox(TEREGION *TEr) // -- ric: 15/Jul/98 - Draw selected colour box { int halfwidth=TEr->x2-TEr->x1-4; int height=TEr->y2-TEr->y1-4; char DSCBtempcolor; TERegFill(TEr, black); DrawSunkRegion(TEr); FilledBox(TExoffs+2+TEr->x1, TEyoffs+2+TEr->y1, halfwidth, height, titlebg); height-=2; halfwidth-=2; halfwidth>>=1; FilledBox(TExoffs+3+TEr->x1, TEyoffs+3+TEr->y1, halfwidth, height, lcolor); FilledBox(TExoffs+3+TEr->x1+halfwidth, TEyoffs+3+TEr->y1, halfwidth, height, rcolor); if (MouseOverTEreg(TEr) && TEr->bitflags®ACTIVE) { strcpy(TEtempstr, "Click to swap colors"); SetCaption(&TEregs[HELPBAR], TEtempstr); // Handle mouse clicks if (TEOldReg==TEr) if ((MBStatus[0]|MBStatus[1])==MOUSECLICKED && MouseOverTEreg(TEr)) { DSCBtempcolor=lcolor; lcolor=rcolor; rcolor=DSCBtempcolor; } } } static void DrawSCTxtBx(TEREGION *TEr) // -- ric: 15/Jul/98 - Draw selected colour text box { // char DSCTBTextBuf[256]; int i; int DSCTBx=TEr->x1+TExoffs+2; int DSCTBy=TEr->y1+TEyoffs+2; TERegFill(TEr, black); DrawSunkRegion(TEr); i=lcolor*3; sprintf(TEtempstr, "Left: %03d (rgb: %03d/%03d/%03d)", lcolor, pal[i], pal[i+1], pal[i+2]); GotoXY(DSCTBx, DSCTBy); printstring(TEtempstr); i=rcolor*3; sprintf(TEtempstr, "Right: %03d (rgb: %03d/%03d/%03d)", rcolor, pal[i], pal[i+1], pal[i+2]); GotoXY(DSCTBx, DSCTBy+7); printstring(TEtempstr); } static void SetCaption(TEREGION *TEr, char *helptext) { TEFree(TEr->caption); TEr->caption=(char *)strcpy((char *)TEAlloc(strlen(helptext)+1,helptext), helptext); } static void TEDrawHilight(int x1, int y1, int width, int height, unsigned char colour) // -- ric: 15/Jul/98 - Draws hilight around given rectangle { VLine(x1-1, y1, height, colour); VLine(x1+width, y1, height, colour); HLine(x1-1, y1-1, width+2, colour); HLine(x1-1, y1+height, width+2, colour); } static void TEDrawCheckeredBox(int x1, int y1, int width, int height, unsigned char colour) // -- ric: 17/Jul/98 - Draws a checkered box { int i,j; unsigned char c; for (j=0; j-1) FilledBox(TEr->x1+TExoffs, TEr->y1+TEyoffs, (TEr->x2)-(TEr->x1), (TEr->y2)-(TEr->y1), colour); } static void TERegText(TEREGION *TEr, char *message) // Prints given message in the specified region { int tempx, tempy; tempx=(TEr->x1)+TExoffs+2; tempy=(TEr->y2)-(TEr->y1); tempy>>=1; tempy+=(TEr->y1)-3; GotoXY(tempx,tempy+TEyoffs); printstring(message); } static void TEClearImage(void) // -- ric: 26/Jul/98 - clear selected image { int j; if (TEbitflags&TESHOWMSK) { j=TEysize*TExsize; memcpy(TEundo, TEimage, j); // backup image to undo buffer do { j--; if (*(TEmask+j)) *(TEimage+j)=rcolor; } while (j>0); } } static void TECopyImage(void) // -- ric: 26/Jul/98 - copy selected image to copy buffer { int i, j, TECIxstart, TECIystart, TECIxsize, TECIysize; if (TEbitflags&TESHOWMSK) // only makes sense if selected region is shown { TECIxstart=TExsize; TECIystart=TEysize; TECIxsize=-1; TECIysize=-1; // loop through image to find the starting and ending x and y coords // of the image to copy for (j=0; jTECIxsize) TECIxsize=i; if (jTECIysize) TECIysize=j; } } TECIxsize-=TECIxstart-1; TECIysize-=TECIystart-1; if (TECIxsize>0 && TECIysize>0) { // free and create TEcopy and TEcmsk buffers TEFree(TEcopy); TEFree(TEcmsk); // make copy buffer square (allows for rotation) TEcopyxsize=TECIysize; TEcopyysize=TECIysize; if (TECIxsize>TECIysize) { TEcopyxsize=TECIxsize; TEcopyysize=TECIxsize; } TEcopy=(char *)TEAlloc(TEcopyxsize*TEcopyysize, "copy buffer"); TEcmsk=(char *)TEAlloc(TEcopyxsize*TEcopyysize, "copy mask"); // copy image into buffer for (j=0; j0); } while (j>0); TEFree(TERILimg); } } static void TERotateImageClockwise(unsigned char *TERILsrc, int TERILxsize, int TERILysize) // -- ric: 16/Jul/98 - rotates image (must be square) 90 degrees clockwise { unsigned char *TERILimg=NULL; int i, j, amount; if (TERILxsize==TERILysize) { amount=TERILxsize*TERILysize; TERILimg=(char *) TEAlloc(amount, "temporary image buffer for TERotateImageClockwise"); memcpy(TERILimg, TERILsrc, amount); j=TERILysize; do { j--; i=TERILxsize; do { i--; TERILsrc[(j*TERILxsize)+i]=TERILimg[((TERILxsize-1-i)*TERILxsize)+(j)]; } while (i>0); } while (j>0); TEFree(TERILimg); } } static void TEFlipImage(unsigned char *TERILsrc, int TERILxsize, int TERILysize) // -- ric: 15/Jul/98 - flips image { unsigned char *TERILimg=NULL; int i, j, amount; amount=TERILxsize*TERILysize; TERILimg=(char *) TEAlloc(amount, "temporary image buffer for TEFlipImage"); memcpy(TERILimg, TERILsrc, amount); j=TERILysize; do { j--; i=TERILxsize; do { i--; TERILsrc[(j*TERILxsize)+i]=TERILimg[((TERILysize-1-j)*TERILxsize)+i]; } while (i>0); } while (j>0); TEFree(TERILimg); } static void TEMirrorImage(unsigned char *TERILsrc, int TERILxsize, int TERILysize) // -- ric: 15/Jul/98 - mirrors image { unsigned char *TERILimg=NULL; int i, j, amount; amount=TERILxsize*TERILysize; TERILimg=(char *) TEAlloc(amount, "temporary image buffer for TEMirrorImage"); memcpy(TERILimg, TERILsrc, amount); j=TERILysize; do { j--; i=TERILxsize; do { i--; TERILsrc[(j*TERILxsize)+i]=TERILimg[(j*TERILxsize)+(TERILxsize-1-i)]; } while (i>0); } while (j>0); TEFree(TERILimg); } static void TEFillImage(char *TEFIimage, char *TEFImask, int TEFIxsize, int TEFIysize, int TEFIx, int TEFIy, char TEFIcolour) // -- ric: 29/Jul/98 - Fill procedure - sets up and calls recursive procedure below { int i,j; unsigned char *TEFIfillmask=NULL; // will eventually contain 0 for ignore and 1 for fill TEFIfillmask=(char *) TEAlloc(TEFIxsize*TEFIysize, "temporary fill buffer for TEFillImage"); TERFillImage(TEFIimage, TEFIfillmask, TEFIxsize, TEFIysize, TEFIx, TEFIy); if (TEFImask) for (j=0; j=0 && x=0 && y=0 && x=0 && y=0 && x=0 && y=0 && x=0 && y0); } while (j>0); } static void TEUndo (void) { unsigned char *tempimg=TEimage; TEimage=TEundo; TEundo=tempimg; } static void *TEAlloc(unsigned long amount, char *whatfor) // -- ric: 14/Jul/98 - TE's custom, error-handling memory allocation routine { char *TETmpBuf=NULL; amount += 3; // aen amount &= ~3; // static char DebugBuf[256]; TETmpBuf=(char *) malloc(amount); if (!TETmpBuf) { sprintf(TEtempstr, "Unable to allocate %ld bytes for %s.", amount, whatfor); err(TEtempstr); } memset(TETmpBuf,0, amount); // Clear allocated mem /* __asm { // aen mov edi,TETmpBuf mov ecx,amount shr ecx,2 xor eax,eax cld rep stosd } ; */ return TETmpBuf; } #ifdef JUNK static void TEFree(void *TETmpBuf) // -- ric: 14/Jul/98 - TE's custom memory freeing routine { if (TETmpBuf) free(TETmpBuf); // Only free memory if previously allocated TETmpBuf=NULL; // Set freed memory to point to NULL } #endif static void MBClickHandler(TEREGION *TEBaseReg) // -- ric: 20/Jul/98 - Mouse button click handler { int i,j; ReadMouse(); if (TEBaseReg) { if (!TEBaseReg->data) err("No region data defined."); if (((struct DATABASEREGION *)TEBaseReg->data)->infotype!=DITBASEREGION) err("MBClickHandler called with invalid base region."); } for (i=0; i<3; ++i) { if (mb & (i+1)) { if (MBStatus[i] == MOUSECLICKED) MBStatus[i]=MOUSEPRESSED; else if (MBStatus[i] == MOUSENONE) { MBStatus[i] = MOUSECLICKED; if (TEBaseReg) { TEOldReg = NULL; for (j=0; j<((struct DATABASEREGION *)TEBaseReg->data)->numofregs; ++j) if (MouseOverTEreg(TEBaseReg+j)&&!((TEBaseReg+j)->bitflags®NOCLICK)) TEOldReg = TEBaseReg+j; } } } else { if (MBStatus[i] <= MOUSERELEASE) MBStatus[i] = MOUSENONE; else if (MBStatus[i]>MOUSERELEASE) MBStatus[i] = MOUSERELEASE; } } } static void AboutTE (void) // Just here to test the mouse input loop - remove this later { TEREGION *TEr=NULL; TEREGION *TEaboutwin=NULL; // int amxsize=150, amysize=82; int amxofs=60, amyofs=60; int i,i2,j,j2; int QuitAW=FALSE; int moving=FALSE; // Allocate memory TEaboutwin=(struct TEREGION *) TEAlloc((sizeof (struct TEREGION))*4,"about window regions"); TEr=TEaboutwin; TEr->infotype=DITREGION; TEr->x1=amxofs; TEr->x2=TEr->x1+150; TEr->y1=amyofs; TEr->y2=TEr->y1+82; TEr->bitflags=REGACTIVE|REGVISIBLE|REGNOCLICK; // TEr->drawproc=NULL; sprintf(strbuf, "About MapEd %s Tile Editor", ME2_VERSION); TEr->caption=TENewText(strbuf, "About window"); TEr->data=(struct DATABASEREGION *) TEAlloc(sizeof (struct DATABASEREGION), "base region data"); ((struct DATABASEREGION *)(TEr->data))->infotype=DITBASEREGION; ((struct DATABASEREGION *)(TEr->data))->numofregs=4; ((struct DATABASEREGION *)(TEr->data))->windowtype=DBRSTDWINDOW; TEr+=1; TEr->infotype=DITREGION; TEr->x1=0; TEr->x2=TEaboutwin->x2-TEaboutwin->x1-9; TEr->y1=0; TEr->y2=8; TEr->bitflags=REGACTIVE; // TEr->drawproc=NULL; // TEr->caption=NULL; TEr+=1; TEr->infotype=DITREGION; TEr->x1=TEaboutwin->x2-TEaboutwin->x1-9; TEr->x2=TEaboutwin->x2-TEaboutwin->x1-3; TEr->y1=3; TEr->y2=6; TEr->bitflags=REGACTIVE|REGVISIBLE; TEr->drawproc=&DrawButton; // TEr->caption=NULL; TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "quit button data"); ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON; ((struct DATABUTTON *)(TEr->data))->text=NULL; ((struct DATABUTTON *)(TEr->data))->buttontype=CLICKBUTTON; ((struct DATABUTTON *)(TEr->data))->bitflag=&QuitAW; ((struct DATABUTTON *)(TEr->data))->bitvalue=TRUE; TEr+=1; TEr->infotype=DITREGION; TEr->x1=60; TEr->x2=90; TEr->y1=62; TEr->y2=72; TEr->bitflags=REGACTIVE|REGVISIBLE; TEr->drawproc=&DrawButton; TEr->caption=TENewText("ok","ok button caption"); TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "quit button data"); ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON; ((struct DATABUTTON *)(TEr->data))->text=NULL; ((struct DATABUTTON *)(TEr->data))->buttontype=CLICKBUTTON; ((struct DATABUTTON *)(TEr->data))->bitflag=&QuitAW; ((struct DATABUTTON *)(TEr->data))->bitvalue=TRUE; TEr=TEaboutwin+1; // point to title bar area while (!QuitAW) { // Mouse button click handler routines MBClickHandler(TEaboutwin); amxofs=TEaboutwin->x1; amyofs=TEaboutwin->y1; if ((MBStatus[0]|MBStatus[1])==MOUSERELEASE) moving=FALSE; // Draw loop RenderTileEdit(TEregs); RenderTileEdit(TEaboutwin); sprintf(strbuf, "MapEd v.%s", ME2_VERSION); GotoXY(amxofs+52, amyofs+16); printstring(strbuf); GotoXY(amxofs+31, amyofs+22); printstring("Copyright (C) 1998 vecna"); GotoXY(amxofs+40, amyofs+28); printstring("All Rights Reserved"); sprintf(strbuf, "MapEd v.%s Tile Editor", ME2_VERSION); GotoXY(amxofs+29, amyofs+41); printstring(strbuf); GotoXY(amxofs+20, amyofs+47); printstring("Additional code by Richard Lau"); DrawMouse(); ShowPage(); // Move window? if (MouseOverTEreg(TEr) && TEOldReg==TEr) { if ((MBStatus[0]|MBStatus[1])==MOUSECLICKED) { i2=TEaboutwin->x2-TEaboutwin->x1; j2=TEaboutwin->y2-TEaboutwin->y1; i=mx-TEaboutwin->x1; j=my-TEaboutwin->y1; moving=TRUE; } } if ((MBStatus[0]|MBStatus[1])==MOUSEPRESSED && moving) { if (((mx-i)<16)) TEaboutwin->x1=16; else if (((mx-i+i2)>=(16+sx))) TEaboutwin->x1=16+(sx-i2); else TEaboutwin->x1=mx-i; if (((my-j)<16)) TEaboutwin->y1=16; else if (((my-j+j2)>=(16+sy))) TEaboutwin->y1=16+(sy-j2); else TEaboutwin->y1=my-j; TEaboutwin->x2=TEaboutwin->x1+i2; TEaboutwin->y2=TEaboutwin->y1+j2; } if (key[SCAN_ESC]) { key[SCAN_ESC]=0; QuitAW=TRUE; } } // free TEaboutwin TEFreeReg(TEaboutwin); } static void RestartTileEditor(void) // -- ric: 17/Jul/98 - reinit the tile editor { int i,j, amount; unsigned char *TERTEmask=NULL; switch (TEtype) { case TETILE: // edit tile TEtile i=TExsize; j=TEysize; amount=i*j; TERTEmask=(unsigned char *) TEAlloc(amount, "tile editor mask backup buffer"); // backup mask memcpy(TERTEmask, TEmask, amount); // Restart editor DeinitTEImage(); TEFreeReg(TEregs); TEtype=TETILE; TExsize=i; TEysize=j; TEsource=vsp+(256*TEtile); InitTEImage(); SetupRegions(); // Restore mask memcpy(TEmask, TERTEmask, amount); TEFree(TERTEmask); break; } } static void InitTEImage (void) // Copy the image data being edited and allocate memory for the image buffers { int i; int amount=TExsize*TEysize; if (TEtype==TEUNKNOWN) err("Unrecognised tile editor graphics type."); if (!TEsource) err("Invalid input image."); TEimage=(unsigned char *) TEAlloc(amount, "tile editor image buffer"); TEmask=(unsigned char *) TEAlloc(amount, "tile editor mask buffer"); TEundo=(unsigned char *) TEAlloc(amount, "tile editor undo buffer"); // if (!TEimage || !TEundo) err("Cannot allocate memory for tile editor image buffers."); memcpy(TEimage, TEsource, amount); // copy original image into edit buffer memcpy(TEundo, TEimage, amount); // copy original image into undo buffer // if editing tile find the animation strand (if any) tile belongs to TEanimstrand=0; // Does not belong to an animation strand if (TEtype==TETILE) { i=100; do { i--; if (vspanim[i].delay && TEtile<=vspanim[i].finish && TEtile>=vspanim[i].start) TEanimstrand=i+1; } while (i>0); } } static void DeinitTEImage(void) // Unallocate allocated image buffers - copy edited buffer into original { memcpy(TEsource, TEimage, (TExsize*TEysize)); TEFree(TEimage); TEFree(TEmask); TEFree(TEundo); TEtype=TEUNKNOWN; // Clear type info for error checking purposes TExsize=0; TEysize=0; } static void SetupRegions (void) { int temp; TEREGION *TEr=NULL; // Allocate memory TEregs=(struct TEREGION *) TEAlloc((sizeof (struct TEREGION))*MAX_REGIONS,"tile edit regions"); TEr=TEregs+BASEREG; TEr->infotype=DITREGION; TEr->x1=16; TEr->x2=TEr->x1+sx; TEr->y1=16; TEr->y2=TEr->y1+sy; TEr->bitflags=REGACTIVE|REGVISIBLE|REGNOCLICK; TEr->drawproc=NULL; TEr->caption=NULL; switch (TEtype) { case TETILE: sprintf(TEtempstr, "MapEd %s Tile Editor - Tile: %d", ME2_VERSION, TEtile); if (TEanimstrand) sprintf(TEtempstr, "MapEd %s Tile Editor - Tile: %d (anim strand: %d, frame: %d/%d)", ME2_VERSION, TEtile, TEanimstrand-1, TEtile-vspanim[TEanimstrand-1].start+1, vspanim[TEanimstrand-1].finish-vspanim[TEanimstrand-1].start+1); SetCaption(TEr, TEtempstr); break; } TEr->data=(struct DATABASEREGION *) TEAlloc(sizeof (struct DATABASEREGION), "base region data"); ((struct DATABASEREGION *)(TEr->data))->infotype=DITBASEREGION; ((struct DATABASEREGION *)(TEr->data))->numofregs=MAX_REGIONS; ((struct DATABASEREGION *)(TEr->data))->windowtype=DBRSTDWINDOW; TEr=TEregs+HELPBAR; TEr->infotype=DITREGION; TEr->x1=3; TEr->x2=TEregs->x2-TEregs->x1-3; TEr->y1=TEregs->y2-TEregs->y1-13; TEr->y2=TEregs->y2-TEregs->y1-3; TEr->bitflags=REGACTIVE|REGVISIBLE|REGNOCLICK; TEr->drawproc=&DrawHelpBar; TEr->caption=NULL; TEr->data=NULL; temp=(((TEregs->x2-TEregs->x1-8)>>6)<<5)+2; TEr=TEregs+PALETTE; TEr->infotype=DITREGION; TEr->x1=((TEregs->x2-TEregs->x1)>>1)-temp; TEr->x2=((TEregs->x2-TEregs->x1)>>1)+temp; TEr->y1=TEregs->y2-TEregs->y1-36; TEr->y2=TEregs->y2-TEregs->y1-16; TEr->bitflags=REGACTIVE|REGVISIBLE; TEr->drawproc=&DrawPalette; TEr->caption=NULL; TEr->data=NULL; TEr=TEregs+EDITREG; TEr->infotype=DITREGION; TEr->x1=3; TEr->x2=3+128+4; TEr->y1=10; TEr->y2=10+128+4; TEr->bitflags=REGACTIVE|REGVISIBLE; TEr->drawproc=&DrawEditReg; TEr->caption=NULL; TEr->data=(struct DATAEDITREG *) TEAlloc(sizeof (struct DATAEDITREG), "edit region data"); ((struct DATAEDITREG *)(TEr->data))->infotype=DITEDITREG; TEr=TEregs+PREVIEW; TEr->infotype=DITREGION; TEr->x1=TEregs->x2-TEregs->x1-23; TEr->x2=TEregs->x2-TEregs->x1-3; TEr->y1=10; TEr->y2=10+20; TEr->bitflags=REGACTIVE|REGVISIBLE; TEr->drawproc=&DrawPreview; TEr->caption=NULL; TEr->data=NULL; TEr=TEregs+SCOLBOX; TEr->infotype=DITREGION; TEr->x1=TEregs[EDITREG].x1; TEr->x2=TEr->x1+20; TEr->y1=TEregs[EDITREG].y2+2; TEr->y2=TEr->y1+16; TEr->bitflags=REGACTIVE|REGVISIBLE; TEr->drawproc=&DrawSColBox; TEr->caption=NULL; TEr->data=NULL; TEr=TEregs+SCTXTBX; TEr->infotype=DITREGION; TEr->x1=TEregs[SCOLBOX].x2+2; TEr->x2=TEregs[EDITREG].x2; TEr->y1=TEregs[SCOLBOX].y1; TEr->y2=TEregs[SCOLBOX].y2; TEr->bitflags=REGACTIVE|REGVISIBLE|REGNOCLICK; TEr->drawproc=&DrawSCTxtBx; TEr->caption=NULL; TEr->data=NULL; TEr=TEregs+QUITBUT; TEr->infotype=DITREGION; TEr->x1=TEregs->x2-TEregs->x1-9; TEr->x2=TEregs->x2-TEregs->x1-3; TEr->y1=3; TEr->y2=6; TEr->bitflags=REGACTIVE|REGVISIBLE; TEr->drawproc=&DrawButton; TEr->caption=NULL; TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "quit button data"); ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON; ((struct DATABUTTON *)(TEr->data))->text=TENewText("Exit", "quit button text"); ((struct DATABUTTON *)(TEr->data))->buttontype=CLICKBUTTON; ((struct DATABUTTON *)(TEr->data))->bitflag=&TEbitflags; ((struct DATABUTTON *)(TEr->data))->bitvalue=TEQUITCUR; TEr=TEregs+EDMDFRM; TEr->infotype=DITREGION; TEr->x1=TEregs[EDITREG].x2+3; TEr->x2=TEr->x1+34; TEr->y1=TEregs[EDITREG].y1; TEr->y2=TEr->y1+11*5+3; // 10*number of buttons TEr->bitflags=REGACTIVE|REGVISIBLE|REGNOCLICK; TEr->drawproc=&DrawSunkRegion; TEr->caption=NULL; TEr->data=NULL; TEr=TEregs+DRAWBUT; TEr->infotype=DITREGION; TEr->x1=TEregs[EDMDFRM].x1+2; TEr->x2=TEregs[EDMDFRM].x2-2; TEr->y1=TEregs[EDMDFRM].y1+2; TEr->y2=TEr->y1+10; TEr->bitflags=REGACTIVE|REGVISIBLE; TEr->drawproc=&DrawButton; TEr->caption=NULL; SetCaption(TEr,"Draw"); TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "draw button data"); ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON; ((struct DATABUTTON *)(TEr->data))->text=TENewText("Draw mode", "draw button text"); ((struct DATABUTTON *)(TEr->data))->buttontype=RADIOBUTTON; ((struct DATABUTTON *)(TEr->data))->bitflag=&TEeditmode; ((struct DATABUTTON *)(TEr->data))->bitvalue=EDDRAW; TEr=TEregs+FILLBUT; TEr->infotype=DITREGION; TEr->x1=TEregs[EDMDFRM].x1+2; TEr->x2=TEregs[EDMDFRM].x2-2; TEr->y1=TEregs[EDMDFRM].y1+2+11; TEr->y2=TEr->y1+10; TEr->bitflags=REGACTIVE|REGVISIBLE; TEr->drawproc=&DrawButton; TEr->caption=NULL; SetCaption(TEr,"Fill"); TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "fill button data"); ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON; ((struct DATABUTTON *)(TEr->data))->text=TENewText("Fill mode", "fill button text"); ((struct DATABUTTON *)(TEr->data))->buttontype=RADIOBUTTON; ((struct DATABUTTON *)(TEr->data))->bitflag=&TEeditmode; ((struct DATABUTTON *)(TEr->data))->bitvalue=EDFILL; TEr=TEregs+PICKBUT; TEr->infotype=DITREGION; TEr->x1=TEregs[EDMDFRM].x1+2; TEr->x2=TEregs[EDMDFRM].x2-2; TEr->y1=TEregs[EDMDFRM].y1+2+22; TEr->y2=TEr->y1+10; TEr->bitflags=REGACTIVE|REGVISIBLE; TEr->drawproc=&DrawButton; TEr->caption=NULL; SetCaption(TEr,"Pick"); TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "pick button data"); ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON; ((struct DATABUTTON *)(TEr->data))->text=TENewText("Pick color mode", "pick button text"); ((struct DATABUTTON *)(TEr->data))->buttontype=RADIOBUTTON; ((struct DATABUTTON *)(TEr->data))->bitflag=&TEeditmode; ((struct DATABUTTON *)(TEr->data))->bitvalue=EDPICK; TEr=TEregs+MASKBUT; TEr->infotype=DITREGION; TEr->x1=TEregs[EDMDFRM].x1+2; TEr->x2=TEregs[EDMDFRM].x2-2; TEr->y1=TEregs[EDMDFRM].y1+2+33; TEr->y2=TEr->y1+10; TEr->bitflags=REGACTIVE|REGVISIBLE; TEr->drawproc=&DrawButton; TEr->caption=NULL; SetCaption(TEr,"Select"); TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "select button data"); ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON; ((struct DATABUTTON *)(TEr->data))->text=TENewText("Select mode", "select button text"); ((struct DATABUTTON *)(TEr->data))->buttontype=RADIOBUTTON; ((struct DATABUTTON *)(TEr->data))->bitflag=&TEeditmode; ((struct DATABUTTON *)(TEr->data))->bitvalue=EDMASK; TEr=TEregs+PSTEBUT; TEr->infotype=DITREGION; TEr->x1=TEregs[EDMDFRM].x1+2; TEr->x2=TEregs[EDMDFRM].x2-2; TEr->y1=TEregs[EDMDFRM].y1+2+44; TEr->y2=TEr->y1+10; TEr->bitflags=REGACTIVE|REGVISIBLE; TEr->drawproc=&DrawButton; TEr->caption=NULL; SetCaption(TEr,"Paste"); TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "paste button data"); ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON; ((struct DATABUTTON *)(TEr->data))->text=TENewText("Paste mode", "paste button text"); ((struct DATABUTTON *)(TEr->data))->buttontype=RADIOBUTTON; ((struct DATABUTTON *)(TEr->data))->bitflag=&TEeditmode; ((struct DATABUTTON *)(TEr->data))->bitvalue=EDPASTE; TEr=TEregs+IND_FRM; TEr->infotype=DITREGION; TEr->x1=TEregs[SCTXTBX].x2+2; TEr->x2=TEr->x1+12*4-1; // 10*number of buttons TEr->y1=TEregs[SCTXTBX].y1; TEr->y2=TEr->y1+13; TEr->bitflags=REGACTIVE|REGVISIBLE|REGNOCLICK; TEr->drawproc=&DrawSunkRegion; TEr->caption=NULL; TEr->data=NULL; TEr=TEregs+MASKIND; TEr->infotype=DITREGION; TEr->x1=TEregs[IND_FRM].x1+2; TEr->x2=TEr->x1+10; TEr->y1=TEregs[IND_FRM].y1+2; TEr->y2=TEregs[IND_FRM].y2-2; TEr->bitflags=REGACTIVE|REGVISIBLE; TEr->drawproc=&DrawButton; TEr->caption=NULL; SetCaption(TEr,"m"); TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "mask indicator data"); ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON; ((struct DATABUTTON *)(TEr->data))->text=TENewText("mask", "mask indicator text"); ((struct DATABUTTON *)(TEr->data))->buttontype=PUSHBUTTON; ((struct DATABUTTON *)(TEr->data))->bitflag=&TEbitflags; ((struct DATABUTTON *)(TEr->data))->bitvalue=TESHOWMSK; TEr=TEregs+GRIDIND; TEr->infotype=DITREGION; TEr->x1=TEregs[MASKIND].x2+1; TEr->x2=TEr->x1+10; TEr->y1=TEregs[IND_FRM].y1+2; TEr->y2=TEregs[IND_FRM].y2-2; TEr->bitflags=REGACTIVE|REGVISIBLE; TEr->drawproc=&DrawButton; TEr->caption=NULL; SetCaption(TEr,"g"); TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "grid button data"); ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON; ((struct DATABUTTON *)(TEr->data))->text=TENewText("grid", "grid indicator text"); ((struct DATABUTTON *)(TEr->data))->buttontype=PUSHBUTTON; ((struct DATABUTTON *)(TEr->data))->bitflag=&TEbitflags; ((struct DATABUTTON *)(TEr->data))->bitvalue=TEGRID; TEr=TEregs+ANIMIND; TEr->infotype=DITREGION; TEr->x1=TEregs[GRIDIND].x2+1; TEr->x2=TEr->x1+10; TEr->y1=TEregs[IND_FRM].y1+2; TEr->y2=TEregs[IND_FRM].y2-2; TEr->bitflags=REGACTIVE|REGVISIBLE; TEr->drawproc=&DrawButton; TEr->caption=NULL; SetCaption(TEr,"a"); TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "animation button data"); ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON; ((struct DATABUTTON *)(TEr->data))->text=TENewText("animation", "animation indicator text"); ((struct DATABUTTON *)(TEr->data))->buttontype=PUSHBUTTON; ((struct DATABUTTON *)(TEr->data))->bitflag=&TEbitflags; ((struct DATABUTTON *)(TEr->data))->bitvalue=TEANIMATE; TEr=TEregs+PXHLIND; TEr->infotype=DITREGION; TEr->x1=TEregs[ANIMIND].x2+1; TEr->x2=TEr->x1+10; TEr->y1=TEregs[IND_FRM].y1+2; TEr->y2=TEregs[IND_FRM].y2-2; TEr->bitflags=REGACTIVE|REGVISIBLE; TEr->drawproc=&DrawButton; TEr->caption=NULL; SetCaption(TEr,"h"); TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "highlight button data"); ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON; ((struct DATABUTTON *)(TEr->data))->text=TENewText("pixel highlight", "highlight indicator text"); ((struct DATABUTTON *)(TEr->data))->buttontype=PUSHBUTTON; ((struct DATABUTTON *)(TEr->data))->bitflag=&TEbitflags; ((struct DATABUTTON *)(TEr->data))->bitvalue=TEHILIGHT; TEr=TEregs+BUT_FRM; TEr->infotype=DITREGION; TEr->x1=TEregs[EDMDFRM].x1; TEr->x2=TEregs[EDMDFRM].x2; TEr->y1=TEregs[EDMDFRM].y2+2; TEr->y2=TEr->y1+11*4+3; // 10*number of buttons TEr->bitflags=REGACTIVE|REGVISIBLE|REGNOCLICK; TEr->drawproc=&DrawSunkRegion; TEr->caption=NULL; TEr->data=NULL; TEr=TEregs+UNDOBUT; TEr->infotype=DITREGION; TEr->x1=TEregs[BUT_FRM].x1+2; TEr->x2=TEregs[BUT_FRM].x2-2; TEr->y1=TEregs[BUT_FRM].y1+2; TEr->y2=TEr->y1+10; TEr->bitflags=REGACTIVE|REGVISIBLE; TEr->drawproc=&DrawButton; TEr->caption=NULL; SetCaption(TEr, "Undo"); TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "undo button data"); ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON; ((struct DATABUTTON *)(TEr->data))->text=TENewText("Undo last action", "undo button text"); ((struct DATABUTTON *)(TEr->data))->buttontype=CLICKBUTTON; ((struct DATABUTTON *)(TEr->data))->bitflag=&TEbfa; ((struct DATABUTTON *)(TEr->data))->bitvalue=BFAUNDO; TEr=TEregs+COPYBUT; TEr->infotype=DITREGION; TEr->x1=TEregs[BUT_FRM].x1+2; TEr->x2=TEregs[BUT_FRM].x2-2; TEr->y1=TEregs[BUT_FRM].y1+2+11; TEr->y2=TEr->y1+10; TEr->bitflags=REGACTIVE|REGVISIBLE; TEr->drawproc=&DrawButton; TEr->caption=NULL; SetCaption(TEr, "Copy"); TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "copy button data"); ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON; ((struct DATABUTTON *)(TEr->data))->text=TENewText("Copy selected area", "copy button text"); ((struct DATABUTTON *)(TEr->data))->buttontype=CLICKBUTTON; ((struct DATABUTTON *)(TEr->data))->bitflag=&TEbfa; ((struct DATABUTTON *)(TEr->data))->bitvalue=BFACOPY; TEr=TEregs+CUT_BUT; TEr->infotype=DITREGION; TEr->x1=TEregs[BUT_FRM].x1+2; TEr->x2=TEregs[BUT_FRM].x2-2; TEr->y1=TEregs[BUT_FRM].y1+2+22; TEr->y2=TEr->y1+10; TEr->bitflags=REGACTIVE|REGVISIBLE; TEr->drawproc=&DrawButton; TEr->caption=NULL; SetCaption(TEr, "Cut"); TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "cut button data"); ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON; ((struct DATABUTTON *)(TEr->data))->text=TENewText("Cut selected area", "cut button text"); ((struct DATABUTTON *)(TEr->data))->buttontype=CLICKBUTTON; ((struct DATABUTTON *)(TEr->data))->bitflag=&TEbfa; ((struct DATABUTTON *)(TEr->data))->bitvalue=BFACUT; TEr=TEregs+CLR_BUT; TEr->infotype=DITREGION; TEr->x1=TEregs[BUT_FRM].x1+2; TEr->x2=TEregs[BUT_FRM].x2-2; TEr->y1=TEregs[BUT_FRM].y1+2+33; TEr->y2=TEr->y1+10; TEr->bitflags=REGACTIVE|REGVISIBLE; TEr->drawproc=&DrawButton; TEr->caption=NULL; SetCaption(TEr, "Clear"); TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "clear button data"); ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON; ((struct DATABUTTON *)(TEr->data))->text=TENewText("Clear selected area", "clear button text"); ((struct DATABUTTON *)(TEr->data))->buttontype=CLICKBUTTON; ((struct DATABUTTON *)(TEr->data))->bitflag=&TEbfa; ((struct DATABUTTON *)(TEr->data))->bitvalue=BFACLEAR; TEr=TEregs+TOOLFRM; TEr->infotype=DITREGION; TEr->x1=TEregs[BUT_FRM].x2+2; TEr->x2=TEr->x1+34; TEr->y1=TEregs[BUT_FRM].y1; TEr->y2=TEr->y1+11*4+3; // 10*number of buttons TEr->bitflags=REGACTIVE|REGVISIBLE|REGNOCLICK; TEr->drawproc=&DrawSunkRegion; TEr->caption=NULL; TEr->data=NULL; TEr=TEregs+RIACBUT; TEr->infotype=DITREGION; TEr->x1=TEregs[TOOLFRM].x1+2; TEr->x2=TEregs[TOOLFRM].x2-2; TEr->y1=TEregs[TOOLFRM].y1+2; TEr->y2=TEr->y1+10; TEr->bitflags=REGACTIVE|REGVISIBLE; TEr->drawproc=&DrawButton; TEr->caption=NULL; SetCaption(TEr, "Turn L"); TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "rotate button data"); ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON; ((struct DATABUTTON *)(TEr->data))->text=TENewText("Rotate anticlockwise", "rotate button text"); ((struct DATABUTTON *)(TEr->data))->buttontype=CLICKBUTTON; ((struct DATABUTTON *)(TEr->data))->bitflag=&TEbfa; ((struct DATABUTTON *)(TEr->data))->bitvalue=BFARIAC; TEr=TEregs+RIC_BUT; TEr->infotype=DITREGION; TEr->x1=TEregs[TOOLFRM].x1+2; TEr->x2=TEregs[TOOLFRM].x2-2; TEr->y1=TEregs[TOOLFRM].y1+2+11; TEr->y2=TEr->y1+10; TEr->bitflags=REGACTIVE|REGVISIBLE; TEr->drawproc=&DrawButton; TEr->caption=NULL; SetCaption(TEr, "Turn R"); TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "rotate button data"); ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON; ((struct DATABUTTON *)(TEr->data))->text=TENewText("Rotate clockwise", "rotate button text"); ((struct DATABUTTON *)(TEr->data))->buttontype=CLICKBUTTON; ((struct DATABUTTON *)(TEr->data))->bitflag=&TEbfa; ((struct DATABUTTON *)(TEr->data))->bitvalue=BFARIC; TEr=TEregs+FLIPBUT; TEr->infotype=DITREGION; TEr->x1=TEregs[TOOLFRM].x1+2; TEr->x2=TEregs[TOOLFRM].x2-2; TEr->y1=TEregs[TOOLFRM].y1+2+22; TEr->y2=TEr->y1+10; TEr->bitflags=REGACTIVE|REGVISIBLE; TEr->drawproc=&DrawButton; TEr->caption=NULL; SetCaption(TEr, "Flip"); TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "flip button data"); ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON; ((struct DATABUTTON *)(TEr->data))->text=TENewText("Flip", "flip button text"); ((struct DATABUTTON *)(TEr->data))->buttontype=CLICKBUTTON; ((struct DATABUTTON *)(TEr->data))->bitflag=&TEbfa; ((struct DATABUTTON *)(TEr->data))->bitvalue=BFAFLIP; TEr=TEregs+MIRRBUT; TEr->infotype=DITREGION; TEr->x1=TEregs[TOOLFRM].x1+2; TEr->x2=TEregs[TOOLFRM].x2-2; TEr->y1=TEregs[TOOLFRM].y1+2+33; TEr->y2=TEr->y1+10; TEr->bitflags=REGACTIVE|REGVISIBLE; TEr->drawproc=&DrawButton; TEr->caption=NULL; SetCaption(TEr, "Mirror"); TEr->data=(struct DATABUTTON *) TEAlloc(sizeof (struct DATABUTTON), "mirror button data"); ((struct DATABUTTON *)(TEr->data))->infotype=DITBUTTON; ((struct DATABUTTON *)(TEr->data))->text=TENewText("Mirror", "mirror button text"); ((struct DATABUTTON *)(TEr->data))->buttontype=CLICKBUTTON; ((struct DATABUTTON *)(TEr->data))->bitflag=&TEbfa; ((struct DATABUTTON *)(TEr->data))->bitvalue=BFAMIRROR; } static void DestroyRegions (TEREGION **TEBaseReg) { TEREGION *TEr=NULL; int i; if (!(*TEBaseReg)->data) err("No region data defined."); if (((struct DATABASEREGION *)(*TEBaseReg)->data)->infotype!=DITBASEREGION) err("DestroyRegions called with invalid base region."); i=((struct DATABASEREGION *)(*TEBaseReg)->data)->numofregs; do { i--; TEr=(*TEBaseReg)+i; TEFree(TEr->caption); if (TEr->data) { switch (((struct DATABASEREGION *)(TEr->data))->infotype) { case DITBASEREGION: break; case DITBUTTON: TEFree(((struct DATABUTTON *)TEr->data)->text); break; } } TEFree(TEr->data); } while (i>0); TEFree(*TEBaseReg); // if (*TEBaseReg) err("Not freed"); } static void RenderTileEdit (TEREGION *TEBaseReg) // -- ric: 20/Jul/98 - updatedt to be a little more generic ;) { int i; TExoffs=TEBaseReg->x1; TEyoffs=TEBaseReg->y1; if (!TEBaseReg->data) err("No region data defined."); if (((struct DATABASEREGION *)TEBaseReg->data)->infotype!=DITBASEREGION) err("RenderTileEdit called with invalid base region."); switch (((struct DATABASEREGION *)TEBaseReg->data)->windowtype) { case DBRSTDWINDOW: Window(TExoffs,TEyoffs,TEBaseReg->x2,TEBaseReg->y2, ((TEBaseReg->caption) ? TEBaseReg->caption : "")); break; case DBRPANEL: stdwindow(TExoffs,TEyoffs,TEBaseReg->x2,TEBaseReg->y2); break; } i=((struct DATABASEREGION *)TEBaseReg->data)->numofregs; do { i--; if ((TEBaseReg+i)->bitflags®VISIBLE) (TEBaseReg+i)->drawproc(TEBaseReg+i); } while (i>1); } void TileEdit (void) { int i,j; int TEoldeditmode=EDDRAW; if (TEbitflags&TEQUITCUR) TEbitflags^=TEQUITCUR; InitTEImage(); SetupRegions(); TEeditmode=EDDRAW; // Default to drawing mode if (TEbitflags&TESHOWMSK) TEbitflags^=TESHOWMSK; while (!(TEbitflags&TEQUITCUR)) { // Mouse button click handler routines MBClickHandler(TEregs); TEbfa=BFANONE; // Reset button action flag if (TEeditmode==EDMASK && TEoldeditmode!=EDMASK) TEbitflags|=TESHOWMSK; if (TEeditmode==EDMASK && TEoldeditmode==EDMASK && !(TEbitflags&TESHOWMSK)) TEeditmode=EDDRAW; TEoldeditmode=TEeditmode; // Draw loop RenderTileEdit(TEregs); DrawMouse(); ShowPage(); if (key[SCAN_ESC]) { key[SCAN_ESC]=0; TEbitflags|=TEQUITCUR; } if ((key[SCAN_CTRL] && key[SCAN_Z]) || (TEbfa&BFAUNDO) || (key[SCAN_U] && !(key[SCAN_CTRL])) && ((MBStatus[0]|MBStatus[1])==MOUSENONE)) { key[SCAN_U]=0; key[SCAN_Z]=0; TEUndo(); } if (key[SCAN_CTRL] && key[SCAN_R]) { key[SCAN_R]=0; memcpy(TEundo, TEimage, TExsize*TEysize); // copy image into undo buffer memcpy(TEimage, TEsource, TExsize*TEysize); // copy original image into edit buffer } if (key[SCAN_CTRL] && key[SCAN_A]) { key[SCAN_A]=0; j=TEysize*TExsize; memset(TEmask, 0xf, j); } if (key[SCAN_CTRL] && key[SCAN_U]) { key[SCAN_U]=0; j=TEysize*TExsize; memset(TEmask, 0x0, j); } if ((TEbfa&BFACOPY) || (key[SCAN_CTRL] && key[SCAN_C]) && ((MBStatus[0]|MBStatus[1])==MOUSENONE)) { key[SCAN_C]=0; TECopyImage(); } if ((TEbfa&BFACUT) || (key[SCAN_CTRL] && key[SCAN_X]) && ((MBStatus[0]|MBStatus[1])==MOUSENONE)) { key[SCAN_X]=0; TECopyImage(); TEClearImage(); } if (key[SCAN_CTRL] && key[SCAN_V] && ((MBStatus[0]|MBStatus[1])==MOUSENONE)) { key[SCAN_V]=0; TEeditmode=EDPASTE; } if ((TEbfa&BFACLEAR) || key[SCAN_DEL] && ((MBStatus[0]|MBStatus[1])==MOUSENONE)) { key[SCAN_DEL]=0; TEClearImage(); } if (key[SCAN_Q] && ((MBStatus[0]|MBStatus[1])==MOUSENONE)) { key[SCAN_Q]=0; if (TEtype==TETILE && TEanimstrand) { if (TEtile>vspanim[TEanimstrand-1].start) { // Change tile index TEtile-=1; i=TExsize; j=TEysize; // Restart editor RestartTileEditor(); } } } if (key[SCAN_W] && ((MBStatus[0]|MBStatus[1])==MOUSENONE)) { key[SCAN_W]=0; if (TEtype==TETILE && TEanimstrand) { if (TEtile0); } if (key[SCAN_M]) { key[SCAN_M]=0; if (TEeditmode==EDMASK) TEeditmode=EDDRAW; TEbitflags^=TESHOWMSK; } if (key[SCAN_SPACE]) { key[SCAN_SPACE]=0; if (TEeditmode==EDDRAW) { TEeditmode=EDMASK; TEbitflags|=TESHOWMSK; } else TEeditmode=EDDRAW; } if (key[SCAN_PGUP]) { key[SCAN_PGUP]=0; switch (TEeditmode) { case EDDRAW: case EDMASK: memcpy(TEundo, TEimage, TExsize*TEysize); if (TEbitflags&TESHOWMSK) TEShiftColours(TEimage, TEmask, TExsize, TEysize, 1); else TEShiftColours(TEimage, NULL, TExsize, TEysize, 1); break; case EDPASTE: if (TEcopy) TEShiftColours(TEcopy, TEcmsk, TEcopyxsize, TEcopyysize, 1); break; } } if (key[SCAN_PGDN]) { key[SCAN_PGDN]=0; switch (TEeditmode) { case EDDRAW: case EDMASK: memcpy(TEundo, TEimage, TExsize*TEysize); if (TEbitflags&TESHOWMSK) TEShiftColours(TEimage, TEmask, TExsize, TEysize, -1); else TEShiftColours(TEimage, NULL, TExsize, TEysize, -1); break; case EDPASTE: if (TEcopy) TEShiftColours(TEcopy, TEcmsk, TEcopyxsize, TEcopyysize, -1); break; } } if (key[SCAN_LANGLE]) { key[SCAN_LANGLE]=0; ShutdownVideo(); TEFreeReg(TEregs); vm=0; InitVideo(0); SetupRegions(); set_intensity(63); InitMouse(); } if (key[SCAN_RANGLE]) { key[SCAN_RANGLE]=0; ShutdownVideo(); TEFreeReg(TEregs); vm=1; InitVideo(1); SetupRegions(); set_intensity(63); InitMouse(); } } DeinitTEImage(); TEFreeReg(TEregs); }