Skip to content

Instantly share code, notes, and snippets.

@steventroughtonsmith
Created January 19, 2015 01:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save steventroughtonsmith/ca38f97e65517106297d to your computer and use it in GitHub Desktop.
Save steventroughtonsmith/ca38f97e65517106297d to your computer and use it in GitHub Desktop.
Pascal:Mac Linker Error
#
# Requires https://github.com/ksherlock/mpw and an
# install of MPW in the emulator's root (~/mpw)
# Uses modern (Xcode) version of Rez
#
# Location of your mpw binary
MPW=~/bin/mpw
RINCLUDES=/Applications/MPW-GM/Interfaces\&Libraries/Interfaces/RIncludes
LDFLAGS =-w -c 'MPS ' -t APPL \
-sn STDIO=Main -sn INTENV=Main -sn %A5Init=Main
LIBRARIES={Libraries}Stubs.o \
{Libraries}MacRuntime.o \
{Libraries}IntEnv.o \
{Libraries}ObjLib.o \
{Libraries}Interface.o \
{Libraries}ToolLibs.o \
{CLibraries}StdCLib.o \
{PLibraries}PasLib.o
SOURCES=test.p
OBJECTS=$(SOURCES:.p=.o)
EXECUTABLE=test
RFILES=test.r
all: $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(MPW) link $(LDFLAGS) $(OBJECTS) $(LIBRARIES) -o $@
Rez -rd $(RFILES) -o $@ -i $(RINCLUDES) -append
%.o : %.p
$(MPW) Pascal -n -h $< -o $@
clean:
rm -rf *.o $(EXECUTABLE)
{
Billiard Simulation Program
To demonstrate features of OOP in Object Pascal
Written by Tim Budd, September 1995
}
Program billiards;
USES
QuickDraw,
MacTypes,
Types,
Menus,
Windows;
type
Ball = object
{ data values maintained by balls }
link : Ball;
region : Rect;
filler : integer;
direction : real;
energy : real;
{ initialization routine }
procedure initialize (xx, yy : integer);
{ common methods }
procedure draw;
procedure erase;
procedure update;
procedure hitBy (aBall : Ball);
procedure setCenter (newx, newy : integer);
{ return x, y coordinate center of ball }
function x : integer;
function y :integer;
end;
Wall = object
{ data fields }
link : Wall;
region : Rect;
{ factor used to reflect striking balls }
convertFactor : real;
{ initialization function }
procedure initialize (left, top, right, bottom : integer; cf : real);
{ draw wall }
procedure draw;
{ notify wall that a ball has struck }
procedure hitBy (aBall : Ball);
end;
Hole = object
{ data fields }
link : Hole;
region : Rect;
{ initialize location of hole }
procedure initialize (x, y : integer);
{ draw the hole }
procedure draw;
{ notify hole that it has received a ball }
procedure hitBy (aBall : Ball);
end;
var
cueBall : Ball;
saveRack : integer;
ballMoved : boolean;
listOfHoles : Hole;
listOfWalls : Wall;
listOfBalls: Ball;
theWindow : windowPtr;
procedure Wall.initialize (left, top, right, bottom : integer; cf : real);
begin
{ initialize convertion factor }
convertFactor := cf;
{ set up region for wall }
SetRect (region, left, top, right, bottom);
end;
procedure Wall.draw;
begin
PaintRect (region);
end;
procedure Wall.hitBy (aBall : Ball);
begin
{ bounce the ball off the wall }
aBall.direction := convertFactor - aBall.direction;
end;
procedure Hole.initialize (x, y : integer);
var left, top, bottom, right : integer;
begin
{ identify region centered around x, y }
left := x - 5;
top := y - 5;
right := x + 5;
bottom := y + 5;
SetRect (region, left, top, right, bottom);
end;
procedure Hole.draw;
begin
PaintOval (region);
end;
procedure Hole.hitBy (aBall : Ball);
begin
{ drain enery from ball }
aBall.energy := 0.0;
aBall.erase;
{ move ball }
if aBall = CueBall then
aBall.setCenter(50, 100)
else begin
saveRack := saveRack + 1;
aBall.setCenter (10 + saveRack * 15, 250);
end;
{ redraw ball }
aBall.draw;
end;
procedure Ball.setCenter (newx, newy : integer);
var left, top, bottom, right : integer;
begin
{ identify region centered around x, y }
left := newx - 5;
top := newy - 5;
right := newx + 5;
bottom := newy + 5;
SetRect (region, left, top, right, bottom);
end;
procedure Ball.initialize (xx, yy : integer);
begin
setCenter(xx, yy);
direction := 0.0;
energy := 0.0;
end;
procedure Ball.erase;
begin
EraseRect (region);
end;
procedure Ball.draw;
begin
if self = CueBall then
FrameOval (region)
else
PaintOval (region)
end;
procedure Ball.update;
var
hptr : Hole;
wptr : Wall;
bptr : Ball;
dx, dy : integer;
theIntersection : Rect;
i : integer;
begin
if energy > 0.5 then begin
ballMoved := true;
{ erase ball }
erase;
{ decrease energy }
energy := energy - 0.05;
{ move ball }
dx := trunc(5.0 * cos(direction));
dy := trunc(5.0 * sin(direction));
offsetRect(region, dx, dy);
{ redraw ball }
for i := 1 to 25 do
draw;
{ see if we hit a hole }
hptr := listOfHoles;
while (hptr <> nil) do
if SectRect(region, hptr.region, theIntersection) then begin
hptr.hitBy(self);
hptr := nil;
end
else
hptr := hptr.link;
{ see if we hit a wall }
wptr := listOfWalls;
while (wptr <> nil) do
if SectRect(region, wptr.region, theIntersection) then begin
wptr.hitBy(self);
wptr := nil;
end
else
wptr := wptr.link;
{ see if we hit a ball }
bptr := listOfBalls;
while (bptr <> nil) do
if (bptr <> self) and SectRect(region, bptr.region, theIntersection) then begin
bptr.hitBy(self);
bptr := nil;
end
else
bptr := bptr.link;
end;
end;
function Ball.x :integer;
begin
x := (region.left + region.right) div 2;
end;
function Ball.y : integer;
begin
y := (region.top + region.bottom) div 2;
end;
function hitAngle (dx, dy : real) : real;
const
PI = 3.14159;
var
na : real;
begin
if (abs(dx) < 0.05) then
na := PI / 2
else
na := arctan (abs(dy / dx));
if (dx < 0) then
na := PI - na;
if (dy < 0) then
na := - na;
hitAngle := na;
end;
procedure Ball.hitBy (aBall : Ball);
var
da : real;
begin
{ cut the energy of the hitting ball in half }
aBall.energy := aBall.energy / 2.0;
{ and add it to our own }
energy := energy + aBall.energy;
{ set our new direction }
direction := hitAngle(self.x - aBall.x, self.y - aBall.y);
{ and set the hitting balls direction }
da := aBall.direction - direction;
aBall.direction := aBall.direction + da;
{ continue our update }
update;
end;
procedure mouseButtonDown (x, y : integer);
var
bptr : Ball;
begin
{ give the cue ball some energy }
cueBall.energy := 20.0;
{ and a direction }
cueBall.direction := hitAngle (cueBall.x - x, cueBall.y - y);
{ then loop as long as called for }
ballMoved := true;
while ballMoved do begin
ballMoved := false;
bptr := listOfBalls;
while bptr <> nil do begin
bptr.update;
bptr := bptr.link;
end;
end;
end;
procedure createGlobals;
var
i, j : integer;
newBall : Ball;
newWall : Wall;
newHole : Hole;
begin
saveRack := 0;
listOfWalls := nil;
listOfHoles := nil;
listOfBalls := nil;
{ create walls }
new (newWall);
newWall.initialize(10, 10, 300, 15, 0.0);
newWall.link := listOfWalls;
listOfWalls := newWall;
new (newWall);
newWall.initialize(10, 200, 300, 205, 0.0);
newWall.link := listOfWalls;
listOfWalls := newWall;
new (newWall);
newWall.initialize(10, 10, 15, 200, 3.14159);
newWall.link := listOfWalls;
listOfWalls := newWall;
new (newWall);
newWall.initialize(300, 10, 305, 205, 3.14159);
newWall.link := listOfWalls;
listOfWalls := newWall;
{ creat holes }
new(newHole);
newHole.initialize(15, 15);
newHole.link := listOfHoles;
listOfHoles := newHole;
new(newHole);
newHole.initialize(15, 200);
newHole.link := listOfHoles;
listOfHoles := newHole;
new(newHole);
newHole.initialize(300, 15);
newHole.link := listOfHoles;
listOfHoles := newHole;
new(newHole);
newHole.initialize(300, 200);
newHole.link := listOfHoles;
listOfHoles := newHole;
{ create balls }
new (cueBall);
cueBall.initialize(50, 96);
listOfBalls := cueBall;
for i := 1 to 5 do
for j := 1 to i do
begin
new(newBall);
newBall.initialize(190 + i * 8,
100 + 16 * j - 8 * i);
newBall.link := listOfBalls;
listOfBalls := newBall;
end;
end;
procedure drawBoard;
var
aWall : Wall;
aBall : Ball;
aHole : Hole;
i, j : integer;
begin
SetPort (theWindow);
aWall := listOfWalls;
while (aWall <> nil) do begin
aWall.draw;
aWall := aWall.link;
end;
aHole := listOfHoles;
while (aHole <> nil) do begin
aHole.draw;
aHole := aHole.link;
end;
aBall := listOfBalls;
{while (aBall <> nil) do begin
aBall.draw;
aBall := aBall.link;
end;}
for i := 1 to 5 do
for j := 1 to i do
begin
if (aBall <> nil) then
aBall.draw;
aBall := aBall.link;
end;
cueBall.draw;
end;
procedure createWindow;
var
name : STR255;
winType : integer;
windowRect : Rect;
begin
name := 'billiards game';
SetRect (windowRect, 50, 70, 500, 400);
winType := DocumentProc;
theWindow := NewWindow(nil, windowRect, name, TRUE, winType, WindowPtr(-1),
True, LongInt(09));
SelectWindow(theWindow);
showWindow(theWindow);
end;
procedure eventLoop;
var
ignore : boolean;
event : eventRecord;
localPoint : Point;
done : boolean;
begin
done := false;
while not done do begin
systemTask;
ignore := GetNextEvent(everyEvent, event);
case event.what of
keyDown:
done := true; { return and quit }
mouseDown:
begin
localPoint := event.where;
GlobalToLocal(localPoint);
mouseButtonDown(localPoint.h, localPoint.v);
end;
updateEvt:
drawBoard;
end;
end;
end;
begin
MaxApplZone;
InitGraf(@qd.thePort);
InitWindows;
InitCursor;
createGlobals;
createWindow;
eventLoop;
end.
#include "SysTypes.r"
#include "Types.r"
/* these #defines are used to set enable/disable flags of a menu */
#define AllItems 0b1111111111111111111111111111111 /* 31 flags */
#define NoItems 0b0000000000000000000000000000000
#define MenuItem1 0b0000000000000000000000000000001
#define MenuItem2 0b0000000000000000000000000000010
#define MenuItem3 0b0000000000000000000000000000100
#define MenuItem4 0b0000000000000000000000000001000
#define MenuItem5 0b0000000000000000000000000010000
#define MenuItem6 0b0000000000000000000000000100000
#define MenuItem7 0b0000000000000000000000001000000
#define MenuItem8 0b0000000000000000000000010000000
#define MenuItem9 0b0000000000000000000000100000000
#define MenuItem10 0b0000000000000000000001000000000
#define MenuItem11 0b0000000000000000000010000000000
#define MenuItem12 0b0000000000000000000100000000000
#define kMBarDisplayed 128
#define mApple 128
#define mFile 129
#define mEdit 130
#define rUserAlert 129
resource 'WIND' (128, preload, purgeable)
{
{50, 40, 300, 450},
kWindowDocumentProc,
visible,
goAway,
0x0,
"Pascal Window",
staggerParentWindowScreen
};
resource 'MBAR' (kMBarDisplayed, preload)
{
{
mApple,
mFile,
mEdit
}
};
resource 'vers' (1) {
0x01, 0x00, release, 0x00,
verUS,
"1.0",
"1.0, Copyright \251 High Caffeine Content 2014"
};
resource 'MENU' (mApple, preload) {
mApple, textMenuProc,
AllItems & ~MenuItem2, /* Disable dashed line, enable About and DAs */
enabled, apple,
{
"About Test�",
noicon, nokey, nomark, plain;
"-",
noicon, nokey, nomark, plain
}
};
resource 'MENU' (mFile, preload)
{
mFile,
textMenuProc,
0x7ffffffd,
enabled,
"File",
{
"Quit", noIcon, "Q", noMark, plain
}
};
resource 'MENU' (mEdit, preload)
{
mEdit,
textMenuProc,
AllItems & ~MenuItem1 & ~MenuItem2,
enabled,
"Edit",
{
"Undo", noIcon, "Z", noMark, plain;
"-", noicon, nokey, nomark, plain;
"Cut", noIcon, "X", noMark, plain;
"Copy", noIcon, "C", noMark, plain;
"Paste", noIcon, "V", noMark, plain;
"Clear", noIcon, nokey, noMark, plain;
}
};
resource 'ALRT' (rUserAlert, purgeable) {
{121, 136, 221, 376}, /* 240x100 */
rUserAlert,
{ /* array: 4 elements */
/* [1] */
OK, visible, silent,
/* [2] */
OK, visible, silent,
/* [3] */
OK, visible, silent,
/* [4] */
OK, visible, silent
},
centerMainScreen
};
resource 'DITL' (rUserAlert, purgeable) {
{ /* array DITLarray: 3 elements */
/* [1] */
{70, 150, 90, 230},
Button {
enabled,
"OK"
},
/* [2] */
{10, 60, 65, 230},
StaticText {
disabled,
"Version 1.0\n\251 High Caffeine Content 2014"
},
/* [3] */
{8, 8, 40, 40},
Icon {
disabled,
1
}
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment