mirror of
https://github.com/gamache/blehm.git
synced 2025-08-15 10:27:38 +00:00
first commit
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
.DS_Store
|
||||
|
BIN
Duane Blehm's Code.zip
Normal file
BIN
Duane Blehm's Code.zip
Normal file
Binary file not shown.
24
Duane Blehm's Code/Animation ƒ/About Animation.txt
Executable file
24
Duane Blehm's Code/Animation ƒ/About Animation.txt
Executable file
@@ -0,0 +1,24 @@
|
||||
About the Animation Demo files:
|
||||
{note: TML is now shipping version 2.5 of their Pascal, believe it is
|
||||
free to version 2.0 owners. Fixes some stuff for the new System. We
|
||||
didn't have any trouble with 2.0 until we moved up to System 4.1. The
|
||||
package includes 'Edit' version 2.1. 'Edit' is also available from APDA..see
|
||||
the MoreInfo.sit files.
|
||||
**note: Watch out for the new print stuff and systems before 4.1!}
|
||||
|
||||
'Animation Steps' is a 'FullPaint' document that illustrates the steps
|
||||
in getting graphics from a Paint program to animation on the screen...
|
||||
document can be opened from most Paint type programs.
|
||||
|
||||
'Animation.Pas' is an 'Edit' text file containing pascal source
|
||||
code to be compiled by the Pascal compiler.
|
||||
|
||||
'Anim.R' is an 'Edit' text file containing RMaker source code to
|
||||
be compiled by RMaker.
|
||||
|
||||
'Anim/Rsrc' is a resource document containing resources built with
|
||||
ResEdit, the resource editor. These resources are 'included' when
|
||||
Anim.R is compiled by RMaker.
|
||||
|
||||
'Animation' is our application... the result of Link.
|
||||
|
16
Duane Blehm's Code/Animation ƒ/Anim.R
Executable file
16
Duane Blehm's Code/Animation ƒ/Anim.R
Executable file
@@ -0,0 +1,16 @@
|
||||
* Anim.R
|
||||
|
||||
Anim.rsrc
|
||||
|
||||
TYPE MENU
|
||||
,1
|
||||
\14
|
||||
|
||||
,256
|
||||
File
|
||||
OffScreen..
|
||||
Quit
|
||||
|
||||
* will include Pict resource file built with ResEdit and ScrapBook
|
||||
INCLUDE Anim/rsrc
|
||||
|
0
Duane Blehm's Code/Animation ƒ/Anim:rsrc
Executable file
0
Duane Blehm's Code/Animation ƒ/Anim:rsrc
Executable file
0
Duane Blehm's Code/Animation ƒ/Animation
Executable file
0
Duane Blehm's Code/Animation ƒ/Animation
Executable file
BIN
Duane Blehm's Code/Animation ƒ/Animation Steps
Executable file
BIN
Duane Blehm's Code/Animation ƒ/Animation Steps
Executable file
Binary file not shown.
534
Duane Blehm's Code/Animation ƒ/Animation.Pas
Executable file
534
Duane Blehm's Code/Animation ƒ/Animation.Pas
Executable file
@@ -0,0 +1,534 @@
|
||||
Program Anim;
|
||||
{this is a simple animation program.. in CreatePictures we load several
|
||||
pictures. These pictures can be created in any Paint or Drawing type
|
||||
program.. then copied to Scrapbook DA. Using ResEdit, the resource editor,
|
||||
these Pictures can be copied from the Scrapbook into 'PICT' type resources.
|
||||
Note that in our Anim.R source file we have an INCLUDE Anim.rsrc... when
|
||||
RMaker compiles the Anim.R file it 'includes' any resources in the file
|
||||
Anim.rsrc. That's how our Paint pictures get into the SimpleAnimation
|
||||
resources.
|
||||
|
||||
Once we have them loaded into our various picHandles we then
|
||||
CreateOffScreenBitMap so we have a place to DrawPicture() them. The
|
||||
OffScreen bitmap is a section of memory just like the memory being
|
||||
displayed on the screen... we just can't see it! at least not until we
|
||||
CopyBits() some of it over to the visible screen Bitmap. We 'Draw' into
|
||||
the OffScreen by setting our window^.portbits to our OffScreen bitmap..
|
||||
watch out for 'clipping' if your OffScreen is bigger than your window.
|
||||
Now for the fun! We have everything we need for the CopyBits() ROM call.
|
||||
We have two Rectangles... one (sRect) that frames the shape to be copied
|
||||
from OffScreen, the other (dRect) frames the location in our window where
|
||||
we want the shape to be drawn. If dRect is not same size as sRect then
|
||||
CopyBits will scale the shape to fit. This program uses the srcCopy mode
|
||||
to 'erase' any previous stuff in the dRect... by using a 3 pixel white
|
||||
border on the left side of our wagon we can offset it by 3 pixels per
|
||||
animation loop and still 'erase' the previous wagon just by drawing over it.
|
||||
Internal Animation (wheels turning, horse running,etc.) is achieved by
|
||||
alternately drawing 3 different shapes in sequence as the dRect moves across
|
||||
the screen... this is easily done by having an array of offscreen sRect's
|
||||
and an index to step thru the array...}
|
||||
|
||||
{note: to move a given rectangle 'myRect' from its present location
|
||||
(Current) to another location (Destination) the following can be used...
|
||||
|
||||
OffsetRect(myRect,Destination.h - Current.h,Destination.v - Current.v);
|
||||
|
||||
or...
|
||||
|
||||
OffsetRect(myRect,DestRect.left - myRect.left,DestRect.top - myRect.top);}
|
||||
|
||||
USES MacIntf;
|
||||
|
||||
{$L Anim.rsrc}{link resources...just our menu stuff}
|
||||
|
||||
CONST
|
||||
lastMenu = 2; {Number of Menus}
|
||||
appleMenu = 1;
|
||||
fileMenu = 256;
|
||||
|
||||
WagonOne = 128;{Three wagon shapes loaded from resource file}
|
||||
WagonTwo = 129;
|
||||
WagonThree = 130;
|
||||
{Resource Picts pasted from Scrapbook into Resource file using ResEdit}
|
||||
|
||||
VAR {global program stuff}
|
||||
myDialog: DialogPtr;
|
||||
myMenus: Array[1..lastMenu] of MenuHandle;
|
||||
refNum,theMenu,
|
||||
theItem: integer;
|
||||
Finished: Boolean;{used to terminate the program}
|
||||
ClockCursor: CursHandle; {handle to watch cursor}
|
||||
myWindow: WindowPtr;
|
||||
Screen,DragArea,
|
||||
GrowArea: Rect;
|
||||
|
||||
HomeTown: PicHandle;{handle for our Logo pic}
|
||||
HomeRect: Rect;{destination rect for our Logo}
|
||||
Wagon: Array[1..3] of PicHandle;{we got three wagon pics}
|
||||
WagonRect: Rect;{size of one wagon, onScreen destination for Copybits}
|
||||
OffWagonRect: Array[1..3] of Rect;{wagon shape rects in offScreen}
|
||||
WagonNdx: integer;{which of 3 wagon shapes is to be drawn}
|
||||
|
||||
{here's all the fly/regions stuff}
|
||||
Fly: array[1..2] of PicHandle;{for loading 2 fly pictures}
|
||||
FlyRect: Rect;{destination rect for drawing fly}
|
||||
OffFly: array[1..2] of Rect;{source rects in offscreen}
|
||||
FlyNdx: integer;{which offFly to draw}
|
||||
Flower: PicHandle;{load picture from resource}
|
||||
FlowerRect: Rect;{for locating the flower}
|
||||
FlowerRgn: RgnHandle;{For 'clipping' fly and flower}
|
||||
FlyLimits: Rect;{for fly border}
|
||||
FlightRect: Rect;{For limiting fly flight}
|
||||
CursorIsOn: Boolean;
|
||||
MouseRect: Rect;{size of FlightRect, slides with mouse to smooth movement}
|
||||
|
||||
OffScreen,OldBits: BitMap; {for drawing into offscreen}
|
||||
SizeOfOff: Size; {Size offscreen bitmap}
|
||||
OffRowBytes: Integer;
|
||||
|
||||
{----------------------------------------------}
|
||||
procedure CreatePictures; {get 3 Wagon PICT's from resource file}
|
||||
var
|
||||
i:integer;
|
||||
Begin
|
||||
HomeTown := GetPicture(131);{HomeTown logo}
|
||||
HomeRect := HomeTown^^.picFrame;{size dest.Rest for drawing pic}
|
||||
|
||||
{we'll draw logo into upper right corner of window so relocate}
|
||||
OffSetRect(HomeRect,myWindow^.portRect.right - 20 -
|
||||
HomeRect.right,20 - HomeRect.top);
|
||||
|
||||
Wagon[1] := GetPicture(WagonOne); {load Wagon shapes from resources}
|
||||
Wagon[2] := GetPicture(WagonTwo);
|
||||
Wagon[3] := GetPicture(WagonThree);
|
||||
WagonRect := Wagon[1]^^.picFrame; { i-159, size our WagonRect }
|
||||
{Size Rects for OffScreen shapes...will locate them later}
|
||||
For i := 1 to 3 do OffWagonRect[i] := WagonRect;
|
||||
|
||||
{load flystuff to demonstrate regions}
|
||||
Fly[1] := GetPicture(132);
|
||||
Fly[2] := GetPicture(133);
|
||||
{size the fly rectangles}
|
||||
For i := 1 to 2 do OffFly[i] := Fly[i]^^.picFrame;{they're both same size}
|
||||
FlyRect := OffFly[1];
|
||||
|
||||
Flower := GetPicture(134);
|
||||
FlowerRect := Flower^^.picFrame;
|
||||
|
||||
{load the region resource and coerce it to RgnHandle}
|
||||
FlowerRgn := RgnHandle(GetResource('RGN ',128));{flower region... outline}
|
||||
{note this region created with our 'Regions' utility}
|
||||
end;
|
||||
|
||||
procedure CreateOffScreenBitMap; {see CopyBits stuff,also tech.note 41}
|
||||
const
|
||||
OffLeft = 0;
|
||||
OffTop = 0;
|
||||
OffRight = 115;
|
||||
OffBottom = 95; {size bitmap to contain three wagon Picts}
|
||||
var
|
||||
bRect: Rect;
|
||||
Begin
|
||||
{find size/rows/bounds of bitimage}
|
||||
SetRect(bRect,Offleft,OffTop,OffRight,OffBottom); { drawing area }
|
||||
with bRect do begin
|
||||
OffRowBytes := (((right - left -1) div 16) +1) * 2;{has to be even!}
|
||||
SizeOfOff := (bottom - top) * OffRowBytes;
|
||||
OffSetRect(bRect,-left,-top); {local coordinates...0,0 = topleft }
|
||||
end; { of with }
|
||||
|
||||
with OffScreen do begin; { create new BitMap record }
|
||||
{create new bitimage and make baseAddr point to it}
|
||||
baseAddr := QDPtr(NewPtr(SizeOfOff));
|
||||
rowbytes := OffRowBytes;{number of bytes/row,can extend beyond bounds}
|
||||
bounds := bRect;{limits of bitimage drawing?}
|
||||
end; { of with OffScreen }
|
||||
End;
|
||||
|
||||
procedure DrawPicsIntoOffScreen;
|
||||
var
|
||||
i: integer;
|
||||
Begin
|
||||
OldBits := myWindow^.portBits; {preserve old myWindow BitMap}
|
||||
SetPortBits(OffScreen); {our new myWindow BitMap }
|
||||
|
||||
{note: If offscreen bitmap is bigger than myWindow bitmap watchout for
|
||||
clipping caused by ClipRgn and VisRgn fields of grafport record, you
|
||||
can set cliprgn with ClipRect procedure and use CopyRgn procedure
|
||||
to store old visrgn in temporary rgn... etc.}
|
||||
|
||||
FillRect(myWindow^.PortRect,white); {erase our new BitMap to white}
|
||||
|
||||
{locate wagon shape Rectangles in OffScreen Bitmap}
|
||||
OffSetRect(OffWagonRect[1],-OffWagonRect[1].left,
|
||||
-OffWagonRect[1].top);{topleft corner..0,0}
|
||||
OffSetRect(OffWagonRect[2],-OffWagonRect[2].left,
|
||||
OffWagonRect[1].bottom - OffWagonRect[2].top);{below 1}
|
||||
OffSetRect(OffWagonRect[3],-OffWagonRect[3].left,
|
||||
OffWagonRect[2].bottom - OffWagonRect[3].top);{below 2}
|
||||
|
||||
{draw the wagons into the offscreen bitmap}
|
||||
For i := 1 to 3 do DrawPicture(Wagon[i],OffWagonRect[i]);
|
||||
|
||||
{locate the flys in the offscreen bitmap}
|
||||
OffSetRect(OffFly[1],OffWagonRect[1].right - OffFly[1].left,
|
||||
-OffFly[1].top); {right of wagons, at top}
|
||||
OffSetRect(OffFly[2],OffWagonRect[1].right - OffFly[2].left,
|
||||
OffFly[1].bottom-OffFly[2].top); {right of wagons, below fly[1]}
|
||||
|
||||
{draw the flys into offscreen}
|
||||
For i := 1 to 2 do DrawPicture(Fly[i],OffFly[i]);
|
||||
|
||||
{could do a 'ReleaseResource' here if you're done with the Pictures}
|
||||
|
||||
SetPortBits(OldBits); {restore old bitmap}
|
||||
end;
|
||||
|
||||
procedure DrawWindowContents(WhichWindow:WindowPtr);{response to Update event}
|
||||
var
|
||||
trect:Rect;
|
||||
i:integer;
|
||||
Begin
|
||||
DrawPicture(HomeTown,HomeRect);{draw our logo}
|
||||
|
||||
{draw groundline under wagon}
|
||||
MoveTo(myWindow^.portRect.left,WagonRect.bottom);
|
||||
LineTo(myWindow^.portRect.right,WagonRect.bottom);
|
||||
|
||||
{copy offScreen Wagons & flys into Window..upperleft corner,as in bitmap}
|
||||
CopyBits(OffScreen,myWindow^.portBits,OffScreen.bounds,
|
||||
OffScreen.bounds,srcCopy,nil);
|
||||
|
||||
{draw current wagon Shape being animated into WagonRect}
|
||||
CopyBits(OffScreen,myWindow^.portBits,OffWagonRect[WagonNdx],
|
||||
WagonRect,srcCopy,nil);
|
||||
|
||||
{all the fly stuff}
|
||||
DrawPicture(Flower,FlowerRect);
|
||||
CopyBits(OffScreen,myWindow^.portBits,OffFly[FlyNdx],
|
||||
FlyRect,srcCopy,FlowerRgn);
|
||||
FrameRoundRect(FlyLimits,48,32);{border around the fly area}
|
||||
End;
|
||||
|
||||
Procedure InitialAnimation;{locate everything to begin animation}
|
||||
var
|
||||
tRgn:RgnHandle;
|
||||
Begin
|
||||
{locate first WagonRect,left side of window on groundline (250)}
|
||||
OffSetRect(WagonRect,-WagonRect.left,250-WagonRect.bottom);
|
||||
WagonNdx := 1;{set to first Wagon shape}
|
||||
|
||||
{locate the flower}
|
||||
OffSetRect(FlowerRect,160-FlowerRect.left,90-FlowerRect.top);
|
||||
|
||||
{locate the FlowerRgn in sync with Flower}
|
||||
OffSetRgn(FlowerRgn,FlowerRect.left-FlowerRgn^^.rgnBBox.left,
|
||||
FlowerRect.top-FlowerRgn^^.rgnBBox.top);
|
||||
|
||||
{size the FlyLimits}
|
||||
FlyLimits := FlowerRect;
|
||||
InsetRect(FlyLimits,-18,0);{expand left/right for border}
|
||||
FlyLimits.top := FlyLimits.top - 18;{also top.. leave bottom for stem}
|
||||
|
||||
{create the region to exclude drawing in the flower}
|
||||
tRgn := NewRgn;
|
||||
OpenRgn;
|
||||
FrameRoundRect(FlyLimits,48,32);
|
||||
CloseRgn(tRgn);{region of limits rectangle}
|
||||
|
||||
DiffRgn(tRgn,FlowerRgn,FlowerRgn);{take out flower,put result in FlowerRgn}
|
||||
|
||||
{expand limits by 1 so we can have a frame border}
|
||||
InSetRect(FlyLimits,-1,-1);
|
||||
|
||||
FlightRect := FlyLimits;{FlightRect will compensate for using fly.topleft}
|
||||
InSetRect(FlightRect,-20,-20);{expand it so fly will be outside border}
|
||||
OffSetRect(FlightRect,-20,-20);{compensate for using flyRect.topleft}
|
||||
MouseRect := FlightRect;{MouseRect moves with cursor,& map into FlightRect}
|
||||
|
||||
{locate fly in upperleft of FlightRect}
|
||||
OffSetRect(FlyRect,FlightRect.left-FlyRect.left,
|
||||
FlightRect.top-FlyRect.top);
|
||||
FlyNdx := 1;{set to first Fly shape}
|
||||
end;
|
||||
|
||||
procedure AnimateWagon;
|
||||
var tPoint:Point;
|
||||
tRect:Rect;
|
||||
Begin
|
||||
{locate next WagonRect for wagon shape}
|
||||
If WagonRect.left > myWindow^.portRect.right then
|
||||
OffSetRect(WagonRect,-WagonRect.right,0) {back to left side}
|
||||
else OffSetRect(WagonRect,1,0); {move one pixel to right}
|
||||
|
||||
{draw Current WagonNdx shape into WagonRect}
|
||||
CopyBits(OffScreen,myWindow^.portBits,OffWagonRect[WagonNdx],
|
||||
WagonRect,srcCopy,nil);
|
||||
|
||||
{next wagon shape to be drawn}
|
||||
If WagonNdx < 3 then inc(WagonNdx) {next shape}
|
||||
else WagonNdx := 1; {back to first shape}
|
||||
|
||||
{now animate the fly}
|
||||
GetMouse(tPoint);{get current mouse coordinates}
|
||||
|
||||
{hide cursor if its over the fly area}
|
||||
If PtInRect(tPoint,FlyLimits) then begin
|
||||
If CursorIsOn then begin {hide cursor if its on}
|
||||
HideCursor;
|
||||
CursorIsOn := False;
|
||||
end;
|
||||
end
|
||||
else If not(CursorIsOn) then begin {show cursor if its off}
|
||||
ShowCursor;
|
||||
CursorIsOn := True;
|
||||
end;
|
||||
|
||||
{limit fly image (FlyRect) to FlightRect extremes..}
|
||||
{to keep fly from wondering off visible area}
|
||||
{mouseRect moves with the cursor and tPoint is mapped into FlightRect}
|
||||
|
||||
If not(PtInRect(tPoint,MouseRect)) then begin
|
||||
{a coordinate is outside mouseRect so slide mouseRect to tPoint}
|
||||
If tPoint.h < MouseRect.left then begin {slide MouseRect to left}
|
||||
MouseRect.right := MouseRect.right -
|
||||
(MouseRect.left - tPoint.h);
|
||||
MouseRect.left := tPoint.h;
|
||||
end
|
||||
else If tPoint.h > MouseRect.right then begin
|
||||
MouseRect.left := MouseRect.left + tPoint.h - MouseRect.right;
|
||||
MouseRect.right := tPoint.h;
|
||||
end;
|
||||
If tPoint.v < MouseRect.top then begin
|
||||
MouseRect.bottom := MouseRect.bottom -
|
||||
(MouseRect.top - tPoint.v);
|
||||
MouseRect.top := tPoint.v;
|
||||
end
|
||||
else If tPoint.v > MouseRect.bottom then begin
|
||||
MouseRect.top := MouseRect.top + tPoint.v - MouseRect.bottom;
|
||||
MouseRect.bottom := tPoint.v;
|
||||
end;
|
||||
end;{if not(ptinRect)}
|
||||
|
||||
{tPoint is to Mouse as FlyRect.topleft is to FlightRect}
|
||||
MapPt(tPoint,MouseRect,FlightRect);
|
||||
|
||||
{determine horizontal offset if needed}
|
||||
If tPoint.h > FlyRect.left + 2 then begin
|
||||
FlyRect.left := FlyRect.left + 3;{offsetRect to right}
|
||||
FlyRect.right := FlyRect.right + 3;
|
||||
end
|
||||
else if tPoint.h < FlyRect.left - 2 then begin
|
||||
FlyRect.left := FlyRect.left - 3;{offsetRect to left}
|
||||
FlyRect.right := FlyRect.right - 3;
|
||||
end;
|
||||
{vertical offset?}
|
||||
If tPoint.v > FlyRect.top + 2 then begin
|
||||
FlyRect.top := FlyRect.top + 3;
|
||||
FlyRect.bottom := FlyRect.bottom + 3;
|
||||
end
|
||||
else if tPoint.v < FlyRect.top - 2 then begin
|
||||
FlyRect.top := FlyRect.top - 3;
|
||||
FlyRect.bottom := FlyRect.bottom - 3;
|
||||
end;
|
||||
|
||||
CopyBits(OffScreen,myWindow^.portBits,OffFly[FlyNdx],
|
||||
FlyRect,srcCopy,FlowerRgn);
|
||||
|
||||
If FlyNdx = 1 then inc(FlyNdx) {next shape, there are 2}
|
||||
else FlyNdx := 1; {back to first shape}
|
||||
end;
|
||||
|
||||
|
||||
PROCEDURE InitThings;
|
||||
Begin
|
||||
InitGraf(@thePort); {create a grafport for the screen}
|
||||
|
||||
MoreMasters; {extra pointer blocks at the bottom of the heap}
|
||||
MoreMasters; {this is 5 X 64 master pointers}
|
||||
MoreMasters;
|
||||
MoreMasters;
|
||||
MoreMasters;
|
||||
|
||||
{get the cursors we use and lock them down - no clutter}
|
||||
ClockCursor := GetCursor(watchCursor);
|
||||
HLock(Handle(ClockCursor));
|
||||
|
||||
{show the watch while we wait for inits & setups to finish}
|
||||
SetCursor(ClockCursor^^);
|
||||
|
||||
{init everything in case the app is the Startup App}
|
||||
InitFonts; {startup the fonts manager}
|
||||
InitWindows; {startup the window manager}
|
||||
InitMenus; {startup the menu manager}
|
||||
TEInit; {startup the text edit manager}
|
||||
InitDialogs(Nil); {startup the dialog manager}
|
||||
|
||||
Finished := False; {set program terminator to false}
|
||||
FlushEvents(everyEvent,0); {clear events from previous program}
|
||||
{ set up screen size stuff }
|
||||
Screen := ScreenBits.Bounds; { Get screen dimensions from thePort }
|
||||
with Screen do { Screen.Left, etc. }
|
||||
Begin
|
||||
SetRect(DragArea,Left+4,Top+24,Right-4,Bottom-4);
|
||||
SetRect(GrowArea,Left,Top+24,Right,Bottom);
|
||||
End;
|
||||
End;
|
||||
|
||||
procedure CreateWindow;
|
||||
var
|
||||
Wrect: Rect;
|
||||
TypeWind: Integer;
|
||||
Visible: Boolean;
|
||||
GoAway: Boolean;
|
||||
RefVal: Longint;
|
||||
Begin
|
||||
SetRect(Wrect,10,40,500,300);
|
||||
TypeWind := 0;
|
||||
Visible := True;
|
||||
GoAway := True;
|
||||
|
||||
myWindow := NewWindow(Nil,Wrect,'Simple Animation',Visible,
|
||||
TypeWind,Nil,GoAway,RefVal);
|
||||
SetPort(myWindow);
|
||||
ClipRect(myWindow^.portRect);{set clipping area as per Inside Mac}
|
||||
End;
|
||||
|
||||
procedure DoMenuCommand(mResult:LongInt);
|
||||
var
|
||||
name: Str255;
|
||||
tPort: GrafPtr;
|
||||
Begin
|
||||
theMenu := HiWord(mResult);
|
||||
theItem := LoWord(mResult);
|
||||
Case theMenu of
|
||||
appleMenu:
|
||||
Begin
|
||||
GetItem(myMenus[1],theItem,name);
|
||||
refNum := OpenDeskAcc(name);
|
||||
End;
|
||||
fileMenu:
|
||||
Case theItem of
|
||||
1:{display offScreen bitmap in dialog}
|
||||
Begin
|
||||
myDialog := GetNewDialog(128,nil,myWindow);{from resource}
|
||||
GetPort(tPort);
|
||||
ShowWindow(myDialog);{invisible in resource}
|
||||
SelectWindow(myDialog);
|
||||
SetPort(myDialog); {so we can draw into our window}
|
||||
|
||||
CopyBits(OffScreen,myDialog^.portBits,OffScreen.bounds,
|
||||
OffScreen.bounds,srcOr,Nil);{the whole thing}
|
||||
FrameRect(OffScreen.bounds);{frame it }
|
||||
MoveTo(OffScreen.bounds.left + 10,OffScreen.bounds.bottom + 20);
|
||||
DrawString('^ copy of OffScreen Bitmap');
|
||||
|
||||
ModalDialog(Nil,theItem);{we'll close no matter what hit}
|
||||
|
||||
HideWindow(myDialog);
|
||||
SelectWindow(myWindow);{restore our game window}
|
||||
SetPort(tPort);
|
||||
end;{1:}
|
||||
2:Finished := True;
|
||||
end;{case theItem}
|
||||
End;
|
||||
HiliteMenu(0);
|
||||
End;
|
||||
|
||||
procedure TakeCareMouseDown(myEvent:EventRecord);
|
||||
var
|
||||
Location: integer;
|
||||
WhichWindow: WindowPtr;
|
||||
MouseLoc: Point;
|
||||
WindowLoc: integer;
|
||||
Begin
|
||||
MouseLoc := myEvent.Where; {Global coordinates}
|
||||
WindowLoc := FindWindow(MouseLoc,WhichWindow); {I-287}
|
||||
case WindowLoc of
|
||||
inMenuBar:
|
||||
DoMenuCommand(MenuSelect(MouseLoc));
|
||||
inSysWindow:
|
||||
SystemClick(myEvent,WhichWindow); {I-441}
|
||||
inContent:
|
||||
If WhichWindow <> FrontWindow then
|
||||
SelectWindow (WhichWindow);
|
||||
inGoAway:
|
||||
If TrackGoAway(WhichWindow,MouseLoc) then
|
||||
Finished := True;{end the game}
|
||||
end; {case of}
|
||||
end; { TakeCareMouseDown }
|
||||
|
||||
procedure TakeCareActivates(myEvent:EventRecord);
|
||||
var
|
||||
WhichWindow: WindowPtr;
|
||||
Begin
|
||||
WhichWindow := WindowPtr(myEvent.message);
|
||||
SetPort(WhichWindow);
|
||||
End;
|
||||
|
||||
procedure TakeCareUpdates(Event:EventRecord);
|
||||
var
|
||||
UpDateWindow,TempPort: WindowPtr;
|
||||
Begin
|
||||
UpDateWindow := WindowPtr(Event.message);
|
||||
GetPort(TempPort);
|
||||
SetPort(UpDateWindow);
|
||||
BeginUpDate(UpDateWindow);
|
||||
EraseRect(UpDateWindow^.portRect);{ or UpdateWindow^.VisRgn^^.rgnBBox }
|
||||
DrawWindowContents(UpDateWindow);
|
||||
EndUpDate(UpDateWindow);
|
||||
SetPort(TempPort);
|
||||
End;
|
||||
|
||||
procedure MainEventLoop;
|
||||
var
|
||||
myEvent: EventRecord;
|
||||
Begin
|
||||
InitCursor;
|
||||
CursorIsOn := True;{keep track of hide/show cursor}
|
||||
Repeat
|
||||
SystemTask;
|
||||
If GetNextEvent(EveryEvent,myEvent) then
|
||||
Case myEvent.What of
|
||||
mouseDown: TakeCareMouseDown(myEvent);
|
||||
KeyDown: Finished:= True;
|
||||
ActivateEvt:TakeCareActivates(myEvent);
|
||||
UpDateEvt: TakeCareUpdates(myEvent);
|
||||
End
|
||||
|
||||
Else AnimateWagon;{animate one loop of our wagon shape}
|
||||
|
||||
Until Finished;
|
||||
End;
|
||||
|
||||
procedure SetUpMenus;
|
||||
var
|
||||
i: integer;
|
||||
Begin
|
||||
myMenus[1] := GetMenu(appleMenu); {get menu info from resources}
|
||||
AddResMenu(myMenus[1],'DRVR'); {add in all the DA's}
|
||||
myMenus[2] := GetMenu(fileMenu);
|
||||
For i := 1 to lastMenu do
|
||||
begin
|
||||
InsertMenu(myMenus[i],0);
|
||||
end;
|
||||
DrawMenuBar;
|
||||
End;
|
||||
|
||||
procedure CloseStuff;
|
||||
Begin
|
||||
{be sure to kill any sound I/O before quitting!}
|
||||
End;
|
||||
|
||||
{Main Program begins here}
|
||||
BEGIN
|
||||
InitThings;
|
||||
SetUpMenus;
|
||||
CreateWindow;
|
||||
CreatePictures;{load picts from resource file}
|
||||
CreateOffScreenBitMap;{for use with copyBits procedure}
|
||||
DrawPicsIntoOffScreen;{OffScreen holds all our wagon/fly shapes}
|
||||
InitialAnimation;{set up stuff for start of animation}
|
||||
MainEventLoop;{will animate wagon/fly if nothing else is going on}
|
||||
CloseStuff;
|
||||
END.
|
1
Duane Blehm's Code/Cairo ƒ/About Cairo files..
Executable file
1
Duane Blehm's Code/Cairo ƒ/About Cairo files..
Executable file
@@ -0,0 +1 @@
|
||||
about the Cairo files....
|
BIN
Duane Blehm's Code/Cairo ƒ/Cairo Animation
Executable file
BIN
Duane Blehm's Code/Cairo ƒ/Cairo Animation
Executable file
Binary file not shown.
BIN
Duane Blehm's Code/Cairo ƒ/Cairo Shapes
Executable file
BIN
Duane Blehm's Code/Cairo ƒ/Cairo Shapes
Executable file
Binary file not shown.
0
Duane Blehm's Code/Cairo ƒ/Cairo ShootOut v1.2L
Executable file
0
Duane Blehm's Code/Cairo ƒ/Cairo ShootOut v1.2L
Executable file
1
Duane Blehm's Code/Cairo ƒ/CairoFont.pro
Executable file
1
Duane Blehm's Code/Cairo ƒ/CairoFont.pro
Executable file
@@ -0,0 +1 @@
|
||||
|
2811
Duane Blehm's Code/Cairo ƒ/CairoShootOut.Pas
Executable file
2811
Duane Blehm's Code/Cairo ƒ/CairoShootOut.Pas
Executable file
File diff suppressed because it is too large
Load Diff
38
Duane Blehm's Code/Cairo ƒ/aCairo.R
Executable file
38
Duane Blehm's Code/Cairo ƒ/aCairo.R
Executable file
@@ -0,0 +1,38 @@
|
||||
* aCairo.R
|
||||
|
||||
aCairo.rsrc
|
||||
|
||||
TYPE NILE = STR
|
||||
,0
|
||||
Cairo ShootOut ver1.2src, by Duane Blehm, 9/15/87
|
||||
|
||||
TYPE MENU
|
||||
,1
|
||||
\14
|
||||
About ShootOut...
|
||||
(-
|
||||
|
||||
,256
|
||||
Game
|
||||
Begin
|
||||
Quit /Q
|
||||
|
||||
,257
|
||||
Options
|
||||
Unlock..
|
||||
Help..
|
||||
HiScore..
|
||||
! Sound
|
||||
Set Speed..
|
||||
|
||||
,258
|
||||
Works
|
||||
Peek OffScreen
|
||||
Source Code...
|
||||
|
||||
,259
|
||||
(Any Key to Exit)
|
||||
|
||||
* will include Resource file built with ResEdit and ScrapBook
|
||||
INCLUDE aCairo/rsrc
|
||||
|
0
Duane Blehm's Code/Cairo ƒ/aCairo:rsrc
Executable file
0
Duane Blehm's Code/Cairo ƒ/aCairo:rsrc
Executable file
BIN
Duane Blehm's Code/Copy Mask ƒ/About CopyMask
Executable file
BIN
Duane Blehm's Code/Copy Mask ƒ/About CopyMask
Executable file
Binary file not shown.
16
Duane Blehm's Code/Copy Mask ƒ/CMask.R
Executable file
16
Duane Blehm's Code/Copy Mask ƒ/CMask.R
Executable file
@@ -0,0 +1,16 @@
|
||||
* CMask.R
|
||||
|
||||
CMask.rsrc
|
||||
|
||||
TYPE MENU
|
||||
,1
|
||||
\14
|
||||
|
||||
,256
|
||||
File
|
||||
OffScreen..
|
||||
Quit
|
||||
|
||||
* will include Pict resources file built with ResEdit and ScrapBook
|
||||
INCLUDE CMask/rsrc
|
||||
|
0
Duane Blehm's Code/Copy Mask ƒ/CMask:rsrc
Executable file
0
Duane Blehm's Code/Copy Mask ƒ/CMask:rsrc
Executable file
0
Duane Blehm's Code/Copy Mask ƒ/CopyMask
Executable file
0
Duane Blehm's Code/Copy Mask ƒ/CopyMask
Executable file
533
Duane Blehm's Code/Copy Mask ƒ/CopyMask.pas
Executable file
533
Duane Blehm's Code/Copy Mask ƒ/CopyMask.pas
Executable file
@@ -0,0 +1,533 @@
|
||||
Program CopyMaskDemo;{copyright <20>,1987...Duane Blehm,HomeTown Software}
|
||||
{This program illustrates using the CopyMask() ROM procedure for animation.
|
||||
Note: CopyMask and CalcMask are NOT available in the 64k ROMs.
|
||||
We just set up everything so we could achieve the same 'effect' as we did
|
||||
with CopyBits and regions in the Animation Demo. We're sure there are
|
||||
some better examples of how CopyMask might be used... thought out with
|
||||
its features in mind. See Inside Mac vol. 4 or Technical Note #57 for
|
||||
specs. on these and other 'new' 128k ROM Quickdraw routines.}
|
||||
|
||||
USES MacIntf;
|
||||
|
||||
{$L CMask.rsrc}{link resources...just our menu stuff}
|
||||
|
||||
CONST
|
||||
lastMenu = 2; {Number of Menus}
|
||||
appleMenu = 1;
|
||||
fileMenu = 256;
|
||||
|
||||
VAR {global program stuff}
|
||||
FlowerMap, {will use FlowerMap to do our CalcMask of Flower pict}
|
||||
MaskMap: BitMap;{final mask, used with CopyMask call}
|
||||
imagePtr,tPtr: Ptr;{imagePtr points to temp. BitImage of FlowerMap}
|
||||
tRect,
|
||||
MaskRect: Rect;{MaskRect same size as FlyRect, CopyMask call}
|
||||
|
||||
HomeTown: PicHandle;{handle for our Logo pic}
|
||||
HomeRect: Rect;{destination rect for our Logo}
|
||||
|
||||
{here's all the fly/regions stuff}
|
||||
Fly: array[1..2] of PicHandle;{for loading 2 fly pictures}
|
||||
FlyRect: Rect;{destination rect for drawing fly}
|
||||
OffFly: array[1..2] of Rect;{source rects in offscreen}
|
||||
FlyNdx: integer;{which offFly to draw}
|
||||
Flower: PicHandle;{load picture from resource}
|
||||
FlowerRect: Rect;{for locating the flower}
|
||||
FlyBorder: Rect;{for fly border}
|
||||
FlightRect: Rect;{For limiting fly flight}
|
||||
CursorIsOn: Boolean;
|
||||
MouseRect: Rect;{slides with mouse to smooth movement}
|
||||
|
||||
OffScreen, {will hold our 2 fly images}
|
||||
OldBits: BitMap;
|
||||
SizeOfOff: Size; {for Size-ing the offscreen bitmap}
|
||||
OffRowBytes: Integer;
|
||||
|
||||
myDialog: DialogPtr;
|
||||
myMenus: Array[1..lastMenu] of MenuHandle;
|
||||
refNum,theMenu,
|
||||
theItem: integer;
|
||||
Finished: Boolean;{used to terminate the program}
|
||||
ClockCursor: CursHandle; {handle to watch cursor}
|
||||
myWindow: WindowPtr;
|
||||
Screen,DragArea,
|
||||
GrowArea: Rect;
|
||||
i,x,y: integer;
|
||||
|
||||
{----------------------------------------------}
|
||||
procedure CreatePictures;
|
||||
var
|
||||
i:integer;
|
||||
Begin
|
||||
HomeTown := GetPicture(131);{HomeTown logo}
|
||||
HomeRect := HomeTown^^.picFrame;{size dest.Rest for drawing pic}
|
||||
|
||||
{we'll draw logo into upper right corner of window so relocate}
|
||||
OffSetRect(HomeRect,myWindow^.portRect.right - 1 -
|
||||
HomeRect.right,1 - HomeRect.top);
|
||||
|
||||
{load flystuff to demonstrate regions}
|
||||
Fly[1] := GetPicture(132);
|
||||
Fly[2] := GetPicture(133);
|
||||
{size the fly rectangles}
|
||||
For i := 1 to 2 do OffFly[i] := Fly[i]^^.picFrame;{they're both same size}
|
||||
FlyRect := OffFly[1];
|
||||
|
||||
Flower := GetPicture(134);
|
||||
FlowerRect := Flower^^.picFrame;{size the FlowerRect}
|
||||
end;
|
||||
|
||||
procedure CreateOffScreenBitMap; {see CopyBits stuff,also tech.note 41}
|
||||
var
|
||||
bRect: Rect;
|
||||
Begin
|
||||
{find size/rows/bounds of bitimage}
|
||||
SetRect(bRect,0,0,50,95); { big enough for our flys! }
|
||||
with bRect do begin
|
||||
OffRowBytes := (((right - left -1) div 16) +1) * 2;{has to be even!}
|
||||
SizeOfOff := (bottom - top) * OffRowBytes;
|
||||
OffSetRect(bRect,-left,-top); {local coordinates...0,0 = topleft }
|
||||
end; { of with }
|
||||
|
||||
with OffScreen do begin; { create new BitMap record }
|
||||
{create new bitimage and make baseAddr point to it}
|
||||
baseAddr := QDPtr(NewPtr(SizeOfOff));
|
||||
rowbytes := OffRowBytes;{number of bytes/row,can extend beyond bounds}
|
||||
bounds := bRect;{limits of bitimage drawing?}
|
||||
end; { of with OffScreen }
|
||||
End;
|
||||
|
||||
procedure DrawPicsIntoOffScreen;
|
||||
var
|
||||
i: integer;
|
||||
Begin
|
||||
OldBits := myWindow^.portBits; {preserve old myWindow BitMap}
|
||||
SetPortBits(OffScreen); {our new myWindow BitMap }
|
||||
|
||||
FillRect(OffScreen.bounds,white); {erase our new BitMap to white}
|
||||
|
||||
{locate the flys in the offscreen bitmap}
|
||||
OffSetRect(OffFly[1],- OffFly[1].left,-OffFly[1].top);
|
||||
OffSetRect(OffFly[2],- OffFly[2].left,OffFly[1].bottom-OffFly[2].top);
|
||||
|
||||
{draw the flys into offscreen}
|
||||
For i := 1 to 2 do begin
|
||||
DrawPicture(Fly[i],OffFly[i]);
|
||||
ReleaseResource(Handle(Fly[i]));{done with pics so dump em}
|
||||
end;
|
||||
|
||||
SetPortBits(OldBits); {restore old bitmap}
|
||||
end;
|
||||
|
||||
procedure CreateMaskBitMap;
|
||||
{first in the FlowerMap we draw the flower then we do a CalcMask of it
|
||||
into an identical bitimage (imagePtr). Once we have the mask in imagePtr
|
||||
we make FlowerMap.baseAddr point to it and invert it so the fly is drawn
|
||||
'outside' the flower edges (the 'flower' becomes white instead black). The
|
||||
MaskMap needs to be size of the area the fly will be flying over, and we
|
||||
have a RoundRect border which includes the flower area. So we fill the
|
||||
RoundRect area with black and copyBits the inverted Flower mask from
|
||||
FlowerMap. (see Paint document for illustration of this) Now there is
|
||||
black everywhere in the MaskMap we want the Fly to be drawn on the screen
|
||||
except the 'coordinates' are not the same. All we need to do is start
|
||||
the MaskRect over the MaskMap in sync with the flyRect in our window so
|
||||
they begin in the same 'relative' position to the flower/border}
|
||||
Begin
|
||||
{find size/rows/bounds of bitimage}
|
||||
tRect := Flower^^.picFrame;{FlowerMap size of flower picture}
|
||||
with tRect do begin
|
||||
OffRowBytes := (((right - left -1) div 16) +1) * 2;{has to be even!}
|
||||
SizeOfOff := (bottom - top) * OffRowBytes;
|
||||
OffSetRect(tRect,-left,-top); {local coordinates...0,0 = topleft }
|
||||
end; { of with }
|
||||
|
||||
with FlowerMap do begin; { create new BitMap record }
|
||||
{create new bitimage and make baseAddr point to it}
|
||||
baseAddr := QDPtr(NewPtr(SizeOfOff));
|
||||
rowbytes := OffRowBytes;{number of bytes/row,can extend beyond bounds}
|
||||
bounds := tRect;{limits of bitimage drawing?}
|
||||
end; {with}
|
||||
|
||||
imagePtr := QDPtr(NewPtr(SizeOfOff));{Bitimage same as FlowerMap}
|
||||
|
||||
OldBits := myWindow^.portBits; {preserve old myWindow BitMap}
|
||||
SetPortBits(FlowerMap); {our new myWindow BitMap }
|
||||
|
||||
DrawPicture(Flower,tRect);{draw flower into the BitMap}
|
||||
|
||||
{create mask for flower picture, 128k ROMs only}
|
||||
CalcMask(FlowerMap.baseAddr,imagePtr,FlowerMap.rowbytes,
|
||||
FlowerMap.rowbytes,FlowerMap.bounds.bottom-FlowerMap.bounds.top,
|
||||
FlowerMap.rowbytes div 2);
|
||||
|
||||
FlowerMap.baseAddr := imagePtr;{make FlowerMap point to mask}
|
||||
SetPortBits(FlowerMap);{make our window point to new flowerMap}
|
||||
InvertRect(FlowerMap.Bounds);{we want to draw outside the flower }
|
||||
|
||||
{create the offscreen MaskMap.....find size/rows/bounds of bitimage}
|
||||
tRect := FlightRect;
|
||||
InsetRect(tRect,-64,-64);{enlarge so fly can exceed border}
|
||||
with tRect do begin
|
||||
OffRowBytes := (((right - left -1) div 16) +1) * 2;{has to be even!}
|
||||
SizeOfOff := (bottom - top) * OffRowBytes;
|
||||
OffSetRect(tRect,-left,-top); {local coordinates...0,0 = topleft }
|
||||
end; { of with }
|
||||
|
||||
with MaskMap do begin; { create new BitMap record }
|
||||
{create new bitimage and make baseAddr point to it}
|
||||
baseAddr := QDPtr(NewPtr(SizeOfOff));
|
||||
rowbytes := OffRowBytes;{number of bytes/row,can extend beyond bounds}
|
||||
bounds := tRect;{limits of bitimage drawing}
|
||||
end; {with}
|
||||
|
||||
SetPortBits(MaskMap);{so we can draw into the MaskMap}
|
||||
FillRect(MaskMap.bounds,white);{erase it to white}
|
||||
InsetRect(tRect,64,64);{shrink it back to flight size to draw border}
|
||||
FillRoundRect(tRect,48,32,black);{black in the flight area}
|
||||
{copy the Flower mask into MaskMap}
|
||||
tRect := FlowerRect;
|
||||
{locate it in center of border}
|
||||
OffSetRect(tRect,64+FlowerRect.left-FlightRect.left-tRect.left,
|
||||
64+FlowerRect.top-FlightRect.top-tRect.top);
|
||||
CopyBits(FlowerMap,MaskMap,FlowerMap.bounds,tRect,srcCopy,nil);
|
||||
|
||||
{note: we are done with the FlowerMap at this point.}
|
||||
|
||||
SetPortBits(OldBits); {restore old bitmap}
|
||||
|
||||
End;
|
||||
|
||||
procedure DrawWindowContents(WhichWindow:WindowPtr);{response to Update event}
|
||||
var
|
||||
trect:Rect;
|
||||
i:integer;
|
||||
Begin
|
||||
DrawPicture(HomeTown,HomeRect);{draw our logo}
|
||||
|
||||
{copy offScreen flys into Window..upperleft corner,as in bitmap}
|
||||
CopyBits(OffScreen,myWindow^.portBits,OffScreen.bounds,
|
||||
OffScreen.bounds,srcCopy,nil);
|
||||
|
||||
{all the fly stuff}
|
||||
DrawPicture(Flower,FlowerRect);
|
||||
FrameRoundRect(FlyBorder,48,32);{border around the fly area}
|
||||
CopyMask(OffScreen,MaskMap,myWindow^.portBits,OffFly[FlyNdx],
|
||||
MaskRect,FlyRect);{draw the fly}
|
||||
|
||||
End;
|
||||
|
||||
Procedure InitialAnimation;{locate everything to begin animation}
|
||||
Begin
|
||||
{locate the flower}
|
||||
OffSetRect(FlowerRect,160-FlowerRect.left,90-FlowerRect.top);
|
||||
|
||||
{size the FlyBorder}
|
||||
FlyBorder := FlowerRect;
|
||||
InsetRect(FlyBorder,-18,0);{expand left/right for border}
|
||||
FlyBorder.top := FlyBorder.top - 18;{also top.. leave bottom for stem}
|
||||
|
||||
FlightRect := FlyBorder;{FlightRect will compensate for using fly.topleft}
|
||||
|
||||
CreateMaskBitMap;{create the 'mask' for use with the CopyMask call}
|
||||
|
||||
InsetRect(FlightRect,-16,-16);{so fly can go beyond the flyborder}
|
||||
OffSetRect(FlightRect,-16,-16);{because we're using FlyRect.topleft}
|
||||
MouseRect := FlightRect;{MouseRect moves with cursor,& maps into FlightRect}
|
||||
|
||||
{expand limits by 1 so we can have a frame border that's not erased}
|
||||
InSetRect(FlyBorder,-1,-1);
|
||||
|
||||
MaskRect := FlyRect;
|
||||
{locate fly in upperleft of FlightRect}
|
||||
OffSetRect(FlyRect,FlightRect.left-FlyRect.left,
|
||||
FlightRect.top-FlyRect.top);
|
||||
{locate MaskRect in MaskMap relative to FlyRect and FlightRect}
|
||||
OffSetRect(MaskRect,32-MaskRect.left,32-MaskRect.top);{in synch with fly}
|
||||
FlyNdx := 1;{set to first Fly shape}
|
||||
end;
|
||||
|
||||
procedure AnimateStuff;
|
||||
var tPoint:Point;
|
||||
tRect:Rect;
|
||||
aTick:Longint;
|
||||
Begin
|
||||
Delay(2,aTick);{CopyMask is seems to be faster than CopyBits with Rgn..?}
|
||||
{now animate the fly}
|
||||
GetMouse(tPoint);{get current mouse coordinates}
|
||||
|
||||
{hide cursor if its over the fly area}
|
||||
If PtInRect(tPoint,FlyBorder) then begin
|
||||
If CursorIsOn then begin {hide cursor if its on}
|
||||
HideCursor;
|
||||
CursorIsOn := False;
|
||||
end;
|
||||
end
|
||||
else If not(CursorIsOn) then begin {show cursor if its off}
|
||||
ShowCursor;
|
||||
CursorIsOn := True;
|
||||
end;
|
||||
|
||||
{limit fly image (FlyRect) to FlightRect extremes..}
|
||||
{to keep fly from wondering off visible area}
|
||||
{mouseRect moves with the cursor and tPoint is mapped into FlightRect}
|
||||
|
||||
If not(PtInRect(tPoint,MouseRect)) then begin
|
||||
{a coordinate is outside mouseRect so slide mouseRect to tPoint}
|
||||
If tPoint.h < MouseRect.left then begin {slide MouseRect to left}
|
||||
MouseRect.right := MouseRect.right -
|
||||
(MouseRect.left - tPoint.h);
|
||||
MouseRect.left := tPoint.h;
|
||||
end
|
||||
else If tPoint.h > MouseRect.right then begin
|
||||
MouseRect.left := MouseRect.left + tPoint.h - MouseRect.right;
|
||||
MouseRect.right := tPoint.h;
|
||||
end;
|
||||
If tPoint.v < MouseRect.top then begin
|
||||
MouseRect.bottom := MouseRect.bottom -
|
||||
(MouseRect.top - tPoint.v);
|
||||
MouseRect.top := tPoint.v;
|
||||
end
|
||||
else If tPoint.v > MouseRect.bottom then begin
|
||||
MouseRect.top := MouseRect.top + tPoint.v - MouseRect.bottom;
|
||||
MouseRect.bottom := tPoint.v;
|
||||
end;
|
||||
end;{if not(ptinRect)}
|
||||
|
||||
{tPoint is to MouseRect as FlyRect.topleft is to FlightRect}
|
||||
MapPt(tPoint,MouseRect,FlightRect);
|
||||
|
||||
{determine horiz/vert. offset if needed, MaskRect moves in sync with FlyRect}
|
||||
If tPoint.h > FlyRect.left + 2 then begin
|
||||
FlyRect.left := FlyRect.left + 3;{offsetRect to right}
|
||||
FlyRect.right := FlyRect.right + 3;
|
||||
MaskRect.left := MaskRect.left + 3;{offsetRect to right}
|
||||
MaskRect.right := MaskRect.right + 3;
|
||||
end
|
||||
else if tPoint.h < FlyRect.left - 2 then begin
|
||||
FlyRect.left := FlyRect.left - 3;{offsetRect to left}
|
||||
FlyRect.right := FlyRect.right - 3;
|
||||
MaskRect.left := MaskRect.left - 3;{offsetRect to left}
|
||||
MaskRect.right := MaskRect.right - 3;
|
||||
end;
|
||||
{vertical offset?}
|
||||
If tPoint.v > FlyRect.top + 2 then begin
|
||||
FlyRect.top := FlyRect.top + 3;
|
||||
FlyRect.bottom := FlyRect.bottom + 3;
|
||||
MaskRect.top := MaskRect.top + 3;
|
||||
MaskRect.bottom := MaskRect.bottom + 3;
|
||||
end
|
||||
else if tPoint.v < FlyRect.top - 2 then begin
|
||||
FlyRect.top := FlyRect.top - 3;
|
||||
FlyRect.bottom := FlyRect.bottom - 3;
|
||||
MaskRect.top := MaskRect.top - 3;
|
||||
MaskRect.bottom := MaskRect.bottom - 3;
|
||||
end;
|
||||
|
||||
{draw the fly from OffScreen to myWindow using MaskMap}
|
||||
CopyMask(OffScreen,MaskMap,myWindow^.portBits,OffFly[FlyNdx],
|
||||
MaskRect,FlyRect);
|
||||
|
||||
If FlyNdx = 1 then inc(FlyNdx) {next shape, there are 2}
|
||||
else FlyNdx := 1; {back to first shape}
|
||||
end;
|
||||
|
||||
|
||||
PROCEDURE InitThings;
|
||||
Begin
|
||||
InitGraf(@thePort); {create a grafport for the screen}
|
||||
|
||||
MoreMasters; {extra pointer blocks at the bottom of the heap}
|
||||
MoreMasters; {this is 5 X 64 master pointers}
|
||||
MoreMasters;
|
||||
MoreMasters;
|
||||
MoreMasters;
|
||||
|
||||
{get the cursors we use and lock them down - no clutter}
|
||||
ClockCursor := GetCursor(watchCursor);
|
||||
HLock(Handle(ClockCursor));
|
||||
|
||||
{show the watch while we wait for inits & setups to finish}
|
||||
SetCursor(ClockCursor^^);
|
||||
|
||||
{init everything in case the app is the Startup App}
|
||||
InitFonts; {startup the fonts manager}
|
||||
InitWindows; {startup the window manager}
|
||||
InitMenus; {startup the menu manager}
|
||||
TEInit; {startup the text edit manager}
|
||||
InitDialogs(Nil); {startup the dialog manager}
|
||||
|
||||
Finished := False; {set program terminator to false}
|
||||
FlushEvents(everyEvent,0); {clear events from previous program}
|
||||
{ set up screen size stuff }
|
||||
Screen := ScreenBits.Bounds; { Get screen dimensions from thePort }
|
||||
with Screen do { Screen.Left, etc. }
|
||||
Begin
|
||||
SetRect(DragArea,Left+4,Top+24,Right-4,Bottom-4);
|
||||
SetRect(GrowArea,Left,Top+24,Right,Bottom);
|
||||
End;
|
||||
End;
|
||||
|
||||
procedure CreateWindow;
|
||||
var
|
||||
Wrect: Rect;
|
||||
TypeWind: Integer;
|
||||
Visible: Boolean;
|
||||
GoAway: Boolean;
|
||||
RefVal: Longint;
|
||||
Begin
|
||||
SetRect(Wrect,8,40,504,336);
|
||||
TypeWind := 0;
|
||||
Visible := True;
|
||||
GoAway := True;
|
||||
|
||||
myWindow := NewWindow(Nil,Wrect,'CopyMask Demo',Visible,
|
||||
TypeWind,Nil,GoAway,RefVal);
|
||||
SetPort(myWindow);
|
||||
ClipRect(myWindow^.portRect);{set clipping area as per Inside Mac}
|
||||
End;
|
||||
|
||||
procedure DoMenuCommand(mResult:LongInt);
|
||||
var
|
||||
name: Str255;
|
||||
tPort: GrafPtr;
|
||||
Begin
|
||||
theMenu := HiWord(mResult);
|
||||
theItem := LoWord(mResult);
|
||||
Case theMenu of
|
||||
appleMenu:
|
||||
Begin
|
||||
GetItem(myMenus[1],theItem,name);
|
||||
refNum := OpenDeskAcc(name);
|
||||
End;
|
||||
fileMenu:
|
||||
Case theItem of
|
||||
1:{display offScreen bitmap in dialog}
|
||||
Begin
|
||||
myDialog := GetNewDialog(128,nil,myWindow);{from resource}
|
||||
GetPort(tPort);
|
||||
ShowWindow(myDialog);{invisible in resource}
|
||||
SelectWindow(myDialog);
|
||||
SetPort(myDialog); {so we can draw into our window}
|
||||
|
||||
CopyBits(OffScreen,myDialog^.portBits,OffScreen.bounds,
|
||||
OffScreen.bounds,srcOr,Nil);{the whole thing}
|
||||
FrameRect(OffScreen.bounds);{frame it }
|
||||
MoveTo(OffScreen.bounds.left + 10,OffScreen.bounds.bottom + 20);
|
||||
DrawString('^ copy of OffScreen Bitmap');
|
||||
ModalDialog(Nil,theItem);{we'll close no matter what hit}
|
||||
|
||||
HideWindow(myDialog);
|
||||
SelectWindow(myWindow);{restore our game window}
|
||||
SetPort(tPort);
|
||||
end;{1:}
|
||||
2:Finished := True;
|
||||
end;{case theItem}
|
||||
End;
|
||||
HiliteMenu(0);
|
||||
End;
|
||||
|
||||
procedure TakeCareMouseDown(myEvent:EventRecord);
|
||||
var
|
||||
Location: integer;
|
||||
WhichWindow: WindowPtr;
|
||||
MouseLoc: Point;
|
||||
WindowLoc: integer;
|
||||
Begin
|
||||
MouseLoc := myEvent.Where; {Global coordinates}
|
||||
WindowLoc := FindWindow(MouseLoc,WhichWindow); {I-287}
|
||||
case WindowLoc of
|
||||
inMenuBar:
|
||||
DoMenuCommand(MenuSelect(MouseLoc));
|
||||
inSysWindow:
|
||||
SystemClick(myEvent,WhichWindow); {I-441}
|
||||
inContent:
|
||||
If WhichWindow <> FrontWindow then
|
||||
SelectWindow (WhichWindow);
|
||||
inGoAway:
|
||||
If TrackGoAway(WhichWindow,MouseLoc) then
|
||||
Finished := True;{end the game}
|
||||
end; {case of}
|
||||
end; { TakeCareMouseDown }
|
||||
|
||||
procedure TakeCareActivates(myEvent:EventRecord);
|
||||
var
|
||||
WhichWindow: WindowPtr;
|
||||
Begin
|
||||
WhichWindow := WindowPtr(myEvent.message);
|
||||
SetPort(WhichWindow);
|
||||
End;
|
||||
|
||||
procedure TakeCareUpdates(Event:EventRecord);
|
||||
var
|
||||
UpDateWindow,TempPort: WindowPtr;
|
||||
Begin
|
||||
UpDateWindow := WindowPtr(Event.message);
|
||||
GetPort(TempPort);
|
||||
SetPort(UpDateWindow);
|
||||
BeginUpDate(UpDateWindow);
|
||||
EraseRect(UpDateWindow^.portRect);{ or UpdateWindow^.VisRgn^^.rgnBBox }
|
||||
DrawWindowContents(UpDateWindow);
|
||||
EndUpDate(UpDateWindow);
|
||||
SetPort(TempPort);
|
||||
End;
|
||||
|
||||
procedure MainEventLoop;
|
||||
var
|
||||
myEvent: EventRecord;
|
||||
Begin
|
||||
InitCursor;
|
||||
CursorIsOn := True;{keep track of hide/show cursor}
|
||||
Repeat
|
||||
SystemTask;
|
||||
If GetNextEvent(EveryEvent,myEvent) then
|
||||
Case myEvent.What of
|
||||
mouseDown: TakeCareMouseDown(myEvent);
|
||||
KeyDown: Finished:= True;
|
||||
ActivateEvt:TakeCareActivates(myEvent);
|
||||
UpDateEvt: TakeCareUpdates(myEvent);
|
||||
End
|
||||
|
||||
Else AnimateStuff;
|
||||
|
||||
Until Finished;
|
||||
End;
|
||||
|
||||
procedure SetUpMenus;
|
||||
var
|
||||
i: integer;
|
||||
Begin
|
||||
myMenus[1] := GetMenu(appleMenu); {get menu info from resources}
|
||||
AddResMenu(myMenus[1],'DRVR'); {add in all the DA's}
|
||||
myMenus[2] := GetMenu(fileMenu);
|
||||
For i := 1 to lastMenu do
|
||||
begin
|
||||
InsertMenu(myMenus[i],0);
|
||||
end;
|
||||
DrawMenuBar;
|
||||
End;
|
||||
|
||||
procedure CloseStuff;
|
||||
Begin
|
||||
{be sure to kill any sound I/O before quitting!}
|
||||
End;
|
||||
|
||||
{Main Program begins here}
|
||||
BEGIN
|
||||
InitThings;
|
||||
{check for the 64k ROMs, abort if they're present}
|
||||
Environs(x,y);
|
||||
If x >= 117 then begin {64k roms aren't present,so go ahead}
|
||||
SetUpMenus;
|
||||
CreateWindow;
|
||||
CreatePictures;{load picts from resource file}
|
||||
CreateOffScreenBitMap;{for use with copyBits procedure}
|
||||
DrawPicsIntoOffScreen;{OffScreen holds all our fly shapes}
|
||||
InitialAnimation;{set up stuff for start of animation}
|
||||
MainEventLoop;{will animate fly if nothing else is going on}
|
||||
end
|
||||
else begin
|
||||
InitCursor;{show arrow cursor}
|
||||
i := NoteAlert(128,nil); {display alert and exit}
|
||||
end;{else}
|
||||
CloseStuff;
|
||||
END.
|
14
Duane Blehm's Code/Drag Piece ƒ/About DragPiece.txt
Executable file
14
Duane Blehm's Code/Drag Piece ƒ/About DragPiece.txt
Executable file
@@ -0,0 +1,14 @@
|
||||
About the DragPieceDemo files....
|
||||
|
||||
'DragPieceDemo.pas' is an 'Edit' text file containing sourcecode for our
|
||||
'almost generic' DragPiece() procedure used in a simple example program.
|
||||
|
||||
'aDragPiece.rsrc' is a resource file which is linked to the Demo code.
|
||||
|
||||
'DragPieceDemo' is the application file.
|
||||
|
||||
'DragPiece animation' is a paint-type file that illustrates what's happening.
|
||||
|
||||
We're including this Demo with 'ZeroGravity' because it illustrates the same
|
||||
principle of animation over backgrounds with some improvements, refinements,
|
||||
etc. We make extensive use of this procedure in our new 'PUZZ'L' application.
|
BIN
Duane Blehm's Code/Drag Piece ƒ/DragPiece animation
Executable file
BIN
Duane Blehm's Code/Drag Piece ƒ/DragPiece animation
Executable file
Binary file not shown.
0
Duane Blehm's Code/Drag Piece ƒ/DragPieceDemo
Executable file
0
Duane Blehm's Code/Drag Piece ƒ/DragPieceDemo
Executable file
392
Duane Blehm's Code/Drag Piece ƒ/DragPieceDemo.Pas
Executable file
392
Duane Blehm's Code/Drag Piece ƒ/DragPieceDemo.Pas
Executable file
@@ -0,0 +1,392 @@
|
||||
Program DragPieceDemo;{Thu Dec 17, 1987, <20> HomeTown Software,1987
|
||||
all rights reserved, this code not for distribution}
|
||||
{this program demonstrates use of our 'generic' DragPiece() procedure for
|
||||
animation of a 'piece' over a background. We're still trying to make the
|
||||
procedure truly independent. Currently it has some 'options' embedded
|
||||
within it for initializing the PicMap and PatchMap and also for how
|
||||
the piece is effected on completion... see DragPiece(). The procedure
|
||||
is called from TakeCareMouseDown() in window contents. }
|
||||
|
||||
{also you might want to check out the MakeBitMap() procedure, this is a big
|
||||
improvement over our old CreateOffScreenBitmap() stuff!}
|
||||
|
||||
USES MacIntf;{TML Directives}
|
||||
|
||||
{$L aDragPiece.rsrc}{link the resource file}
|
||||
|
||||
CONST
|
||||
lastMenu = 2; {Number of Menus}
|
||||
appleMenu = 1;
|
||||
fileMenu = 256;
|
||||
|
||||
VAR {global program stuff}
|
||||
myMenus: Array[1..lastMenu] of MenuHandle;
|
||||
refNum,theMenu,theItem: integer;
|
||||
Finished: Boolean;{used to terminate the program}
|
||||
ClockCursor: CursHandle; {handle to watch cursor}
|
||||
myWindow: WindowPtr;
|
||||
Screen,DragArea,GrowArea: Rect;
|
||||
|
||||
tRect:Rect;
|
||||
tPt:Point;
|
||||
DragRgn:RgnHandle;
|
||||
LogoLoc:Point;
|
||||
{----------------------------------------------}
|
||||
|
||||
procedure DrawWindowContents(WhichWindow:WindowPtr);
|
||||
var
|
||||
trect:Rect;
|
||||
tStr:Str255;
|
||||
myPic:PicHandle;
|
||||
Begin
|
||||
FillRect(whichWindow^.portRect,ltGray);
|
||||
tStr := 'Click to create a spot and then DRAG it!';
|
||||
SetRect(tRect,0,80,StringWidth(tStr) + 20,105);
|
||||
EraseRect(tRect);
|
||||
moveTo(10,100);
|
||||
DrawString(tStr);
|
||||
myPic := GetPicture(128);{logo}
|
||||
tRect := myPic^^.picFrame;
|
||||
{watchout! the window^.portRect is offset by a SetOrigin() call!}
|
||||
OffSetRect(tRect,LogoLoc.h-tRect.right,LogoLoc.v-tRect.bottom);
|
||||
DrawPicture(myPic,tRect);
|
||||
End;
|
||||
|
||||
procedure DragPiece(aWindow:WindowPtr;var theMouse:Point;
|
||||
DragRect:Rect;PieceRgn:RgnHandle);
|
||||
{aWindow is window the piece is to be dragged in, theMouse is location of
|
||||
mouseDown, DragRect limits the area the piece can be dragged within the
|
||||
window, PieceRgn is destination Region in aWindow for the piece. PieceRgn
|
||||
defines the size of the piece by its .rgnBBox and shape by the shape of
|
||||
the region... the Piece drawn into the PicMap is masked into the ComboMap
|
||||
by a copy of the PieceRgn. If no Mask is desired just pass a new Rgn set
|
||||
to the Rect in the window with a RectRgn() call. This procedure does NO
|
||||
error checking for memory available, etc., beware!}
|
||||
var
|
||||
tRgn:RgnHandle;{temp copy of PieceRgn for animation}
|
||||
PatchMap,ComboMap,PicMap,OldBits:Bitmap;
|
||||
sRect,sUnionRect,LastsRect,
|
||||
cRect,cUnionRect,LastcRect:Rect;
|
||||
MouseLoc,LastMouseLoc,tPt:Point;
|
||||
ExitToAnimate:boolean;
|
||||
MaxMove:Point;
|
||||
|
||||
procedure MakeBitMap(var theMap:Bitmap);{create a bitmap record}
|
||||
{assumes that 'theMap.bounds' is predefined rect for size and
|
||||
does NO error checking for available memory or MemErr..}
|
||||
Begin
|
||||
{following same as OffsetRect(theMap.bounds,-left,-top)}
|
||||
theMap.bounds.right := theMap.bounds.right-theMap.bounds.left;
|
||||
theMap.bounds.left := 0;
|
||||
theMap.bounds.bottom := theMap.bounds.bottom-theMap.bounds.top;
|
||||
theMap.bounds.top := 0;
|
||||
|
||||
{now with 0,0 origin.. '.right' is width, and '.bottom' is height}
|
||||
theMap.rowbytes := (((theMap.bounds.right - 1) DIV 16) + 1) * 2;
|
||||
{size of bitimage is bottom times rowBytes, potential MemError here}
|
||||
theMap.baseAddr := NewPtr(theMap.bounds.bottom * theMap.rowbytes);
|
||||
End;
|
||||
|
||||
Begin {procedure dragPiece}
|
||||
SetPt(MaxMove,20,20);{piece will move max. of 20 pixels per loop}
|
||||
{create temp. bitmaps, size Combo for MaxMove}
|
||||
PicMap.bounds := PieceRgn^^.rgnBBox;{size to contain the region}
|
||||
MakeBitMap(PicMap);{create the bitmap record.. must define .bounds first}
|
||||
PatchMap.bounds := PicMap.bounds;{same size}
|
||||
MakeBitMap(PatchMap);
|
||||
|
||||
ComboMap.bounds := PatchMap.bounds;
|
||||
{increase size to accomodate extra for drawing background/union }
|
||||
ComboMap.bounds.right := ComboMap.bounds.right + MaxMove.h;
|
||||
ComboMap.bounds.bottom := ComboMap.bounds.bottom + MaxMove.v;
|
||||
MakeBitMap(ComboMap);
|
||||
|
||||
tRgn := NewRgn;
|
||||
CopyRgn(PieceRgn,tRgn);{make a temp. copy for use in drawing}
|
||||
|
||||
{_________ PicMap must contain image to be 'dragged' ______}
|
||||
{we're just going to 'fill' the PieceRgn for this example, this bitmap
|
||||
could be passed as a parameter.}
|
||||
OldBits := aWindow^.portBits;
|
||||
SetPortBits(PicMap);{so we can quickdraw 'piece' into the PicMap}
|
||||
tRect := aWindow^.portRect;
|
||||
InsetRect(tRect,-50,-50);{in case mouse is near edge of window,clipping}
|
||||
ClipRect(tRect);
|
||||
SetOrigin(tRgn^^.rgnBBox.left,tRgn^^.rgnBBox.top);
|
||||
EraseRect(tRgn^^.rgnBBox);{erase to white first}
|
||||
FillRgn(tRgn,gray);
|
||||
FrameRgn(tRgn);
|
||||
SetOrigin(0,0);
|
||||
SetPortBits(OldBits);
|
||||
{__________________________}
|
||||
|
||||
{____ initialize PatchMap, will be background under piece _____}
|
||||
{restore, erase or draw initial BackGround under piece to PatchMap}
|
||||
SetPortBits(PatchMap);{so we can quickdraw into the PatchMap}
|
||||
{make the PatchMap topleft = to PieceRgn topleft for drawing, so
|
||||
that the correct stuff is drawn into PatchMap for Piece location
|
||||
in aWindow!}
|
||||
SetOrigin(PieceRgn^^.rgnBBox.left,PieceRgn^^.rgnBBox.top);
|
||||
EraseRect(PieceRgn^^.rgnBBox);{erase whole thing to white first}
|
||||
{note: SetOrigin effects the aWindow^.portRect!!}
|
||||
DrawWindowContents(aWindow);{draw window just like update event...}
|
||||
SetOrigin(0,0);{restore normal origin}
|
||||
SetPortBits(OldBits);
|
||||
{___________________________}
|
||||
|
||||
LastsRect := tRgn^^.rgnBBox;{last location in aWindow!}
|
||||
sRect := LastsRect;{initialize sRect for size}
|
||||
cRect := sRect;
|
||||
LastMouseLoc := theMouse;{this is where user clicked}
|
||||
MouseLoc := LastMouseLoc;
|
||||
MouseLoc.h := MouseLoc.h + 1;{this will force redraw thru first loop}
|
||||
Repeat { the entire process Until a MouseUp}
|
||||
{determine If the mouse has moved and how much}
|
||||
ExitToAnimate := false;{will flag mouse movement, need to draw stuff}
|
||||
Repeat {wait for mouse move or mouse up}
|
||||
{keep the piece on screen}
|
||||
If not (PtInRect(MouseLoc,DragRect)) then Begin {move it back in}
|
||||
If MouseLoc.h > DragRect.right then
|
||||
MouseLoc.h := DragRect.right
|
||||
Else If MouseLoc.h < DragRect.left then
|
||||
MouseLoc.h := DragRect.left;
|
||||
If MouseLoc.v > DragRect.bottom then
|
||||
MouseLoc.v := DragRect.bottom
|
||||
Else If MouseLoc.v < DragRect.top then
|
||||
MouseLoc.v := DragRect.top;
|
||||
End;
|
||||
tPt.h := MouseLoc.h - LastMouseLoc.h;{tPt is offset requested}
|
||||
tPt.v := MouseLoc.v - LastMouseLoc.v;
|
||||
If (tPt.h <> 0) OR (tPt.v <> 0) then Begin {must have moved so animate}
|
||||
{tPt move must be less than MaxMove}
|
||||
If tPt.h > MaxMove.h then tPt.h := MaxMove.h
|
||||
Else If tPt.h < -MaxMove.h then tPt.h := -MaxMove.h;
|
||||
|
||||
If tPt.v > MaxMove.v then tPt.v := MaxMove.v
|
||||
Else If tPt.v < -MaxMove.v then tPt.v := -MaxMove.v;
|
||||
|
||||
{slide sRect to new location by tPt offset}
|
||||
sRect.left := sRect.left + tPt.h;
|
||||
sRect.right := sRect.right + tPt.h;
|
||||
sRect.top := sRect.top + tPt.v;
|
||||
sRect.bottom := sRect.bottom + tPt.v;
|
||||
|
||||
{LastMouse is moved to the 'adjusted' location}
|
||||
LastMouseLoc.h := tPt.h + LastMouseLoc.h;
|
||||
LastMouseLoc.v := tPt.v + LastMouseLoc.v;
|
||||
ExitToAnimate := True;{TML users can do a 'Leave' here!}
|
||||
End;{If (abs..}
|
||||
GetMouse(MouseLoc);
|
||||
Until (not(StillDown) or ExitToAnimate);
|
||||
|
||||
{combine/union the Last and new sRects, in the aWindow/screen}
|
||||
UnionRect(LastsRect,sRect,sUnionRect);
|
||||
LastcRect := LastsRect;{copy the sRects to cRects in ComboMap}
|
||||
cRect := sRect;
|
||||
cUnionRect := sUnionRect;
|
||||
|
||||
{offset/slide all the cRects (combo) rects so cUnion is topleft}
|
||||
LastcRect.right := LastcRect.right-cUnionRect.left;
|
||||
LastcRect.left := LastcRect.left-cUnionRect.left;
|
||||
LastcRect.bottom := LastcRect.bottom-cUnionRect.top;
|
||||
LastcRect.top := LastcRect.top-cUnionRect.top;
|
||||
cRect.right := cRect.right-cUnionRect.left;
|
||||
cRect.left := cRect.left-cUnionRect.left;
|
||||
cRect.bottom := cRect.bottom-cUnionRect.top;
|
||||
cRect.top := cRect.top-cUnionRect.top;
|
||||
cUnionRect.right := cUnionRect.right-cUnionRect.left;
|
||||
cUnionRect.left := cUnionRect.left-cUnionRect.left;
|
||||
cUnionRect.bottom := cUnionRect.bottom-cUnionRect.top;
|
||||
cUnionRect.top := cUnionRect.top-cUnionRect.top;
|
||||
|
||||
{copy current screen Union to ComboMap}
|
||||
CopyBits(aWindow^.portBits,ComboMap,sUnionRect,
|
||||
cUnionRect,srcCopy,NIL);
|
||||
|
||||
{copy patch over last in combo.. will restore previous background}
|
||||
CopyBits(PatchMap,ComboMap,PatchMap.bounds,LastcRect,srcCopy,NIL);
|
||||
|
||||
CopyBits(ComboMap,PatchMap,cRect,PatchMap.bounds,srcCopy,NIL);
|
||||
|
||||
{copy the piece into new location in Combo}
|
||||
{move the tRgn to cRect to mask drawing into the Combo map}
|
||||
OffSetRgn(tRgn,cRect.left - tRgn^^.rgnBBox.left,
|
||||
cRect.top - tRgn^^.rgnBBox.top);
|
||||
Copybits(PicMap,ComboMap,PicMap.bounds,cRect,srcCopy,tRgn);
|
||||
|
||||
{copy Combo union to screen}
|
||||
CopyBits(ComboMap,aWindow^.portBits,cUnionRect,
|
||||
sUnionRect,srcCopy,NIL);
|
||||
|
||||
LastsRect := sRect;{remember where the last piece is drawn}
|
||||
Until (not(StillDown));{Until the mouse button is released,i-259}
|
||||
|
||||
{________ optional to erase the piece or leave it, etc. _____}
|
||||
{we'll restore the patch of background over the piece... erasing it}
|
||||
CopyBits(PatchMap,aWindow^.portBits,PatchMap.bounds,sRect,srcCopy,nil);
|
||||
{____________________}
|
||||
|
||||
theMouse := LastMouseLoc;{return last mouse location to caller}
|
||||
DisposPtr(PatchMap.baseAddr);{dispose of temp stuff in heap}
|
||||
DisposPtr(ComboMap.baseAddr);
|
||||
DisposPtr(PicMap.baseAddr);
|
||||
DisposeRgn(tRgn);
|
||||
End;{DragPiece procedure}
|
||||
|
||||
PROCEDURE InitThings;
|
||||
Begin
|
||||
InitGraf(@thePort); {create a grafport for the screen}
|
||||
|
||||
MoreMasters; {extra pointer blocks at the bottom of the heap}
|
||||
MoreMasters; {this is 5 X 64 master pointers}
|
||||
MoreMasters;
|
||||
MoreMasters;
|
||||
MoreMasters;
|
||||
|
||||
{get the cursors we use and lock them down - no clutter}
|
||||
ClockCursor := GetCursor(watchCursor);
|
||||
HLock(Handle(ClockCursor));
|
||||
|
||||
{show the watch while we wait for inits & setups to finish}
|
||||
SetCursor(ClockCursor^^);
|
||||
|
||||
{init everything in case the app is the Startup App}
|
||||
InitFonts; {startup the fonts manager}
|
||||
InitWindows; {startup the window manager}
|
||||
InitMenus; {startup the menu manager}
|
||||
TEInit; {startup the text edit manager}
|
||||
InitDialogs(Nil); {startup the dialog manager}
|
||||
|
||||
Finished := False; {set program terminator to false}
|
||||
FlushEvents(everyEvent,0); {clear events from previous program}
|
||||
{ set up screen size stuff }
|
||||
Screen := ScreenBits.Bounds; { Get screen dimensions from thePort }
|
||||
with Screen do Begin
|
||||
SetRect(DragArea,Left+4,Top+24,Right-4,Bottom-4);
|
||||
SetRect(GrowArea,Left,Top+24,Right,Bottom);
|
||||
End;
|
||||
End;
|
||||
|
||||
procedure CreateWindow;
|
||||
Begin
|
||||
SetRect(tRect,2,40,508,40 + 290);
|
||||
myWindow := NewWindow(Nil,tRect,'DragPiece Demo',True,4,Nil,True,0);
|
||||
SetPort(myWindow);
|
||||
ClipRect(myWindow^.portRect);
|
||||
End;
|
||||
|
||||
procedure DoMenuCommand(mResult:LongInt);
|
||||
var
|
||||
name: Str255;
|
||||
tPort: GrafPtr;
|
||||
Begin
|
||||
theMenu := HiWord(mResult);
|
||||
theItem := LoWord(mResult);
|
||||
Case theMenu of
|
||||
appleMenu:
|
||||
Begin
|
||||
GetItem(myMenus[1],theItem,name);
|
||||
refNum := OpenDeskAcc(name);
|
||||
End;
|
||||
fileMenu: Finished := True;
|
||||
End;
|
||||
HiliteMenu(0);
|
||||
End;
|
||||
|
||||
procedure TakeCareMouseDown(myEvent:EventRecord);
|
||||
var
|
||||
Location: integer;
|
||||
WhichWindow: WindowPtr;
|
||||
MouseLoc: Point;
|
||||
WindowLoc: integer;
|
||||
Begin
|
||||
MouseLoc := myEvent.Where; {Global coordinates}
|
||||
WindowLoc := FindWindow(MouseLoc,WhichWindow); {I-287}
|
||||
case WindowLoc of
|
||||
inMenuBar:
|
||||
DoMenuCommand(MenuSelect(MouseLoc));
|
||||
inSysWindow:
|
||||
SystemClick(myEvent,WhichWindow); {I-441}
|
||||
inContent:
|
||||
If WhichWindow <> FrontWindow then
|
||||
SelectWindow (WhichWindow)
|
||||
else Begin
|
||||
GlobalToLocal(MouseLoc);
|
||||
SetRect(tRect,MouseLoc.h-20,MouseLoc.v-26,
|
||||
MouseLoc.h+20,MouseLoc.v+26);
|
||||
DragRgn := NewRgn;
|
||||
OpenRgn;
|
||||
FrameOval(tRect);
|
||||
CloseRgn(DragRgn);
|
||||
|
||||
tRect := WhichWindow^.portRect;
|
||||
DragPiece(WhichWindow,MouseLoc,tRect,DragRgn);
|
||||
end;
|
||||
inGoAway:
|
||||
Finished := True;
|
||||
end; {case of}
|
||||
end; { TakeCareMouseDown }
|
||||
|
||||
procedure TakeCareActivates(myEvent:EventRecord);
|
||||
var
|
||||
WhichWindow: WindowPtr;
|
||||
Begin
|
||||
WhichWindow := WindowPtr(myEvent.message);
|
||||
SetPort(WhichWindow);
|
||||
End;
|
||||
|
||||
procedure TakeCareUpdates(Event:EventRecord);
|
||||
var
|
||||
UpDateWindow,TempPort: WindowPtr;
|
||||
Begin
|
||||
UpDateWindow := WindowPtr(Event.message);
|
||||
GetPort(TempPort);
|
||||
SetPort(UpDateWindow);
|
||||
BeginUpDate(UpDateWindow);
|
||||
EraseRect(UpDateWindow^.portRect);{ or UpdateWindow^.VisRgn^^.rgnBBox }
|
||||
DrawWindowContents(UpDateWindow);
|
||||
EndUpDate(UpDateWindow);
|
||||
SetPort(TempPort);
|
||||
End;
|
||||
|
||||
procedure MainEventLoop;
|
||||
var
|
||||
myEvent: EventRecord;
|
||||
EventAvail: Boolean;
|
||||
Begin
|
||||
InitCursor;
|
||||
Repeat
|
||||
SystemTask;
|
||||
EventAvail := GetNextEvent(EveryEvent,myEvent);
|
||||
If EventAvail then
|
||||
Case myEvent.What of
|
||||
mouseDown: TakeCareMouseDown(myEvent);
|
||||
KeyDown: Finished:= True;
|
||||
ActivateEvt:TakeCareActivates(myEvent);
|
||||
UpDateEvt: TakeCareUpdates(myEvent);
|
||||
End;
|
||||
Until Finished;
|
||||
End;
|
||||
|
||||
procedure SetUpMenus;
|
||||
var
|
||||
i: integer;
|
||||
Begin
|
||||
myMenus[1] := GetMenu(appleMenu); {get menu info from resources}
|
||||
myMenus[2] := GetMenu(fileMenu);
|
||||
For i := 1 to lastMenu do InsertMenu(myMenus[i],0);
|
||||
DrawMenuBar;
|
||||
End;
|
||||
|
||||
{Main Program begins here}
|
||||
BEGIN
|
||||
InitThings;
|
||||
MaxApplZone;
|
||||
SetUpMenus;
|
||||
CreateWindow;
|
||||
|
||||
{set destination for bottom right of our logo picture}
|
||||
SetPt(LogoLoc,myWindow^.portRect.right-20,myWindow^.portRect.bottom-20);
|
||||
|
||||
MainEventLoop;{until finished = true}
|
||||
END.
|
0
Duane Blehm's Code/Drag Piece ƒ/aDragPiece.rsrc
Executable file
0
Duane Blehm's Code/Drag Piece ƒ/aDragPiece.rsrc
Executable file
BIN
Duane Blehm's Code/More Info*/Programming the Mac.4.6
Executable file
BIN
Duane Blehm's Code/More Info*/Programming the Mac.4.6
Executable file
Binary file not shown.
1
Duane Blehm's Code/More Info*/TML Std.Procedures
Executable file
1
Duane Blehm's Code/More Info*/TML Std.Procedures
Executable file
@@ -0,0 +1 @@
|
||||
The following are TML 2.5 Standard Procedures and Functions that
|
BIN
Duane Blehm's Code/Regions ƒ/About Regions
Executable file
BIN
Duane Blehm's Code/Regions ƒ/About Regions
Executable file
Binary file not shown.
0
Duane Blehm's Code/Regions ƒ/Regions
Executable file
0
Duane Blehm's Code/Regions ƒ/Regions
Executable file
776
Duane Blehm's Code/Regions ƒ/Regions.pas
Executable file
776
Duane Blehm's Code/Regions ƒ/Regions.pas
Executable file
@@ -0,0 +1,776 @@
|
||||
Program aRegions;{Sun Aug 23, 1987 09:19:36}
|
||||
{version 0.87,copyright <20>,1987...Duane Blehm,HomeTown Software}
|
||||
|
||||
USES MacIntf;
|
||||
|
||||
{$T APPL RDBN set the TYPE and CREATOR}
|
||||
{$B+ set the application's bundle bit }
|
||||
{$L aRegions.rsrc}{link resource file stuff}
|
||||
|
||||
CONST
|
||||
lastMenu = 4; {Number of Menus}
|
||||
appleMenu = 1;
|
||||
fileMenu = 256;
|
||||
editMenu = 257;
|
||||
optionsMenu = 258;
|
||||
|
||||
TYPE
|
||||
{type the dialogs so we can access by name and add to list}
|
||||
DialogList = (Save,Help,SizeTheRgn,About,HowTo,Source);
|
||||
|
||||
VAR
|
||||
tRgn: RgnHandle; {temporary region,used to Invert DemoRgn}
|
||||
tStr: Str255;
|
||||
myPattern: Pattern; {will hold the background pattern}
|
||||
DemoRgn: RgnHandle; {region to be used in demo animation}
|
||||
DemoUnderWay: Boolean; {flag if demo is underway}
|
||||
i: integer;
|
||||
Demo,InvertDemo: ControlHandle; {Rgn Demo and Invert It! buttons}
|
||||
OffScreen: BitMap; {contains our offscreen MacPic image}
|
||||
MacPic: PicHandle; {for loading PICT resource}
|
||||
WorkRefNum: integer; {work resource file RefNum}
|
||||
alertResult: integer; {result of putting up Alert dialogs}
|
||||
DisplayStatus: integer; {what's on display,0 = nothing,1 = pic,2 = rgn}
|
||||
DialNdx: DialogList; {will step through our dialogs array}
|
||||
myDialog: Array[Save..Source] of DialogPtr;{our 'dialogList'}
|
||||
myDialogRec: Array[Save..Source] of DialogRecord;
|
||||
|
||||
WorkRect: Rect; {'work'ing/drawing area of myWindow,left side}
|
||||
CreateRgn,SaveRgn: ControlHandle; {Create Rgn,Save Rgn buttons}
|
||||
myPic: PicHandle; {Handle to Pic pasted in from Clipboard}
|
||||
PicRect: Rect; {Rect for offsetting/Drawing myPic}
|
||||
DemoBox: Rect; {Bounds for movement of demo animation}
|
||||
myRgn: RgnHandle; {Region created by alogrithm}
|
||||
RgnFrame, {Rect limits for FindRegion call...}
|
||||
tRect: Rect;
|
||||
length,offSet,
|
||||
theErr: Longint;
|
||||
|
||||
myMenus: Array[1..lastMenu] of MenuHandle;
|
||||
refNum,theMenu,
|
||||
theItem: integer;{menustuff}
|
||||
Finished: Boolean;{used to terminate the program}
|
||||
ClockCursor: CursHandle; {handle to watch cursor}
|
||||
myWindow: WindowPtr;
|
||||
wRecord: WindowRecord;
|
||||
Screen,DragArea,
|
||||
GrowArea: Rect;
|
||||
|
||||
{----------------------------------------------}
|
||||
procedure AnimateDemo;
|
||||
{animate the mac image clipped to DemoRgn}
|
||||
var
|
||||
tPoint:Point;
|
||||
dh,dv:integer;
|
||||
Begin
|
||||
GetMouse(tPoint);{get current mouse coordinates}
|
||||
|
||||
{limit mac image (PicRect) to DemoBox extremes..}
|
||||
{to keep PicRect from wondering off our visual area}
|
||||
|
||||
If not(PtInRect(tPoint,DemoBox)) then begin {force tPoint into DemoBox}
|
||||
If tPoint.h > DemoBox.right then tPoint.h := DemoBox.right
|
||||
else if tPoint.h < DemoBox.left then tPoint.h := DemoBox.left;
|
||||
If tPoint.v > DemoBox.bottom then tPoint.v := DemoBox.bottom
|
||||
else if tPoint.v < DemoBox.top then tPoint.v := DemoBox.top;
|
||||
end;
|
||||
|
||||
{determine horizontal offset if needed}
|
||||
If tPoint.h > PicRect.left + 2 then begin
|
||||
PicRect.left := PicRect.left + 3;{offsetRect to right}
|
||||
PicRect.right := PicRect.right + 3;
|
||||
end
|
||||
else if tPoint.h < PicRect.left - 2 then begin
|
||||
PicRect.left := PicRect.left - 3;{offsetRect to left}
|
||||
PicRect.right := PicRect.right - 3;
|
||||
end;
|
||||
{vertical offset?}
|
||||
If tPoint.v > PicRect.top + 1 then begin
|
||||
PicRect.top := PicRect.top + 2; {only move 2 because of pattern}
|
||||
PicRect.bottom := PicRect.bottom + 2;
|
||||
end
|
||||
else if tPoint.v < PicRect.top - 1 then begin
|
||||
PicRect.top := PicRect.top - 2; {only move 2 because of pattern}
|
||||
PicRect.bottom := PicRect.bottom - 2;
|
||||
end;
|
||||
|
||||
{ok... now draw it using the DemoRgn as a mask}
|
||||
CopyBits(OffScreen,myWindow^.portBits,OffScreen.bounds,
|
||||
PicRect,srcCopy,DemoRgn);
|
||||
end;
|
||||
|
||||
procedure CreateOffScreenBitMap; {see CopyBits stuff,also tech.note 41}
|
||||
var
|
||||
tRect: Rect;
|
||||
OffRowBytes,SizeOfOff:integer;
|
||||
OldBits:Bitmap;
|
||||
Begin
|
||||
MacPic := GetPicture(128);{load the Mac picture from resource file}
|
||||
tRect := MacPic^^.picframe;{size tRect for creating offscreen}
|
||||
|
||||
{calculate size/dimensions of OffScreen stuff}
|
||||
with tRect do begin
|
||||
OffRowBytes := (((right - left -1) div 16) +1) * 2;{has to be even!}
|
||||
SizeOfOff := (bottom - top) * OffRowBytes;
|
||||
OffSetRect(tRect,-left,-top);{move rect to 0,0 topleft}
|
||||
end; { of with }
|
||||
|
||||
OffScreen.baseAddr := QDPtr(NewPtr(SizeOfOff));{Create BitImage with Ptr}
|
||||
OffScreen.rowbytes := OffRowBytes;{bytes / row in BitImage}
|
||||
OffScreen.bounds := tRect;
|
||||
|
||||
{draw the Mac Picture into OffScreen}
|
||||
OldBits := myWindow^.portBits; {preserve old BitMap}
|
||||
SetPortBits(OffScreen); { our new BitMap }
|
||||
FillRect(OffScreen.bounds,white); {erase our new BitMap to white}
|
||||
DrawPicture(MacPic,OffScreen.bounds); {draw all the pictures}
|
||||
ReleaseResource(handle(MacPic)); {done so dump picture from memory}
|
||||
|
||||
SetPortBits(OldBits); {restore old bitmap}
|
||||
end;
|
||||
|
||||
procedure InitialDemo;{set up stuff for Demo Regions animation}
|
||||
var
|
||||
dh,dv,myErr:integer;
|
||||
begin
|
||||
myErr := noErr;{myErr will flag a resource loading error}
|
||||
If DisplayStatus = 2 then begin {use the current rgn in the demo}
|
||||
DemoRgn := NewRgn;{Create a fresh DemoRgn, disposed of the last}
|
||||
CopyRgn(myRgn,DemoRgn);{Copy of current myRgn into DemoRgn}
|
||||
end
|
||||
else begin {no current myRgn so we'll load our own in from resources}
|
||||
DemoRgn := RgnHandle(GetResource('RGN ',20843));
|
||||
myErr := ResError;{check for loading error}
|
||||
DetachResource(Handle(DemoRgn));{take control from resource Manager}
|
||||
end;
|
||||
If myErr = noErr then begin {continue if no errors where encountered}
|
||||
DemoUnderWay := True;{flag Demo animation in MainEventLoop}
|
||||
{disable menus, other controls}
|
||||
HiliteControl(CreateRgn,255);{disable}
|
||||
HiliteControl(SaveRgn,255);{disable}
|
||||
ShowControl(InvertDemo);
|
||||
DisableItem(myMenus[4],2);{size the Rgn}
|
||||
For i := 1 to LastMenu do DisableItem(myMenus[i],0);{disable menus}
|
||||
DrawMenuBar;
|
||||
SetCTitle(Demo,'End Demo');{so user can end the demo}
|
||||
EraseRect(WorkRect);{erase the work area of window}
|
||||
{find offsets to relocate DemoRgn in center of work area}
|
||||
with DemoRgn^^.rgnBBox do begin
|
||||
dh := ((WorkRect.right-(right-left)) div 2) - left;
|
||||
dv := ((WorkRect.bottom-(bottom-top)) div 2) - top;
|
||||
end;
|
||||
OffSetRgn(DemoRgn,dh,dv);{center the rgnBBox}
|
||||
FillRgn(DemoRgn,myPattern);{pattern of horizontal lines}
|
||||
FrameRgn(DemoRgn);{outline the Rgn}
|
||||
InsetRgn(DemoRgn,1,1);{so the animation won't erase Frame lines}
|
||||
DemoBox := DemoRgn^^.rgnBBox;{DemoBox will limit movement of PicRect}
|
||||
InsetRect(DemoBox,-120,-80);{expand beyond the Rgn a little}
|
||||
PicRect := OffScreen.bounds;{Size PicRect for CopyBits}
|
||||
|
||||
{we'll use Mouse location and PicRect.topleft to offset PicRect
|
||||
so subtract width and height of PicRect from DemoBox limits}
|
||||
DemoBox.right := DemoBox.right - (PicRect.right - PicRect.left);
|
||||
DemoBox.bottom := DemoBox.bottom - (PicRect.bottom - PicRect.top);
|
||||
|
||||
If not(odd(DemoBox.top)) then inc(DemoBox.top);{force odd for pattern}
|
||||
|
||||
{start the PicRect in upper left of DemoBox}
|
||||
OffSetRect(PicRect,DemoBox.left-PicRect.left,DemoBox.top-PicRect.top);
|
||||
end
|
||||
else begin
|
||||
alertResult := NoteAlert(134,nil);{sorry, bad resource}
|
||||
ResetAlrtStage;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure DisplayDialog(WhichDialog:DialogList);
|
||||
var
|
||||
tRect,fRect: Rect;
|
||||
itemHit,i,j,tIDNum,RepeatID,count: integer;
|
||||
tPort: GrafPtr;
|
||||
tHandle,nameHand,tbuf:Handle;
|
||||
tStr,nameStr:Str255;
|
||||
aLong:Longint;
|
||||
tFlag:boolean;
|
||||
theType:ResType;
|
||||
Begin
|
||||
GetPort(tPort);{save the current port}
|
||||
ShowWindow(myDialog[WhichDialog]);
|
||||
SelectWindow(myDialog[WhichDialog]);
|
||||
SetPort(myDialog[WhichDialog]); {we may draw into our dialog window}
|
||||
|
||||
Case WhichDialog of
|
||||
|
||||
HowTo:begin {text for how to use a 'RGN ' resource}
|
||||
TextFont(geneva);
|
||||
Textsize(10);
|
||||
tbuf := GetResource('TBUF',128);{text created with our TransText utility}
|
||||
HLock(tbuf);{lock it we'll be using ptr's}
|
||||
TextBox(tbuf^,GetHandleSize(tBuf),myDialog[HowTo]^.portRect,teJustLeft);
|
||||
HUnLock(tBuf);{done}
|
||||
ModalDialog(Nil,itemHit);
|
||||
end;
|
||||
|
||||
Source:begin {text for Source code offer}
|
||||
TextFont(geneva);
|
||||
Textsize(10);
|
||||
tbuf := GetResource('TBUF',129);
|
||||
HLock(tbuf);
|
||||
TextBox(tbuf^,GetHandleSize(tBuf),myDialog[Source]^.portRect,teJustLeft);
|
||||
HUnLock(tBuf);{done}
|
||||
ModalDialog(Nil,itemHit);
|
||||
end;
|
||||
|
||||
About:ModalDialog(nil,itemHit); {put up our about Regions dialog}
|
||||
|
||||
SizeTheRgn:{user input data for doing an InsetRgn call}
|
||||
Repeat
|
||||
SelIText(myDialog[SizetheRgn],5,0,32767);{select horiz.size text}
|
||||
ModalDialog(nil,itemHit);
|
||||
If itemHit = 1 then Begin {size the rgn}
|
||||
GetDItem(myDialog[SizetheRgn],5,i,tHandle,tRect);{Handle textitem}
|
||||
GetIText(tHandle,tStr);{get the horiz. size text}
|
||||
StringToNum(tStr,aLong);{convert to Number,error check?}
|
||||
i := aLong;{horiz.size}
|
||||
GetDItem(myDialog[SizetheRgn],6,j,tHandle,tRect);{vertical size}
|
||||
GetIText(tHandle,tStr);
|
||||
StringToNum(tStr,aLong);
|
||||
j := aLong;
|
||||
InsetRgn(myRgn,i,j);
|
||||
DisplayStatus := 2;{so InvalRect 'update' will draw the region}
|
||||
end;
|
||||
Until((itemHit = 1) or (itemhit = 7));{size or cancel}
|
||||
|
||||
Help:ModalDialog(nil,itemHit);{help dialog box}
|
||||
|
||||
Save: Begin {save myRgn into our work resource file}
|
||||
nameStr := 'myRegion';{set default Res. name}
|
||||
Repeat
|
||||
{get a 'unique' resID number > 128}
|
||||
Repeat
|
||||
tIDNum := UniqueID('RGN ');
|
||||
Until(tIDNum > 127);
|
||||
{install resID in item 4, name in item 3}
|
||||
NumToString(tIDNum,tStr);
|
||||
GetDItem(myDialog[Save],4,i,tHandle,tRect);
|
||||
SetIText(tHandle,tStr);{set res Id to unique ID}
|
||||
SelIText(myDialog[Save],4,0,32767);{select the res Id text}
|
||||
GetDItem(myDialog[Save],3,i,nameHand,tRect);
|
||||
SetIText(nameHand,NameStr);
|
||||
ModalDialog(Nil,itemHit); {close it no matter what was hit}
|
||||
Case itemHit of
|
||||
1:{add it} begin
|
||||
{get,check name and id, watch out for duplicates}
|
||||
GetIText(nameHand,nameStr);{nameString}
|
||||
GetIText(tHandle,tStr);
|
||||
StringtoNum(tStr,aLong);
|
||||
tIdNum := aLong;
|
||||
|
||||
{check for resource using tIDNum as ID#}
|
||||
count := CountResources('RGN ');{how many rgns}
|
||||
tFlag := True;{initial flag for duplicate Id numbers}
|
||||
If Count > 0 then {if there any RGN'S}
|
||||
For i := 1 to count do begin {step thru 'RGN ' resources}
|
||||
tHandle := GetIndResource('RGN ',i);
|
||||
GetResInfo(tHandle,j,theType,tStr);
|
||||
If j = tIdNum then tFlag := false;{id already exists!}
|
||||
end;
|
||||
|
||||
If tFlag then begin {unique id, so save it}
|
||||
UseResFile(WorkRefNum);
|
||||
AddResource(Handle(myRgn),'RGN ',tIdNum,nameStr);
|
||||
UpdateResFile(WorkRefNum);
|
||||
end
|
||||
Else begin {id alreay used, alert user, Replace it?}
|
||||
alertResult := CautionAlert(128,nil);
|
||||
ResetAlrtStage;
|
||||
If alertResult = 1 then begin {replace old with new}
|
||||
{tIDNum is the repeated ID no.!}
|
||||
tHandle := GetResource('RGN ',tIdNum);{handle to old}
|
||||
RmveResource(tHandle);{remove the old}
|
||||
UseResFile(WorkRefNum);{our Work file}
|
||||
AddResource(Handle(myRgn),'RGN ',tIdNum,nameStr);
|
||||
UpDateResFile(WorkRefNum);{force write of new}
|
||||
end
|
||||
else itemHit := 0;{Cancel,reset itemhit so won't exit Save:}
|
||||
end;{else}
|
||||
end;{1:}
|
||||
|
||||
end;{case itemhit}
|
||||
Until((itemHit = 1) or (itemHit = 2));
|
||||
end;{Save:}
|
||||
end;{Case WhichDialog}
|
||||
|
||||
HideWindow(myDialog[WhichDialog]); {put away dialog window}
|
||||
SelectWindow(myWindow);{restore our game window}
|
||||
SetPort(tPort);{restore port}
|
||||
InvalRect(WorkRect);{force redraw of 'whole' work area.. new Rgn?}
|
||||
end;
|
||||
|
||||
procedure FindRegion(tRect:Rect;var theRgn:RgnHandle);
|
||||
{be sure that tRect is in visible window on screen before executing this
|
||||
procedure to avoid system crash}
|
||||
var
|
||||
x,y:integer;
|
||||
ExitNoBlack: Boolean;
|
||||
Vector,LineVector,ExitStatus:integer;
|
||||
Original:Point;
|
||||
SizeCount:integer;
|
||||
Begin
|
||||
SetEmptyRgn(theRgn);{in case we have to abort, will return empty}
|
||||
{scanning by 'pixels' with GetPixel() ... 'pixel' is right and left
|
||||
of the 'Coordinate' so move inside 1 coordinate}
|
||||
dec(tRect.right);
|
||||
dec(tRect.bottom);
|
||||
x := tRect.left;{we'll begin in topleft, looking for topleftmost black pixel}
|
||||
y := tRect.top;
|
||||
{find upper left black pixel}
|
||||
ExitNoBlack := false;
|
||||
While ((not GetPixel(x,y)) and (not ExitNoBlack)) do
|
||||
Begin
|
||||
If x < tRect.right then inc(x) {move right on line}
|
||||
else begin {move down to next line}
|
||||
x := tRect.left;{reset x to left side of line}
|
||||
If y < tRect.bottom then inc(y)
|
||||
else ExitNoBlack := true; {exit!,didn't find any black pixels}
|
||||
end;{else}
|
||||
end;{while}
|
||||
|
||||
If not(ExitNoBlack) then begin {have a Black pixel..x,y so start region}
|
||||
OpenRgn;
|
||||
SetPt(Original,x,y); {keep track of starting point}
|
||||
MoveTo(x,y);
|
||||
|
||||
LineVector := 1;{track direction of line, won't LineTo() until it changes}
|
||||
Vector := 1; {first vector is down (1)}
|
||||
inc(y);{move coordinates to next}
|
||||
ExitStatus := 0;{1 = 'Original' found, rgn complete, 2 = rgn too large}
|
||||
SizeCount := 0;{count LineTo's for size of region,avoid overflow}
|
||||
|
||||
{from Original begin 'counterclockwise' circuit around Black pixel border}
|
||||
Repeat
|
||||
Case Vector of {case 'last vector move' of.. get next vector}
|
||||
1: Begin {last vector move was down}
|
||||
{if pixel left and below is black then move left}
|
||||
If GetPixel(x-1,y) then Vector := 4
|
||||
|
||||
{if not, then check pixel right and below... move down}
|
||||
else If GetPixel(x,y) then Vector := 1
|
||||
{if not, then must be pixel right and above... move right}
|
||||
else Vector := 2;
|
||||
end;
|
||||
2: Begin {last was right}
|
||||
If GetPixel(x,y) then Vector := 1
|
||||
else If GetPixel(x,y-1) then Vector := 2
|
||||
else Vector := 3;
|
||||
end;
|
||||
3: Begin {last was move up}
|
||||
If GetPixel(x,y-1) then Vector := 2
|
||||
else If GetPixel(x-1,y-1) then Vector := 3
|
||||
else Vector := 4;
|
||||
end;
|
||||
4: Begin {last was move left}
|
||||
If GetPixel(x-1,y-1) then Vector := 3
|
||||
else If GetPixel(x-1,y) then Vector := 4
|
||||
else Vector := 1;
|
||||
end;{of case 4:}
|
||||
End; {of case vector}
|
||||
|
||||
If Vector <> LineVector then begin{new direction,end of current 'line'}
|
||||
SystemTask;{keep system happy?}
|
||||
LineTo(x,y);{include line into region}
|
||||
|
||||
{sizeCount limits number of LineTo()'s, to avoid Stack crashes}
|
||||
If SizeCount < 4000 then inc(SizeCount) {we'll get another line}
|
||||
else begin {too much!, getting too big!.. abort the region}
|
||||
ExitStatus := 2;{force exit of loop}
|
||||
LineTo(Original.h,Original.v);{we'll show the Region}
|
||||
end;
|
||||
|
||||
LineVector := Vector;{start a new line}
|
||||
end;
|
||||
|
||||
Case Vector of {we checked for new 'line',etc. so move coordinates}
|
||||
1:inc(y);{vector moves down}
|
||||
2:inc(x);{vector moves right}
|
||||
3:dec(y);{moves up}
|
||||
4:dec(x);{moves left}
|
||||
end;{case vector}
|
||||
|
||||
If x = Original.h then {is the new Coordinate our 'Original'}
|
||||
If y = Original.v then begin
|
||||
ExitStatus := 1;{finished if it is!,will force exit}
|
||||
LineTo(x,y);{last line}
|
||||
end;
|
||||
|
||||
Until (ExitStatus <> 0);{until we get back to start or too large}
|
||||
|
||||
CloseRgn(theRgn);{we're done so close the rgn}
|
||||
InitCursor;{in case of alerts}
|
||||
If ExitStatus = 2 then begin {display the abort rgn alert}
|
||||
alertResult := NoteAlert(136,nil);{rgn aborted too big}
|
||||
ResetAlrtStage;
|
||||
end;
|
||||
end {if not(Done)}
|
||||
else begin {display no black pix alert}
|
||||
InitCursor;{show arrow cursor for alert}
|
||||
alertResult := NoteAlert(135,nil);{no black pixels}
|
||||
ResetAlrtStage;
|
||||
end;
|
||||
End;
|
||||
|
||||
procedure DrawWindowContents(WhichWindow:WindowPtr);
|
||||
{Remember to SetPort first, response to update event}
|
||||
var
|
||||
trect:Rect;
|
||||
i:integer;
|
||||
tRgn:RgnHandle;
|
||||
tStr:Str255;
|
||||
Begin
|
||||
ClipRect(WorkRect);{limit drawing to WorkRect}
|
||||
Case DisplayStatus of
|
||||
1:Begin {picture on display}
|
||||
DrawPicture(myPic,PicRect);{draw clipboard picture}
|
||||
end;
|
||||
2:Begin {region on display}
|
||||
OffSetRgn(myRgn,5-myRgn^^.rgnBBox.left,5-myRgn^^.rgnBBox.top);
|
||||
FillRgn(myRgn,ltGray);
|
||||
FrameRgn(myRgn);{will appear same coords as pict}
|
||||
end;
|
||||
end;{case displayStatus}
|
||||
ClipRect(myWindow^.portRect);{set clip to window borders.. controls}
|
||||
MoveTo(WorkRect.right,WorkRect.top);{draw right work border line}
|
||||
LineTo(WorkRect.right,WorkRect.bottom);
|
||||
DrawControls(WhichWindow);
|
||||
End;
|
||||
|
||||
PROCEDURE InitThings;
|
||||
Begin
|
||||
InitGraf(@thePort); {create a grafport for the screen}
|
||||
|
||||
MoreMasters; {extra pointer blocks at the bottom of the heap}
|
||||
MoreMasters; {this is 5 X 64 master pointers}
|
||||
MoreMasters;
|
||||
MoreMasters;
|
||||
MoreMasters;
|
||||
|
||||
{get the cursors we use and lock them down - no clutter}
|
||||
ClockCursor := GetCursor(watchCursor);
|
||||
HLock(Handle(ClockCursor));
|
||||
|
||||
{show the watch while we wait for inits & setups to finish}
|
||||
SetCursor(ClockCursor^^);
|
||||
|
||||
{init everything in case the app is the Startup App}
|
||||
InitFonts; {startup the fonts manager}
|
||||
InitWindows; {startup the window manager}
|
||||
InitMenus; {startup the menu manager}
|
||||
TEInit; {startup the text edit manager}
|
||||
InitDialogs(Nil); {startup the dialog manager}
|
||||
|
||||
Finished := False; {set program terminator to false}
|
||||
FlushEvents(everyEvent,0); {clear events from previous program}
|
||||
{ set up screen size stuff }
|
||||
Screen := ScreenBits.Bounds; { Get screen dimensions from thePort }
|
||||
with Screen do { Screen.Left, etc. }
|
||||
Begin
|
||||
SetRect(DragArea,Left+4,Top+24,Right-4,Bottom-4);
|
||||
SetRect(GrowArea,Left,Top+24,Right,Bottom);
|
||||
End;
|
||||
End;
|
||||
|
||||
procedure CreateWindow;
|
||||
var
|
||||
tRect: Rect;
|
||||
Begin
|
||||
SetRect(tRect,2,24,508,338);{size the window}
|
||||
|
||||
myWindow := NewWindow(@wRecord,tRect,'',True,2,Nil,True,0);
|
||||
|
||||
SetRect(tRect,0,0,520,340);{size of clip rgn}
|
||||
For DialNdx := Save to Source do begin {read all the dialogs into array}
|
||||
myDialog[DialNdx] :=
|
||||
GetNewDialog(ord(DialNdx)+128,@myDialogRec[DialNdx],myWindow);
|
||||
SetPort(myDialog[DialNdx]);
|
||||
ClipRect(tRect);{set clip to smaller size..}
|
||||
end;
|
||||
|
||||
SetPort(myWindow);
|
||||
ClipRect(tRect);
|
||||
|
||||
SetRect(tRect,416,35,502,59);{size/location of 1st control button}
|
||||
CreateRgn := NewControl(myWindow,tRect,'Create Rgn',True,0,0,0,0,0);
|
||||
OffSetRect(tRect,0,36);
|
||||
SaveRgn := NewControl(myWindow,tRect,'Save Rgn',True,0,0,0,0,0);
|
||||
OffSetRect(tRect,0,36);
|
||||
Demo := NewControl(myWindow,tRect,'Rgn Demo',True,0,0,0,0,0);
|
||||
OffSetRect(tRect,0,36);
|
||||
InvertDemo := NewControl(myWindow,tRect,'Invert It!',False,0,0,0,0,0);
|
||||
End;
|
||||
|
||||
procedure DoMenuCommand(mResult:LongInt);
|
||||
var
|
||||
name: Str255;
|
||||
tPort: GrafPtr;
|
||||
Begin
|
||||
theMenu := HiWord(mResult);
|
||||
theItem := LoWord(mResult);
|
||||
Case theMenu of
|
||||
appleMenu: Begin
|
||||
If theItem = 1 then DisplayDialog(About)
|
||||
Else begin
|
||||
GetPort(tPort);
|
||||
GetItem(myMenus[1],theItem,name);{must be a desk acc.}
|
||||
refNum := OpenDeskAcc(name);
|
||||
SetPort(tPort);
|
||||
end;
|
||||
End;
|
||||
fileMenu: Finished := True;
|
||||
editMenu:
|
||||
{if systemEdit returns false then process click at our end}
|
||||
If not(SystemEdit(theItem - 1)) then
|
||||
Case theItem of
|
||||
5:begin {paste}
|
||||
{call GetScrap and draw picture into window}
|
||||
length := GetScrap(Handle(myPic),'PICT',offset);
|
||||
If length < 0 then begin {no PICT type scrap available!}
|
||||
alertResult := NoteAlert(129,nil);{sorry no picture}
|
||||
ResetAlrtStage;
|
||||
end
|
||||
else begin {we've got a picture waiting, 'paste' it}
|
||||
PicRect := myPic^^.picframe;
|
||||
OffSetRect(PicRect,5 - PicRect.left,5 - PicRect.top);
|
||||
{check to see it picture is too large for work area}
|
||||
If (PicRect.right > (WorkRect.right-6)) or
|
||||
(PicRect.bottom > (WorkRect.bottom-6)) then Begin
|
||||
{alert user... pic too large!}
|
||||
alertResult := NoteAlert(130,nil);
|
||||
ResetAlrtStage;
|
||||
DisplayStatus := 0;{display nothing}
|
||||
InvalRect(WorkRect);{force update redraw of work}
|
||||
end
|
||||
else begin {draw the scrap picture!}
|
||||
EraseRect(WorkRect);
|
||||
ClipRect(WorkRect);
|
||||
DrawPicture(myPic,PicRect);
|
||||
ClipRect(myWindow^.portRect);
|
||||
RgnFrame := PicRect;
|
||||
{enlarge by one pixel,to ensure white pixel border!}
|
||||
InsetRect(RgnFrame,-1,-1);
|
||||
DisplayStatus := 1;{flag picture on display}
|
||||
HiliteControl(CreateRgn,0);{enable create a rgn}
|
||||
HiliteControl(SaveRgn,255);{disable}
|
||||
DisableItem(myMenus[4],2);{size}
|
||||
end;{else}
|
||||
end;{else}
|
||||
end;{5:}
|
||||
6:begin {clear to original start up status}
|
||||
DisplayStatus := 0;
|
||||
InvalRect(myWindow^.portRect);
|
||||
HiliteControl(CreateRgn,255);
|
||||
HiliteControl(SaveRgn,255);{disable}
|
||||
DisableItem(myMenus[4],2);{size}
|
||||
end;{6:}
|
||||
end;{case theitem}
|
||||
|
||||
optionsMenu:
|
||||
Case theItem of
|
||||
1:DisplayDialog(Help);
|
||||
2:DisplayDialog(SizeTheRgn);
|
||||
3:DisplayDialog(HowTo);
|
||||
4:DisplayDialog(Source);
|
||||
end;{case theItem}
|
||||
End;
|
||||
HiliteMenu(0);{take hilite off menubar}
|
||||
End;
|
||||
|
||||
procedure TakeCareControls(whichControl:ControlHandle;localMouse:point);
|
||||
var
|
||||
ControlHit,i: integer;
|
||||
refnum:integer;
|
||||
Begin
|
||||
ControlHit := TrackControl(whichControl,localMouse,nil); { Find out which}
|
||||
If ControlHit > 0 then {i-417}
|
||||
Begin
|
||||
If whichControl = CreateRgn then Begin
|
||||
{handle a hit in the Create region button}
|
||||
SetCursor(ClockCursor^^);{while we work on the region}
|
||||
myRgn := NewRgn;
|
||||
FindRegion(RgnFrame,myRgn);
|
||||
DisplayStatus := 2;
|
||||
InvalRect(workRect);
|
||||
HiliteControl(CreateRgn,255);{disable}
|
||||
HiliteControl(SaveRgn,0);
|
||||
EnableItem(myMenus[4],2);{size rgn}
|
||||
End;
|
||||
If whichControl = SaveRgn then Begin
|
||||
DisplayDialog(Save);{will handle all the save stuff}
|
||||
end;
|
||||
If whichControl = Demo then begin {could be begin or end of demo!}
|
||||
If DemoUnderWay then begin {then end it}
|
||||
DemoUnderWay := False;{stop the animation}
|
||||
{enable menus, other controls}
|
||||
SetCTitle(Demo,'Rgn Demo');
|
||||
HideControl(InvertDemo);
|
||||
InvalRect(WorkRect);
|
||||
For i := 1 to LastMenu do EnableItem(myMenus[i],0);
|
||||
DrawMenuBar;
|
||||
DisposHandle(Handle(DemoRgn));{dump DemoRgn from memory}
|
||||
If DisplayStatus = 2 then begin {still have a valid myRgn}
|
||||
HiliteControl(SaveRgn,0);
|
||||
EnableItem(myMenus[4],2);{size rgn}
|
||||
end
|
||||
else DisplayStatus := 0;{won't preserve picture?}
|
||||
end {if demoUnderway begin}
|
||||
else InitialDemo; {start the demo}
|
||||
end;{if whichcontrol}
|
||||
If whichControl = InvertDemo then Begin {invert the region}
|
||||
FillRgn(DemoRgn,white);{fill with white, will erase pattern,etc.}
|
||||
FrameRgn(DemoRgn);{frame is just 'inside' the rgn}
|
||||
RectRgn(tRgn,WorkRect);{tRgn of WorkRect}
|
||||
DiffRgn(tRgn,DemoRgn,DemoRgn);{DemoRgn out of tRgn,new in DemoRgn}
|
||||
FillRgn(DemoRgn,myPattern);{Fill new DemoRgn with horz.lines}
|
||||
HideControl(InvertDemo);{we can't invert it again.. so hide button}
|
||||
end;
|
||||
End; {of If ControlHit}
|
||||
End; { of procedure}
|
||||
|
||||
procedure TakeCareMouseDown(myEvent:EventRecord);
|
||||
var
|
||||
Location: integer;
|
||||
WhichWindow: WindowPtr;
|
||||
MouseLoc: Point;
|
||||
WindowLoc: integer;
|
||||
ControlHit: integer;
|
||||
WhichControl:ControlHandle;
|
||||
Begin
|
||||
MouseLoc := myEvent.Where; {Global coordinates}
|
||||
WindowLoc := FindWindow(MouseLoc,WhichWindow); {I-287}
|
||||
case WindowLoc of
|
||||
inMenuBar:
|
||||
DoMenuCommand(MenuSelect(MouseLoc));
|
||||
inSysWindow:
|
||||
SystemClick(myEvent,WhichWindow); {I-441,scrapbook,etc.}
|
||||
inContent:
|
||||
If WhichWindow <> FrontWindow then
|
||||
SelectWindow(WhichWindow) {bring window to front}
|
||||
else Begin {check for hit in control buttons}
|
||||
GlobaltoLocal(MouseLoc);
|
||||
ControlHit := FindControl(MouseLoc,whichWindow,whichControl);
|
||||
If ControlHit > 0 then TakeCareControls(whichControl,Mouseloc);
|
||||
end;
|
||||
end; {case of}
|
||||
end; { TakeCareMouseDown }
|
||||
|
||||
procedure TakeCareActivates(myEvent:EventRecord);
|
||||
var
|
||||
WhichWindow: WindowPtr;
|
||||
Begin
|
||||
WhichWindow := WindowPtr(myEvent.message);
|
||||
If odd(myEvent.modifiers) then begin {becoming active}
|
||||
SetPort(WhichWindow);
|
||||
{disable undo,cut,copy}
|
||||
DisableItem(myMenus[3],1);
|
||||
DisableItem(myMenus[3],3);
|
||||
DisableItem(myMenus[3],4);
|
||||
end
|
||||
else begin {deactivated must be desk accessory}
|
||||
{enable all the Edit stuff}
|
||||
For i := 1 to 6 do EnableItem(myMenus[3],i);{for DA's}
|
||||
end;
|
||||
End;
|
||||
|
||||
procedure TakeCareUpdates(Event:EventRecord);
|
||||
var
|
||||
UpDateWindow,TempPort: WindowPtr;
|
||||
Begin
|
||||
UpDateWindow := WindowPtr(Event.message);
|
||||
GetPort(TempPort);
|
||||
SetPort(UpDateWindow);
|
||||
BeginUpDate(UpDateWindow);
|
||||
EraseRect(UpDateWindow^.portRect);
|
||||
DrawWindowContents(UpDateWindow);
|
||||
EndUpDate(UpDateWindow);
|
||||
SetPort(TempPort);
|
||||
End;
|
||||
|
||||
procedure TakeCareKeyDown(Event:EventRecord);
|
||||
Var
|
||||
KeyCode,i: integer;
|
||||
CharCode: char;
|
||||
Begin
|
||||
{ KeyCode := LoWord(BitAnd(Event.message,keyCodeMask)) div 256; not used }
|
||||
CharCode := chr(LoWord(BitAnd(Event.message,CharCodeMask)));
|
||||
|
||||
If BitAnd(Event.modifiers,CmdKey) = CmdKey then begin
|
||||
{key board command - probably a menu command}
|
||||
DoMenuCommand(MenuKey(CharCode));
|
||||
end;
|
||||
End;
|
||||
|
||||
procedure MainEventLoop;
|
||||
var
|
||||
myEvent: EventRecord;
|
||||
EventAvail: Boolean;
|
||||
Begin
|
||||
InitCursor;
|
||||
Repeat
|
||||
SystemTask;
|
||||
If GetNextEvent(EveryEvent,myEvent) then
|
||||
Case myEvent.What of
|
||||
mouseDown: TakeCareMouseDown(myEvent);
|
||||
KeyDown: TakeCareKeyDown(myEvent);
|
||||
ActivateEvt: TakeCareActivates(myEvent);
|
||||
UpDateEvt: TakeCareUpdates(myEvent);
|
||||
End
|
||||
else If DemoUnderWay then AnimateDemo;{animate one step of demo}
|
||||
Until Finished;
|
||||
End;
|
||||
|
||||
procedure SetUpMenus;
|
||||
var
|
||||
i: integer;
|
||||
Begin
|
||||
myMenus[1] := GetMenu(appleMenu); {get menu info from resources}
|
||||
AddResMenu(myMenus[1],'DRVR'); {add in all the DA's}
|
||||
myMenus[2] := GetMenu(fileMenu);
|
||||
myMenus[3] := GetMenu(editMenu);
|
||||
myMenus[4] := GetMenu(optionsMenu);
|
||||
DisableItem(myMenus[4],2);{size region}
|
||||
For i := 1 to lastMenu do
|
||||
begin
|
||||
InsertMenu(myMenus[i],0);
|
||||
end;
|
||||
DrawMenuBar;
|
||||
End;
|
||||
|
||||
procedure CloseStuff;
|
||||
Begin
|
||||
{always kill sound i/o before quit}
|
||||
CloseResFile(WorkRefNum);{close work resource file}
|
||||
End;
|
||||
|
||||
{Main Program begins here}
|
||||
BEGIN
|
||||
InitThings;
|
||||
MaxApplZone;{grow application zone to max... Scrapbook uses appl.heap}
|
||||
theErr := ZeroScrap;{initialize the Scrap, erases any existing scrap, i-458}
|
||||
SetUpMenus;
|
||||
CreateWindow;
|
||||
CreateOffScreenBitMap;
|
||||
myPic := picHandle(NewHandle(0));{create valid handle for GetScrap call}
|
||||
myRgn := NewRgn;{create the rgns}
|
||||
tRgn := NewRgn;
|
||||
WorkRect := myWindow^.portRect;{size the work area of window}
|
||||
WorkRect.right := 410;
|
||||
DisplayStatus := 0;{nothing is on display}
|
||||
HiliteControl(CreateRgn,255);{disable}
|
||||
HiliteControl(SaveRgn,255);{disable}
|
||||
CreateResFile('RgnWork.rsrc');{no action if it already exists}
|
||||
{will be created in same folder as Regions application?}
|
||||
WorkRefNum := OpenResFile('RgnWork.rsrc');{open for action.. save}
|
||||
DemoUnderWay := false;{no demo to start}
|
||||
GetIndPattern(myPattern,sysPatListID,25);{horiz.line pattern in systemfile}
|
||||
MainEventLoop;
|
||||
CloseStuff;
|
||||
END.
|
0
Duane Blehm's Code/Regions ƒ/RgnWork.rsrc
Executable file
0
Duane Blehm's Code/Regions ƒ/RgnWork.rsrc
Executable file
35
Duane Blehm's Code/Regions ƒ/aRegions.R
Executable file
35
Duane Blehm's Code/Regions ƒ/aRegions.R
Executable file
@@ -0,0 +1,35 @@
|
||||
* aRegions.R
|
||||
|
||||
aRegions.rsrc
|
||||
|
||||
TYPE RDBN = STR
|
||||
,0
|
||||
Regions ver0.87, Duane Blehm, 8/87
|
||||
|
||||
TYPE MENU
|
||||
,1
|
||||
\14
|
||||
About Regions..
|
||||
(-
|
||||
|
||||
,256
|
||||
File
|
||||
Quit /Q
|
||||
|
||||
,257
|
||||
Edit
|
||||
Undo /Z
|
||||
(-
|
||||
Cut /X
|
||||
Copy /C
|
||||
Paste /V
|
||||
Clear
|
||||
|
||||
,258
|
||||
Options
|
||||
Help
|
||||
Size Region..
|
||||
Using Rgns..
|
||||
Source offer..
|
||||
|
||||
INCLUDE aRegions/Rsrc
|
0
Duane Blehm's Code/Regions ƒ/aRegions:Rsrc
Executable file
0
Duane Blehm's Code/Regions ƒ/aRegions:Rsrc
Executable file
1
Duane Blehm's Code/StuntCopter ƒ/About StuntCopter files..
Executable file
1
Duane Blehm's Code/StuntCopter ƒ/About StuntCopter files..
Executable file
@@ -0,0 +1 @@
|
||||
About the StuntCopter files:
|
16
Duane Blehm's Code/StuntCopter ƒ/Anim.R
Executable file
16
Duane Blehm's Code/StuntCopter ƒ/Anim.R
Executable file
@@ -0,0 +1,16 @@
|
||||
* Anim.R
|
||||
|
||||
Anim.rsrc
|
||||
|
||||
TYPE MENU
|
||||
,1
|
||||
\14
|
||||
|
||||
,256
|
||||
File
|
||||
OffScreen..
|
||||
Quit
|
||||
|
||||
* will include Pict resource file built with ResEdit and ScrapBook
|
||||
INCLUDE Anim/rsrc
|
||||
|
33
Duane Blehm's Code/StuntCopter ƒ/StuntCopter.R
Executable file
33
Duane Blehm's Code/StuntCopter ƒ/StuntCopter.R
Executable file
@@ -0,0 +1,33 @@
|
||||
* StuntCopter.R
|
||||
|
||||
aSCopt.rsrc
|
||||
|
||||
TYPE COPT = STR
|
||||
,0
|
||||
StuntCopter 1.5.. by Duane Blehm, 7/87
|
||||
|
||||
TYPE MENU
|
||||
,1
|
||||
\14
|
||||
About Stunt...
|
||||
(-
|
||||
|
||||
,256
|
||||
File
|
||||
Quit /Q
|
||||
|
||||
,257
|
||||
Options
|
||||
! Sound
|
||||
Reset HiScore
|
||||
Help..
|
||||
Set Speed..
|
||||
Source Code..
|
||||
OffScreen..
|
||||
|
||||
,258
|
||||
(Backspace to Exit)
|
||||
Hi!
|
||||
|
||||
* the rest of the resources where built with ResEdit in StuntCopter.Rsrc
|
||||
INCLUDE StuntCopter/Rsrc
|
1823
Duane Blehm's Code/StuntCopter ƒ/StuntCopter.pas
Executable file
1823
Duane Blehm's Code/StuntCopter ƒ/StuntCopter.pas
Executable file
File diff suppressed because it is too large
Load Diff
BIN
Duane Blehm's Code/StuntCopter ƒ/StuntCopter.shapes
Executable file
BIN
Duane Blehm's Code/StuntCopter ƒ/StuntCopter.shapes
Executable file
Binary file not shown.
0
Duane Blehm's Code/StuntCopter ƒ/StuntCopter1.5
Executable file
0
Duane Blehm's Code/StuntCopter ƒ/StuntCopter1.5
Executable file
0
Duane Blehm's Code/StuntCopter ƒ/StuntCopter:Rsrc
Executable file
0
Duane Blehm's Code/StuntCopter ƒ/StuntCopter:Rsrc
Executable file
BIN
Duane Blehm's Code/Zero Gravityƒ/About Zero Animation
Executable file
BIN
Duane Blehm's Code/Zero Gravityƒ/About Zero Animation
Executable file
Binary file not shown.
1
Duane Blehm's Code/Zero Gravityƒ/About Zero files..
Executable file
1
Duane Blehm's Code/Zero Gravityƒ/About Zero files..
Executable file
@@ -0,0 +1 @@
|
||||
About the ZeroGravity files:
|
BIN
Duane Blehm's Code/Zero Gravityƒ/Game Animation
Executable file
BIN
Duane Blehm's Code/Zero Gravityƒ/Game Animation
Executable file
Binary file not shown.
0
Duane Blehm's Code/Zero Gravityƒ/ZeroGravity
Executable file
0
Duane Blehm's Code/Zero Gravityƒ/ZeroGravity
Executable file
35
Duane Blehm's Code/Zero Gravityƒ/ZeroGravity.R
Executable file
35
Duane Blehm's Code/Zero Gravityƒ/ZeroGravity.R
Executable file
@@ -0,0 +1,35 @@
|
||||
* ZeroGravity.R
|
||||
|
||||
ZeroGravity.rsrc
|
||||
|
||||
TYPE ZGRV = STR
|
||||
,0
|
||||
ZeroGravity ver1.0, by Duane Blehm, 2/12/87
|
||||
|
||||
TYPE MENU
|
||||
,1
|
||||
\14
|
||||
About Zero...
|
||||
(-
|
||||
|
||||
,256
|
||||
File
|
||||
Quit /Q
|
||||
|
||||
,257
|
||||
Options
|
||||
Help...
|
||||
LoScore...
|
||||
! Sound
|
||||
|
||||
,258
|
||||
Works
|
||||
Peek OffScreen
|
||||
Source Code...
|
||||
|
||||
,259
|
||||
(Any Key to Exit)
|
||||
Hi!
|
||||
|
||||
* the rest of the resources where built with ResEdit
|
||||
INCLUDE ZeroGravity/Rsrc
|
1906
Duane Blehm's Code/Zero Gravityƒ/ZeroGravity.pas
Executable file
1906
Duane Blehm's Code/Zero Gravityƒ/ZeroGravity.pas
Executable file
File diff suppressed because it is too large
Load Diff
0
Duane Blehm's Code/Zero Gravityƒ/ZeroGravity:Rsrc
Executable file
0
Duane Blehm's Code/Zero Gravityƒ/ZeroGravity:Rsrc
Executable file
16
Makefile
Normal file
16
Makefile
Normal file
@@ -0,0 +1,16 @@
|
||||
# Tested only on Mac OS X, YMMV, etc
|
||||
|
||||
all: unzip detab
|
||||
|
||||
unzip:
|
||||
unzip -o Duane\ Blehm\'s\ Code.zip >/dev/null
|
||||
|
||||
detab: unzip
|
||||
cp -Rp Duane\ Blehm\'s\ Code Duane\ Blehm\'s\ Code.bak
|
||||
( cd Duane\ Blehm\'s\ Code && find . -name '*.[pP]as' -exec tab2space -lf -t3 {} {} \; )
|
||||
( cd Duane\ Blehm\'s\ Code && find . -name '*.[pP]as' -exec perl -i -p -e "s/ +\Z//" {} \; )
|
||||
( cd Duane\ Blehm\'s\ Code && find . -name '*.[rR]' -exec tab2space -lf {} {} \; )
|
||||
( cd Duane\ Blehm\'s\ Code && find . -name '*.txt' -exec tab2space -lf {} {} \; )
|
||||
( cd Duane\ Blehm\'s\ Code && find . -exec touch -r ../Duane\ Blehm\'s\ Code.bak/{} {} \; )
|
||||
rm -r Duane\ Blehm\'s\ Code.bak
|
||||
|
87
README.md
Normal file
87
README.md
Normal file
@@ -0,0 +1,87 @@
|
||||
# Duane Blehm's Code
|
||||
|
||||
This is an archive of the Duane Blehm's source code. Duane Blehm was an
|
||||
early game developer for the Macintosh. He released three games in the
|
||||
1980's:
|
||||
[Zero Gravity](http://www.macintoshrepository.org/4249-zero-gravity-),
|
||||
[StuntCopter](http://www.macintoshrepository.org/5314-stuntcopter), and
|
||||
[Cairo ShootOut!](http://www.macintoshrepository.org/4856-cairo-shootout-).
|
||||
|
||||
As a preteen computer nerd and budding developer, I not only loved the
|
||||
games, but also had an interest in how a real application was made.
|
||||
The About screens for the games offered source code printouts and unlock
|
||||
codes for a small fee, so I saved up my allowance for a month or two,
|
||||
stuffed a few bills and a note into an envelope, and mailed it off.
|
||||
|
||||
I received a reply about a year later. It was from Blehm's parents,
|
||||
gently explaining that their son had passed away and they couldn't offer
|
||||
the unlock codes. They returned my money. I was too young and lucky to
|
||||
have much experience with death. When I read the news, I remember
|
||||
feeling a pang of... something. I never forgot this feeling, and I
|
||||
never forgot about the source code.
|
||||
|
||||
Some years later (a little over fifteen of them), Apple released a
|
||||
Newton that ran NeXTSTEP and had cell phone radio. I was done becoming
|
||||
a programmer and on to becoming a better one. I thought that porting
|
||||
Zero Gravity to the iPhone would be a fun project, and began looking for
|
||||
the source code again so that I could get the physics exactly right.
|
||||
|
||||
Despite the best efforts of a small LiveJournal community, I came up
|
||||
empty. I had enough other projects that I lost interest in that one
|
||||
for the time being.
|
||||
|
||||
But, just like before, I never stopped thinking about the code.
|
||||
I decided earlier this year that it had been long enough since my last
|
||||
try, and in 2016 the venue of choice was Twitter. I pecked out a short
|
||||
plea for help, and in a hail-mary attempt to reach someone who had some
|
||||
idea of how to help, I cc'ed Avadis Tevanian, Jr., who most people know
|
||||
as a longtime VP at Apple but I remember primarily as the developer of
|
||||
a beloved Missile Command port called MacCommand, and John Calhoun, who
|
||||
wrote the fantastic paper-airplane game Glider.
|
||||
|
||||
Avi Tevanian doesn't tweet, really. But John Calhoun did. Suddenly I
|
||||
had the source code.
|
||||
|
||||
So here it is, offered without license or warranty, the code for all
|
||||
three of Duane Blehm's releases. I've converted line endings to LF and
|
||||
detabbed the files according to Blehm's preference for three-space tab
|
||||
stops, and I wrote this README and a top-level Makefile, but the rest was
|
||||
his and now it's ours.
|
||||
|
||||
Rest in peace, Duane Blehm. Thanks for the games.
|
||||
|
||||
|
||||
## Contents
|
||||
|
||||
├── Duane Blehm's Code Data forks
|
||||
│ ├── Animation ƒ
|
||||
│ ├── Cairo ƒ
|
||||
│ ├── Copy Mask ƒ
|
||||
│ ├── Drag Piece ƒ
|
||||
│ ├── More Info*
|
||||
│ ├── Regions ƒ
|
||||
│ ├── StuntCopter ƒ
|
||||
│ └── Zero Gravityƒ
|
||||
│
|
||||
├── __MACOSX Resource forks
|
||||
│ └── Duane Blehm's Code
|
||||
│ ├── Animation ƒ
|
||||
│ ├── Cairo ƒ
|
||||
│ ├── Copy Mask ƒ
|
||||
│ ├── Drag Piece ƒ
|
||||
│ ├── More Info*
|
||||
│ ├── Regions ƒ
|
||||
│ ├── StuntCopter ƒ
|
||||
│ └── Zero Gravityƒ
|
||||
│
|
||||
├── Duane Blehm's Code.zip Original source dump
|
||||
│
|
||||
├── Makefile Run `make` to rebuild this archive
|
||||
│
|
||||
└── README.md This file
|
||||
|
||||
|
||||
## Maintainer
|
||||
|
||||
Pete Gamache, [pete@gamache.org](mailto:pete@gamache.org).
|
||||
|
BIN
__MACOSX/._Duane Blehm's Code
Normal file
BIN
__MACOSX/._Duane Blehm's Code
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/._.DS_Store
Normal file
BIN
__MACOSX/Duane Blehm's Code/._.DS_Store
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/._Animation ƒ
Normal file
BIN
__MACOSX/Duane Blehm's Code/._Animation ƒ
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/._Cairo ƒ
Normal file
BIN
__MACOSX/Duane Blehm's Code/._Cairo ƒ
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/._Copy Mask ƒ
Normal file
BIN
__MACOSX/Duane Blehm's Code/._Copy Mask ƒ
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/._Drag Piece ƒ
Normal file
BIN
__MACOSX/Duane Blehm's Code/._Drag Piece ƒ
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/._More Info*
Normal file
BIN
__MACOSX/Duane Blehm's Code/._More Info*
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/._Regions ƒ
Normal file
BIN
__MACOSX/Duane Blehm's Code/._Regions ƒ
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/._StuntCopter ƒ
Normal file
BIN
__MACOSX/Duane Blehm's Code/._StuntCopter ƒ
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/._Zero Gravityƒ
Normal file
BIN
__MACOSX/Duane Blehm's Code/._Zero Gravityƒ
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/Animation ƒ/._About Animation.txt
Normal file
BIN
__MACOSX/Duane Blehm's Code/Animation ƒ/._About Animation.txt
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/Animation ƒ/._Anim.R
Normal file
BIN
__MACOSX/Duane Blehm's Code/Animation ƒ/._Anim.R
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/Animation ƒ/._Anim:rsrc
Normal file
BIN
__MACOSX/Duane Blehm's Code/Animation ƒ/._Anim:rsrc
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/Animation ƒ/._Animation
Normal file
BIN
__MACOSX/Duane Blehm's Code/Animation ƒ/._Animation
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/Animation ƒ/._Animation Steps
Normal file
BIN
__MACOSX/Duane Blehm's Code/Animation ƒ/._Animation Steps
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/Animation ƒ/._Animation.Pas
Normal file
BIN
__MACOSX/Duane Blehm's Code/Animation ƒ/._Animation.Pas
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/Cairo ƒ/._About Cairo files..
Normal file
BIN
__MACOSX/Duane Blehm's Code/Cairo ƒ/._About Cairo files..
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/Cairo ƒ/._Cairo Animation
Normal file
BIN
__MACOSX/Duane Blehm's Code/Cairo ƒ/._Cairo Animation
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/Cairo ƒ/._Cairo Shapes
Normal file
BIN
__MACOSX/Duane Blehm's Code/Cairo ƒ/._Cairo Shapes
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/Cairo ƒ/._Cairo ShootOut v1.2L
Normal file
BIN
__MACOSX/Duane Blehm's Code/Cairo ƒ/._Cairo ShootOut v1.2L
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/Cairo ƒ/._CairoFont.pro
Normal file
BIN
__MACOSX/Duane Blehm's Code/Cairo ƒ/._CairoFont.pro
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/Cairo ƒ/._CairoShootOut.Pas
Normal file
BIN
__MACOSX/Duane Blehm's Code/Cairo ƒ/._CairoShootOut.Pas
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/Cairo ƒ/._aCairo.R
Normal file
BIN
__MACOSX/Duane Blehm's Code/Cairo ƒ/._aCairo.R
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/Cairo ƒ/._aCairo:rsrc
Normal file
BIN
__MACOSX/Duane Blehm's Code/Cairo ƒ/._aCairo:rsrc
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/Copy Mask ƒ/._About CopyMask
Normal file
BIN
__MACOSX/Duane Blehm's Code/Copy Mask ƒ/._About CopyMask
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/Copy Mask ƒ/._CMask.R
Normal file
BIN
__MACOSX/Duane Blehm's Code/Copy Mask ƒ/._CMask.R
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/Copy Mask ƒ/._CMask:rsrc
Normal file
BIN
__MACOSX/Duane Blehm's Code/Copy Mask ƒ/._CMask:rsrc
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/Copy Mask ƒ/._CopyMask
Normal file
BIN
__MACOSX/Duane Blehm's Code/Copy Mask ƒ/._CopyMask
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/Copy Mask ƒ/._CopyMask.pas
Normal file
BIN
__MACOSX/Duane Blehm's Code/Copy Mask ƒ/._CopyMask.pas
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/Drag Piece ƒ/._About DragPiece.txt
Normal file
BIN
__MACOSX/Duane Blehm's Code/Drag Piece ƒ/._About DragPiece.txt
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/Drag Piece ƒ/._DragPiece animation
Normal file
BIN
__MACOSX/Duane Blehm's Code/Drag Piece ƒ/._DragPiece animation
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/Drag Piece ƒ/._DragPieceDemo
Normal file
BIN
__MACOSX/Duane Blehm's Code/Drag Piece ƒ/._DragPieceDemo
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/Drag Piece ƒ/._DragPieceDemo.Pas
Normal file
BIN
__MACOSX/Duane Blehm's Code/Drag Piece ƒ/._DragPieceDemo.Pas
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/Drag Piece ƒ/._aDragPiece.rsrc
Normal file
BIN
__MACOSX/Duane Blehm's Code/Drag Piece ƒ/._aDragPiece.rsrc
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/More Info*/._Programming the Mac.4.6
Normal file
BIN
__MACOSX/Duane Blehm's Code/More Info*/._Programming the Mac.4.6
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/More Info*/._TML Std.Procedures
Normal file
BIN
__MACOSX/Duane Blehm's Code/More Info*/._TML Std.Procedures
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/Regions ƒ/._About Regions
Normal file
BIN
__MACOSX/Duane Blehm's Code/Regions ƒ/._About Regions
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/Regions ƒ/._Regions
Normal file
BIN
__MACOSX/Duane Blehm's Code/Regions ƒ/._Regions
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/Regions ƒ/._Regions.pas
Normal file
BIN
__MACOSX/Duane Blehm's Code/Regions ƒ/._Regions.pas
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/Regions ƒ/._RgnWork.rsrc
Normal file
BIN
__MACOSX/Duane Blehm's Code/Regions ƒ/._RgnWork.rsrc
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/Regions ƒ/._aRegions.R
Normal file
BIN
__MACOSX/Duane Blehm's Code/Regions ƒ/._aRegions.R
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/Regions ƒ/._aRegions:Rsrc
Normal file
BIN
__MACOSX/Duane Blehm's Code/Regions ƒ/._aRegions:Rsrc
Normal file
Binary file not shown.
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/StuntCopter ƒ/._Anim.R
Normal file
BIN
__MACOSX/Duane Blehm's Code/StuntCopter ƒ/._Anim.R
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/StuntCopter ƒ/._StuntCopter.R
Normal file
BIN
__MACOSX/Duane Blehm's Code/StuntCopter ƒ/._StuntCopter.R
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/StuntCopter ƒ/._StuntCopter.pas
Normal file
BIN
__MACOSX/Duane Blehm's Code/StuntCopter ƒ/._StuntCopter.pas
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/StuntCopter ƒ/._StuntCopter.shapes
Normal file
BIN
__MACOSX/Duane Blehm's Code/StuntCopter ƒ/._StuntCopter.shapes
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/StuntCopter ƒ/._StuntCopter1.5
Normal file
BIN
__MACOSX/Duane Blehm's Code/StuntCopter ƒ/._StuntCopter1.5
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/StuntCopter ƒ/._StuntCopter:Rsrc
Normal file
BIN
__MACOSX/Duane Blehm's Code/StuntCopter ƒ/._StuntCopter:Rsrc
Normal file
Binary file not shown.
BIN
__MACOSX/Duane Blehm's Code/Zero Gravityƒ/._About Zero Animation
Normal file
BIN
__MACOSX/Duane Blehm's Code/Zero Gravityƒ/._About Zero Animation
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user