'Mini Paint - A demonstration paint program for OZAmiga Magazine ' AMOS Tutorial #3. ' By Neil McKnight 1993 - may be freely distributed. 'Special features: ' - Easy to use, mouse operated. ' - A variety of simple drawing tools. ' - Save and Load your pictures. ' - DPaint type "brush" drawing. ' - UNDO that undoes right back to last drawing tool change. 'Storage for the control panel, so we can see the selected drawing mode. Dim Z(15,3) 'Make these global to all procedures as we will use them alot. Global X1,Y1,X2,Y2,Z() 'Create the control panel from a spacked screen. ' This will also set up the default palette for us. Unpack 10 To 0 Screen Display 0,,265,, 'Set up zones for the draw mode controls. Eg Line, Box etc. ' I used DATA statements rather than calculating them because the ' calculations can be rather confusing if you don't know what's going on. ' NOTE: the palette zones are set up in SET_PALETTE Restore CONTROL_ZONE_DATA Read NUMBER_CONTROLS Reserve Zone NUMBER_CONTROLS+32 'I read in a string called GUFF$ which just lets me know what peice of data ' is for which button. Look at the DATA statements. For L=1 To NUMBER_CONTROLS Read GUFF$,Z(L,0),Z(L,1),Z(L,2),Z(L,3) Set Zone L+32,Z(L,0),Z(L,1) To Z(L,2),Z(L,3) Next 'Set up undo screen as another screen identical to the drawing screen. ' I then copy the entire drawing screen to the undo screen whenever ' you change drawing modes. This means you have control over where ' you UNDO to. It's not the most memory efficient method, but I wrote ' this at one sitting... Screen Open 3,320,256,32,Lowres Flash Off : Curs Off Get Palette 0 Cls 0 Screen Hide 'Set up drawing screen. We have to go through the same sequence as for ' the Undo screen. A simple SCREEN COPY won't work. Screen Open 1,320,256,32,Lowres Flash Off : Curs Off Get Palette 0 Paper 0 : Pen 1 Cls Screen To Back 'Setting up. 'We make sure the mouse is free to roam the entire screen. ' NOTE: If you don't call Wait Vbl before Limit Mouse it is not always ' reliable... Wait Vbl Limit Mouse 'Show the current palette. SEE_PALETTE[2] 'Say hello. Gosub HELLO 'Set the starting draw mode to DRAW FREEHAND and highlight it. COMMAND=3 OLD_COMMAND=COMMAND SEE_CONTROL[COMMAND] 'The main loop. ' Here we process the users selection, branching off to a different ' subroutine for each item. Only the colour selection and a few ' "kludges" are present in this loop. A "Kludge" is something the ' programmer does to make a certain function work correctly when the ' normal method causes problems. ' This loop will repeat until the user clicks the logo on the control ' panel. This is the quit button. QUIT=False Repeat 'Wait for a mouse click. CLICK 'Go to the control panel screen and find out if a button is clicked on. Screen 0 MZ=Mouse Zone 'The lowest 32 buttons are the colour selections. This makes life ' easier to work out what colour they want. If MZ>0 and MZ<33 'A Colour was selected! Make it the current colour. SEE_PALETTE[MZ-1] 'Kludge #1 - FILL tried to fill the entire screen if you changed ' colours while in fill mode. This stops it. If OLD_COMMAND=2 : OLD_COMMAND=0 : End If End If If MZ>32 'A Command was selected! Work out which one and highlight it. COMMAND=MZ-32 SEE_CONTROL[COMMAND] 'Copy the drawing screen to the Undo screen when the drawing ' command changes. Except if UNDO was selected of course... If COMMAND<>13 Screen Copy 1 To 3 'Kludge #2 - set a flag so that undo only works once. UNDONE=False End If End If 'Jump to the drawing screen and do something! Screen 1 On COMMAND Gosub USE_LINE,USE_FILL,USE_DRAW,USE_DOTTY,USE_CIRCLE,USE_ELLIPSE,USE_BOX,USE_BAR,USE_GRAB,USE_TEXT,PIC_LOAD,PIC_SAVE,PIC_UNDO,PIC_CLEAR,ENABLE_QUIT 'Remember what it was we just did (see Kludges) OLD_COMMAND=COMMAND Until QUIT End 'LINE tool - draws rays originating from the start point. ' Note the mouse coord -> screen coord conversion. USE_LINE: X1=X Screen(X Mouse) : Y1=Y Screen(Y Mouse) Repeat Draw X1,Y1 To X Screen(X Mouse),Y Screen(Y Mouse) Wait Vbl Until Mouse Key=0 Return 'FILL tool - fills an enclosed area with current drawing colour. ' Kludge #3 - the first fill has an extra mouse click added so it ' doesn't try to fill the entire screen before you click somewhere. ' This means you should select the fill colour, BEFORE selecting the ' Fill tool. The routine expects the first click to select the area ' to fill. ' Otherwise, the area under the palette selection will be filled, ' and you will need to Undo it. ' You can change colours as much as you like between fills. USE_FILL: If OLD_COMMAND<>2 Then CLICK Paint X Screen(X Mouse),Y Screen(Y Mouse) Return 'FREEHAND DRAW tool - lets you draw wiggly lines all over the screen. ' The Plot is where you click. Note the Wait Vbl instruction. It is ' needed to slow down the loop so things have time to update correctly. USE_DRAW: Plot X Screen(X Mouse),Y Screen(Y Mouse) Repeat Draw To X Screen(X Mouse),Y Screen(Y Mouse) Wait Vbl Until Mouse Key=0 Return 'DOTTY DRAW tool - like Freehand Draw, but draws dots. USE_DOTTY: Repeat Plot X Screen(X Mouse),Y Screen(Y Mouse) Wait Vbl Until Mouse Key=0 Return 'CIRCLE tool - calls Rubber_Box to find out where you want to put it, ' then works out where the centre goes and starts from there. ' The diameter is taken as the largest measurement of the box. USE_CIRCLE: RUBBER_BOX XX=(X2-X1)/2 : YY=(Y2-Y1)/2 Circle X1+XX,Y1+YY,Max(XX,YY)+1 Return 'ELLIPSE tool - work just like Circle, but makes the ellipse fit inside ' the Rubber Box. USE_ELLIPSE: RUBBER_BOX XX=(X2-X1)/2 : YY=(Y2-Y1)/2 Ellipse X1+XX,Y1+YY,XX+1,YY+1 Return 'HOLLOW BOX tool - Uses Rubber Box to determine the position and size of ' the box, then draws one there. USE_BOX: RUBBER_BOX Box X1,Y1 To X2,Y2 Return 'FILLED BOX tool - same as Hollow Box, but uses Bar command. USE_BAR: RUBBER_BOX Bar X1,Y1 To X2,Y2 Return 'BRUSH tool - a la Deluxe Paint brushes. Select an area of the screen ' using a Rubber Box, then draw with it. Uses bob commands. ' Hot Spot sets the "handle" to the middle of the area. ' Put Bob is the command that stamps the image onto the drawing screen. ' It would be simple to convert this to remember a number of different ' brushes instead of just one. ' NOTE: turn this off by pressing the RIGHT mouse button. USE_GRAB: RUBBER_BOX Get Bob 1,X1,Y1 To X2,Y2 Hot Spot 1,$11 Repeat Repeat Bob 1,X Screen(X Mouse),Y Screen(Y Mouse),1 Wait Vbl MK=Mouse Key Until MK<>0 If MK=1 Then Put Bob 1 Until MK=2 Bob Off 1 Return 'TEXT tool - type some text, then place it on the screen. ' This uses Gr Writing to change the drawing mode so that the ' background of the text is transparent. USE_TEXT: 'Open a tiny screen for inputting the text. Screen Open 2,640,10,2,Hires Screen Display 2,,140,, Palette $9,$FFF Input At(10,)+"Enter Text: ";A$ Screen Close 2 'Find position, then print it. RUBBER_BOX Gr Writing 0 Text X1,Y1+7,A$ Gr Writing 1 Return 'LOAD tool - loads any IFF picture onto the drawing screen. ' NOTE: although you can load any picture and view it, none of the ' drawing routines have any way of detecting the change in screen ' size, depth or mode. This means that only 320 x 256 x 32 colour ' screens have been catered for. ' However, the correct palette will be displayed. ' Sorry, but this IS only an example... PIC_LOAD: FILE$=Fsel$("","","Load A Picture...") If FILE$>"" If Exist(FILE$) Load Iff FILE$,1 Screen To Back SEE_PALETTE[HUE] COMMAND=3 End If End If Return 'SAVE tool - save your masterpeice as a standard IFF picture. ' This is what Load was meant to read... PIC_SAVE: FILE$=Fsel$("","","Save Picture As...") If FILE$>"" Screen 1 Save Iff FILE$ Screen 0 End If Return 'UNDO tool - returns the screen back to how it was before you last ' changed drawing mode. This means if you draw three lines, then ten ' circles, then hit Undo, ALL the circles will disappear. ' You can force Undo to remember only after a particular point simply ' by changing drawing modes. ' NOTE: the UNDONE flag is so undo cannot be triggered more than once. PIC_UNDO: If Not UNDONE Screen Copy 3 To 1 UNDONE=True End If Return 'CLEAR tool - clears the screen back to colour 0. ' Sorry, there is no way to Clear to another colour (unless you add it). PIC_CLEAR: Screen 1 Cls Return 'QUIT tool - the user wants to quit, so let them. ' Sorry, there is no confirm. Add one here. ENABLE_QUIT: QUIT=True Return 'Title Messages - for startup. ' Reads DATA statements, displays them on the screen, then waits for ' a mouse click or keypress. HELLO: Restore HELP_DATA Read NL Screen 1 P=1 For L=1 To NL Read A$ If A$>"" Inc P Centre At(,L*2+1)+Pen$(P)+A$ End If Next Repeat : Multi Wait : Until Mouse Key>0 or(Inkey$>"") Cls Return 'Data for the various drawing tools. ' These define the areas of the screen to be set up as "zones" so we can ' simulate some sort of button. ' The strings are just so we know what each set of numbers is for. CONTROL_ZONE_DATA: Data 15 Data "Line",0,2,23,17 Data "Fill",0,18,23,33 Data "Draw",24,2,47,17 Data "Dotty",24,18,47,33 Data "Circle",48,2,71,17 Data "Ellipse",48,18,71,33 Data "Box",72,2,95,17 Data "Bar",72,18,95,33 Data "Grab",96,2,119,17 Data "Text",96,18,119,33 Data "Load",248,2,271,17 Data "Save",248,18,271,33 Data "Undo",272,2,295,17 Data "Clear",272,18,295,33 Data "Quit",296,2,319,33 'Data for the startup messages. HELP_DATA: Data 10 Data "M I N I P A I N T","","A Demonstration Program" Data "for OZAmiga AMOS Tutoral #3.","" Data "By Neil McKnight 1993","" Data "May be freely distributed.","" Data "Click on logo to quit." 'Displays the palette area of the control panel. ' It also sets up the selection zones for each colour and highlights ' the current drawing colour. Procedure SEE_PALETTE[HUE] 'Go to control panel and load the palette of the drawing screen. Screen 0 Get Palette 1 'Draw a sample of each colour. For L=0 To 31 'Work out the coordinated of the colour sample. X1=120+(L mod 16)*8 Y1=2-(L>15)*16 X2=X1+7 : Y2=Y1+15 'Put a selection zone around it. Set Zone L+1,X1,Y1 To X2,Y2 'Draw a small box of that colour as a sample. Ink L Bar X1+2,Y1+2 To X2-2,Y2-2 'If it's to be the new drawing colour, highlight it, then set it ' as the Current drawing coloiur on the drawing screen. If L=HUE Ink 0 Box X1+2,Y1+2 To X2-2,Y2-2 Screen 1 Ink HUE Screen 0 End If Next End Proc 'Allows the user to select an area of the screen of variable size and ' position, without disturbing the background underneath. ' Return the coordinates of the area to the drawing routines. Procedure RUBBER_BOX 'Go to the drawing screen and wait until the user lets go of the ' mouse buttons. Screen 1 Repeat : Multi Wait : Until Mouse Key=0 'Set the drawing mode to Exclusive OR - eg. lines are draw in such a ' way that the backgound can be returned to normal by redrawing the ' same line in the same place a second time. Gr Writing 2 'Draw a set of cross hairs to the mouse position. X1=X Screen(X Mouse) : Y1=Y Screen(Y Mouse) OX=X1 : OY=Y1 Draw OX,0 To OX,256 Draw 0,OY To 640,OY 'Track the mouse until the starting position is selected. Repeat X1=X Screen(X Mouse) : Y1=Y Screen(Y Mouse) 'Only redraw the lines if the mouse has moved. If OX<>X1 or OY<>Y1 'Redraw the OLD lines first to erase them. Draw OX,0 To OX,256 Draw 0,OY To 640,OY 'Then draw lines for the current position. Draw X1,0 To X1,256 Draw 0,Y1 To 640,Y1 End If 'Remember the current position for later. OX=X1 : OY=Y1 Wait Vbl Until Mouse Key=1 'User has click where the area is to start, so erase the cross hairs. Draw X1,0 To X1,256 Draw 0,Y1 To 640,Y1 'Do the same sort of line drawing, but with a variable sized box. Repeat 'Track the mouse position as before. X2=X Screen(X Mouse) : Y2=Y Screen(Y Mouse) 'Redraw the box only when it changes. If OX<>X2 or OY<>Y2 Box X1,Y1 To OX,OY Box X1,Y1 To X2,Y2 End If 'Remember the coordinate for later. OX=X2 : OY=Y2 Wait Vbl Until Mouse Key=0 'The area has been defined, so erase the box. Box X1,Y1 To X2,Y2 'As the Box routine actually overlaps the starting point, it tends ' to hang around as a dot. This gets rid of it. Plot X1,Y1 'Return the drawing mode back to normal. Gr Writing 1 'Adjust the coordinates selected so that the X1,Y1 is top left and ' that a zero sized area is not returned. Eg. the Bar command will ' die if the coordinates are wrong. If X1>X2 Then Swap X1,X2 If Y1>Y2 Then Swap Y1,Y2 If X2-X1=0 Then Inc X2 If Y2-Y1=0 Then Inc Y2 End Proc 'Provides a click-and-release function. Procedure CLICK Repeat : Multi Wait : Until Mouse Key=0 Repeat : Multi Wait : Until Mouse Key=1 End Proc 'Show which drawing tool is being used. Procedure SEE_CONTROL[COM] Shared OLD_COMMAND 'Go to the control panel. Screen 0 'Erase the little highlight on the old tool. Ink 27 Bar Z(OLD_COMMAND,0)+1,Z(OLD_COMMAND,1)+1 To Z(OLD_COMMAND,0)+3,Z(OLD_COMMAND,1)+2 'Place new highlight on the current one. Ink 2 Bar Z(COM,0)+1,Z(COM,1)+1 To Z(COM,0)+3,Z(COM,1)+2 End Proc