home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
269.lha
/
MelaniePaint_v.60
/
sources
/
mpaint.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-07-16
|
21KB
|
746 lines
/*============================================================================*/
/* MPaint.c: by Kevin T. Seghetti */
/* Simple paint program, main module */
/*============================================================================*/
/*============================================================================*/
/* includes */
/*============================================================================*/
#include "equates.h"
#include <functions.h>
#include <exec/types.h>
#include <intuition/intuition.h>
#include <graphics/gfx.h>
#include "iff/jiff.h"
/*============================================================================*/
/* external declarations */
/*============================================================================*/
extern void HandleMenu(),DrawContLine(),(*DrawRoutineList[])();
extern long ForeColor,BackColor,OutlineColor,DrawMode;
extern FLAG noUndo;
extern char Crd[20];
extern struct IntuiText *CoordIntuiText;
extern struct Remember *MenuRemember;
/*============================================================================*/
/* Global Variable declarations */
/*============================================================================*/
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Screen *MPaintScreen = NULL;
struct Window *MPaintWindow = NULL,*ToolWindow = NULL,*PaletteWindow = NULL,*HistWindow = NULL,*CoordWindow = NULL;
struct RastPort *VRastPort = NULL;
struct Menu *MPaintMenu;
struct Remember *ToolRemember,*PaletteRemember,*HistRemember,*CoordRemember;
struct ILBM_info *info;
struct RastPort UndoRastPort;
struct BitMap UndoBitMap;
int i,CurrWindow,GridX,GridY,MaxColor,PaletteColorMode,Function_DrawMode;
SHORT mx,my,PaintWidth,PaintHeight;
FLAG Continue,SelectDown,UndoBuffer = FALSE,PropGadgDown = FALSE,Grid = FALSE,ChoosingBackColor = FALSE,PatternOn = FALSE;
UBYTE *TempPlane = 0;
UWORD *ColorPTR,CurrGadg;
ULONG Class,Code,Qualifier;
void (*DrawRoutine)();
struct Gadget *GadgetPTR;
struct TmpRas myTmpRas;
struct Gadget *OldGadget = 0;
struct PropInfo *TempProp;
struct Gadget *TempGadget;
UWORD areabuffer[250];
struct AreaInfo myAreaInfo;
USHORT areaPattern[] =
{
0xaaaa,
0x5555
};
/*============================================================================*/
/* default colors */
/*============================================================================*/
UWORD colortable[32] =
{
0,0xfff,0xf00,0x0f0,0x00f,0xff0,0x0ff,0xf0f,
0x8a8,0xa88,0x080,0x008,0x888,0x808,0x088,0x880,
0xeee,0xddd,0xccc,0xbbb,0xaaa,0x999,0x888,0x777,
0x666,0x555,0x444,0x333,0x222,0x111,0x000,0x00f
};
/*============================================================================*/
/* Initial Screen Definition */
/*============================================================================*/
struct NewScreen NewMPaintScreen =
{
0,0,320,200,5, /* leftedge, topedge, width, height, depth */
0,1, /* detail and block pens */
NULL, /* Viewmodes */
CUSTOMSCREEN, /* screen type */
NULL, /* font pointer */
(UBYTE *)"MPaint Screen", /* screen title */
NULL, /* pointer to screen gadgets */
NULL /* custom bitmap pointer */
};
/*============================================================================*/
/* Return palette settings to default */
/*============================================================================*/
RestorePalette()
{
int i;
if(ColorPTR)
for(i=0;i<32;i++)
ColorPTR[i] = colortable[i];
}
/*============================================================================*/
/* free a set of bitplanes */
/*============================================================================*/
void
myfree_planes(bmap)
register struct BitMap *bmap;
{
PLANEPTR plane;
long length;
short i;
length = bmap->BytesPerRow * bmap->Rows;
for (i=0; i<bmap->Depth; i++)
if ( (plane = bmap->Planes[i]) != NULL)
{
rfree(plane, length);
bmap->Planes[i] = NULL;
}
}
/*============================================================================*/
/* cleanup: Program finished, time to free all memory and resources */
/*============================================================================*/
cleanup(text,err)
char *text;
int err;
{
if(text)
DoAutoRequest(MPaintWindow,text,NULL,"Ok");
if(MPaintWindow)
{
ClearMenuStrip(MPaintWindow);
CloseWindow(MPaintWindow);
}
if(ToolWindow)
CloseToolWindow();
if(PaletteWindow)
ClosePaletteWindow();
if(HistWindow)
CloseHistWindow();
if(CoordWindow)
CloseCoordWindow();
if(UndoBuffer)
{
myfree_planes( UndoRastPort.BitMap);
}
DeleteAllPages();
CloseVScreen();
if(GfxBase)
CloseLibrary(GfxBase);
if(IntuitionBase)
CloseLibrary(IntuitionBase);
if(MenuRemember)
FreeRemember(&MenuRemember,(long)TRUE);
if(TempPlane)
FreeRaster(TempPlane,(long)PaintWidth,(long)PaintHeight);
exit(err);
}
/*============================================================================*/
/* Open all libraries we will use */
/*============================================================================*/
OpenLibrarys()
{
IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",REVISION);
if(!IntuitionBase)
cleanup("Cannot Open Intuition Library",ERR_NOLIB);
GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",REVISION);
if(!GfxBase)
cleanup("Cannot Open Graphics Library",ERR_NOLIB);
}
/*----------------------------------------------------------------------------*/
InitVScreen()
{
MPaintScreen = OpenScreen(&NewMPaintScreen);
if(!MPaintScreen)
cleanup("Cannot open custom screen",5);
MaxColor = 32;
PaintWidth = 320;
PaintHeight = 200;
ColorPTR = AllocMem((long)sizeof(UWORD[32]),NULL);
if(!ColorPTR)
cleanup("not enough memory");
RestorePalette();
LoadRGB4(&MPaintScreen->ViewPort,ColorPTR,32L);
}
/*============================================================================*/
CloseVScreen()
{
if(MPaintScreen)
CloseScreen(MPaintScreen);
if(ColorPTR)
FreeMem(ColorPTR,(long)sizeof(UWORD[32]));
}
/*============================================================================*/
InitTempPlane()
{
TempPlane = AllocRaster((long)PaintWidth,(long)PaintHeight);
if(!TempPlane)
cleanup("no memory for TmpRas",ERR_NOMEM);
InitTmpRas(&myTmpRas,TempPlane,(long)(PaintWidth/8)*PaintHeight);
VRastPort->TmpRas = &myTmpRas;
InitArea(&myAreaInfo,areabuffer, 100L);
VRastPort->AreaInfo=&myAreaInfo;
}
/*============================================================================*/
InitDefaults()
{
ForeColor = 1;
SetAPen(VRastPort,(long)ForeColor);
DrawRoutine = DrawContLine;
DrawMode = JAM2;
Function_DrawMode = JAM2;
SelectDown = FALSE;
PaletteColorMode = COLORMODE_NORMAL;
GridX = 10;
GridY = 10;
}
/*============================================================================*/
InitUndoBuffer()
{
long Depth;
Depth = Num2Bit((long)MaxColor);
InitRastPort(&UndoRastPort);
UndoRastPort.Mask = (1<<Depth)-1;
InitBitMap(&UndoBitMap,Depth,(long)PaintWidth,(long)PaintHeight);
UndoRastPort.BitMap = &UndoBitMap;
for (i=0; i<Depth; i++)
if ((UndoRastPort.BitMap->Planes[i] = ralloc(PaintWidth*(PaintHeight/8))) == NULL)
{
myfree_planes( UndoRastPort.BitMap );
UndoBuffer = FALSE;
return();
}
UndoBuffer = TRUE;
noUndo = FALSE;
SaveToUndoBuffer();
}
/*============================================================================*/
/* put_ea_cmap: convert IFF colormap to Amiga colormap */
/*============================================================================*/
/*put_ea_cmap given an ea-type color map:
an array of unsigned chars of form ea_cmap[] = {r, g, b, r, g, b...}
turn it into an amiga-type color map:
an array of unsigned short of form amiga_cmap = {0xrgb, 0xrgb, ...}
and then tell Dale this is the colors we want for our viewport */
void
put_ea_cmap(cmap, colors)
unsigned char *cmap;
int colors;
{
unsigned short amy_cmap[MAXCOL];
int i;
unsigned char r, g, b;
if (colors > MAXCOL) /*color clipping*/
colors = MAXCOL;
for (i=0; i<colors; i++)
{
amy_cmap[i] =
((cmap[0] & 0xf0) << 4) + (cmap[1] & 0xf0) + ((cmap[2] & 0xf0) >> 4);
cmap += 3;
}
LoadRGB4( &MPaintScreen->ViewPort, amy_cmap, (long)colors);
for(i=0;i<colors;i++)
{
ColorPTR[i] = amy_cmap[i];
}
}
/*============================================================================*/
/* ConvertToDecimal: this is MUCH faster than using sprintf */
/*============================================================================*/
ConvertToDecimal(text,num)
char *text;
int num;
{
int temp;
temp = '0';
while(num>99)
{ num -=100;
temp+=1;
}
*text++ = temp;
temp = '0';
while(num>9)
{ num -=10;
temp+=1;
}
*text++ = temp;
*text = num + '0';
}
/*============================================================================*/
/* UpdateCoordinates: Print the current mouse coordinates in coord window */
/*============================================================================*/
UpdateCoordinates()
{
if(CoordWindow)
{
ConvertToDecimal(Crd,MPaintScreen->MouseX);
Crd[3] = ',';
ConvertToDecimal(&Crd[4],MPaintScreen->MouseY);
Crd[7] = 0;
PrintIText(CoordWindow->RPort,CoordIntuiText,5L,12L);
}
}
/*============================================================================*/
/* Dispatch:all drawing operations are called from here */
/*============================================================================*/
Dispatch()
{
if(Grid)
{
mx = (int)(mx/GridX) * GridX;
my = (int)(my/GridY) * GridY;
}
if(CoordWindow)
UpdateCoordinates();
if(Class == MOUSEBUTTONS && Code == SELECTDOWN)
SaveToUndoBuffer();
(*DrawRoutine)();
}
/*============================================================================*/
/* converts a proportional value to a # between 0 and 15 */
/*============================================================================*/
USHORT PotConvert16(value)
USHORT value;
{ return(15 - (value/(0xFFFF/15)));
}
/*============================================================================*/
/* converts a # between 0 & 15 to a proportional value */
/*============================================================================*/
USHORT ConvertToPot16(value)
USHORT value;
{ return((15 - value) * (0xffff/15));
}
/*============================================================================*/
/* search a GList for a particular gadget */
/*============================================================================*/
struct Gadget *
FindGadget(GList,GadgetID)
struct Gadget *GList;
USHORT GadgetID;
{
while(GList->GadgetID != GadgetID && GList->NextGadget != 0)
GList = GList->NextGadget;
return(GList);
}
/*============================================================================*/
/* This is where all input events are parsed */
/* menu choices are handled in "menuparse.c" */
/*============================================================================*/
HandleInput(message)
struct IntuiMessage *message;
{
UWORD TempColor,NewColor;
struct StringInfo *TempString;
if(message)
{
Class=message->Class;
Code=message->Code;
Qualifier=message->Qualifier;
mx=message->MouseX;
my=message->MouseY;
GadgetPTR = (struct Gadget *)message->IAddress;
ReplyMsg(message);
}
if(CoordWindow)
UpdateCoordinates();
switch(Class)
{ case MOUSEMOVE:
switch(CurrWindow)
{
case WINDOW_PAINT:
Dispatch();
break;
case WINDOW_PALETTE:
if(PropGadgDown)
UpdateColor();
break;
}
break;
case MOUSEBUTTONS:
switch(Code)
{ case SELECTDOWN:
SelectDown = TRUE;
Dispatch();
break;
case SELECTUP:
SelectDown = FALSE;
Dispatch();
if(Function_DrawMode == DRAWMODE_CYCLE)
UpdatePropGadgets();
break;
}
break;
case MENUPICK:
HandleMenu(Code);
break;
case CLOSEWINDOW:
if(CurrWindow == WINDOW_TOOLS)
CloseToolWindow();
else if(CurrWindow == WINDOW_PALETTE)
ClosePaletteWindow();
else if(CurrWindow == WINDOW_HIST)
CloseHistWindow();
if(CurrWindow == WINDOW_COORD)
CloseCoordWindow();
break;
case GADGETDOWN:
if(CurrWindow == WINDOW_PALETTE)
if(GadgetPTR->SpecialInfo)
{
TempProp = (struct PropInfo *)GadgetPTR->SpecialInfo;
CurrGadg = GadgetPTR->GadgetID;
PropGadgDown = TRUE;
}
break;
case GADGETUP:
if(CurrWindow == WINDOW_TOOLS)
{
if(GadgetPTR->GadgetID >= TOOL_GADG_START)
DrawRoutine = DrawRoutineList[GadgetPTR->GadgetID-TOOL_GADG_START];
else if(GadgetPTR->GadgetID < 32 /*&& ToolWindow*/)
{ if(ChoosingBackColor)
{
SetBackColor((long)GadgetPTR->GadgetID);
}
else
SetForeColor((long)GadgetPTR->GadgetID);
}
else if(GadgetPTR->GadgetID == TOOL_GADG_UNDO)
DoUndo();
else if(GadgetPTR->GadgetID == TOOL_GADG_BACK)
ChoosingBackColor = GadgetPTR->Flags & SELECTED;
else if(GadgetPTR->GadgetID == TOOL_GADG_PATTERN)
{
if(GadgetPTR->Flags & SELECTED)
{
PatternOn = TRUE;
SetAfPt(VRastPort,&areaPattern[0],1L);
}
else
{
PatternOn = FALSE;
SetAfPt(VRastPort,0L,0L);
}
}
}
if(CurrWindow == WINDOW_COORD)
{
switch(GadgetPTR->GadgetID)
{
case COORD_GADG_GRID:
if(GadgetPTR->Flags & SELECTED)
Grid = TRUE;
else Grid = FALSE;
break;
case COORD_GADG_GRIDX:
TempString = (struct StringInfo *)GadgetPTR->SpecialInfo;
if(TempString->LongInt < 1 || TempString->LongInt > PaintWidth)
DoAutoRequest(MPaintWindow,"Invalid Entry, Try again",NULL,"Ok");
else GridX = TempString->LongInt;
break;
case COORD_GADG_GRIDY:
TempString = (struct StringInfo *)GadgetPTR->SpecialInfo;
if(TempString->LongInt < 1 || TempString->LongInt > PaintWidth)
DoAutoRequest(MPaintWindow,"Invalid Entry, Try again",NULL,"Ok");
else GridY = TempString->LongInt;
break;
}
}
if(CurrWindow == WINDOW_PALETTE)
{
PropGadgDown = FALSE;
if(GadgetPTR->GadgetID >= PALETTE_GADG_START && GadgetPTR->GadgetID <= PALETTE_GADG_PROP_BLUE)
{
SetScreenTitle("MPaint");
PaletteColorMode = COLORMODE_NORMAL;
TempColor = ColorPTR[ForeColor];
switch(GadgetPTR->GadgetID)
{
case PALETTE_GADG_RED_PLUS2:
for(i=0;i<MaxColor;++i)
ColorPTR[i] = Palette_IncRed(ColorPTR[i]);
UpdatePropGadgets();
break;
case PALETTE_GADG_GREEN_PLUS2:
for(i=0;i<MaxColor;++i)
ColorPTR[i] = Palette_IncGreen(ColorPTR[i]);
UpdatePropGadgets();
break;
case PALETTE_GADG_BLUE_PLUS2:
for(i=0;i<MaxColor;++i)
ColorPTR[i] = Palette_IncBlue(ColorPTR[i]);
UpdatePropGadgets();
break;
case PALETTE_GADG_RED_MINUS2:
for(i=0;i<MaxColor;++i)
ColorPTR[i] = Palette_DecRed(ColorPTR[i]);
UpdatePropGadgets();
break;
case PALETTE_GADG_GREEN_MINUS2:
for(i=0;i<MaxColor;++i)
ColorPTR[i] = Palette_DecGreen(ColorPTR[i]);
UpdatePropGadgets();
break;
case PALETTE_GADG_BLUE_MINUS2:
for(i=0;i<MaxColor;++i)
ColorPTR[i] = Palette_DecBlue(ColorPTR[i]);
UpdatePropGadgets();
break;
case PALETTE_GADG_PROP_RED:
TempProp = (struct PropInfo *)GadgetPTR->SpecialInfo;
ColorPTR[ForeColor] = Palette_SetRed(ColorPTR[ForeColor],PotConvert16(TempProp->VertPot));
UpdatePropGadgets();
break;
case PALETTE_GADG_PROP_GREEN:
TempProp = (struct PropInfo *)GadgetPTR->SpecialInfo;
ColorPTR[ForeColor] = Palette_SetGreen(ColorPTR[ForeColor],PotConvert16(TempProp->VertPot));
UpdatePropGadgets();
break;
case PALETTE_GADG_PROP_BLUE:
TempProp = (struct PropInfo *)GadgetPTR->SpecialInfo;
ColorPTR[ForeColor] = Palette_SetBlue(ColorPTR[ForeColor],PotConvert16(TempProp->VertPot));
UpdatePropGadgets();
break;
}
LoadRGB4(&MPaintScreen->ViewPort,ColorPTR,MaxColor);
}
else if(GadgetPTR->GadgetID < 32 && PaletteWindow)
switch(PaletteColorMode)
{
case COLORMODE_NORMAL:
SetForeColor((long)GadgetPTR->GadgetID);
break;
case COLORMODE_COPY:
ColorPTR[GadgetPTR->GadgetID] = ColorPTR[ForeColor];
SetScreenTitle("MPaint");
PaletteColorMode = COLORMODE_NORMAL;
LoadRGB4(&MPaintScreen->ViewPort,ColorPTR,MaxColor);
break;
case COLORMODE_EXCHNG:
TempColor = ColorPTR[ForeColor];
ColorPTR[ForeColor]= ColorPTR[GadgetPTR->GadgetID];
ColorPTR[GadgetPTR->GadgetID] = TempColor;
SetScreenTitle("MPaint");
PaletteColorMode = COLORMODE_NORMAL;
LoadRGB4(&MPaintScreen->ViewPort,ColorPTR,MaxColor);
break;
}
else if(GadgetPTR->GadgetID == PALETTE_GADG_COPY)
{
SetScreenTitle("Choose color to copy to");
PaletteColorMode = COLORMODE_COPY;
}
else if(GadgetPTR->GadgetID == PALETTE_GADG_EXCHNG)
{
SetScreenTitle("Choose color to exchange with");
PaletteColorMode = COLORMODE_EXCHNG;
}
}
break;
}
}
/*============================================================================*/
HandlePaintWindowInput()
{
struct IntuiMessage *message;
CurrWindow = WINDOW_PAINT;
while ((message = (struct IntuiMessage *)GetMsg(MPaintWindow->UserPort)) != NULL)
{
if(message->Class == MOUSEMOVE)
{
while(message->Class == MOUSEMOVE)
{
mx=message->MouseX;
my=message->MouseY;
ReplyMsg(message);
message = (struct IntuiMessage *)GetMsg(MPaintWindow->UserPort);
if(message == NULL)
{
Class = MOUSEMOVE;
HandleInput(NULL);
break;
}
}
}
HandleInput(message);
}
}
/*============================================================================*/
/* Main entry point of program */
/* First will initialize everything, then will load file if name specified, */
/* then enter main loop */
/*============================================================================*/
main(argc,argv)
int argc;
char *argv[];
{
int x,y,color,Result;
struct IntuiMessage *message;
long WaitBits;
MenuRemember = NULL;
OpenLibrarys();
InitVScreen();
InitMenus();
InitWindow();
InitUndoBuffer();
VRastPort = MPaintWindow->RPort;
InitTempPlane(); /* for area and flood operations */
InitDefaults(); /* setup default configuration */
if(argc > 1) /* if command line filename,*/
MIFFLoad(argv[1]); /* load it */
Continue = TRUE;
while(Continue)
{
WaitBits = (1L<<MPaintWindow->UserPort->mp_SigBit);
if(ToolWindow)
WaitBits |=(1L<<ToolWindow->UserPort->mp_SigBit);
if(PaletteWindow)
WaitBits |=(1L<<PaletteWindow->UserPort->mp_SigBit);
if(HistWindow)
WaitBits |=(1L<<HistWindow->UserPort->mp_SigBit);
if(CoordWindow)
WaitBits |=(1L<<CoordWindow->UserPort->mp_SigBit);
Wait(WaitBits);
HandlePaintWindowInput();
if(ToolWindow)
while ((message = (struct IntuiMessage *)GetMsg(ToolWindow->UserPort)) != NULL)
{
CurrWindow = WINDOW_TOOLS;
HandleInput(message);
if(!ToolWindow)
break;
}
if(PaletteWindow)
while ((message = (struct IntuiMessage *)GetMsg(PaletteWindow->UserPort)) != NULL)
{
CurrWindow = WINDOW_PALETTE;
HandleInput(message);
if(!PaletteWindow)
break;
}
if(HistWindow)
while ((message = (struct IntuiMessage *)GetMsg(HistWindow->UserPort)) != NULL)
{
CurrWindow = WINDOW_HIST;
HandleInput(message);
if(!HistWindow)
break;
}
if(CoordWindow)
while ((message = (struct IntuiMessage *)GetMsg(CoordWindow->UserPort)) != NULL)
{
CurrWindow = WINDOW_COORD;
HandleInput(message);
if(!CoordWindow)
break;
}
}
cleanup(NULL,0); /* user quit, time to cleanup */
}
/*============================================================================*/
/* end of MPaint.c */
/*============================================================================*/