From 964934265267c66cb6ec353351e11012ae6d19cc Mon Sep 17 00:00:00 2001 From: acn Date: Wed, 24 Jun 2020 12:58:25 +0200 Subject: [PATCH] Added Turbo Pascal reimplementation of Ladder --- LadderTP/LADACTOR.PAS | 411 ++++++++++++++++++++++++++++++++++++++++++ LadderTP/LADCONF.COM | Bin 0 -> 22784 bytes LadderTP/LADCONST.PAS | 20 ++ LadderTP/LADDER.COM | Bin 0 -> 33792 bytes LadderTP/LADDER.DAT | Bin 0 -> 512 bytes LadderTP/LADDER.PAS | 34 ++++ LadderTP/LADFIELD.PAS | 75 ++++++++ LadderTP/LADICONS.PAS | 244 +++++++++++++++++++++++++ LadderTP/LADMAIN.PAS | 221 +++++++++++++++++++++++ LadderTP/LADPROCS.PAS | 393 ++++++++++++++++++++++++++++++++++++++++ LadderTP/LADTYPE.PAS | 96 ++++++++++ LadderTP/LADUTILS.PAS | 24 +++ LadderTP/LADVAR.PAS | 17 ++ LadderTP/README.md | 108 +++++++++++ LadderTP/TP/READ.ME | 181 +++++++++++++++++++ LadderTP/TP/TINST.COM | Bin 0 -> 25472 bytes LadderTP/TP/TINST.DTA | Bin 0 -> 4480 bytes LadderTP/TP/TINST.MSG | 123 +++++++++++++ LadderTP/TP/TURBO.COM | Bin 0 -> 30720 bytes LadderTP/TP/TURBO.MSG | 101 +++++++++++ LadderTP/TP/TURBO.OVR | Bin 0 -> 1152 bytes README.md | 2 +- 22 files changed, 2049 insertions(+), 1 deletion(-) create mode 100644 LadderTP/LADACTOR.PAS create mode 100644 LadderTP/LADCONF.COM create mode 100644 LadderTP/LADCONST.PAS create mode 100644 LadderTP/LADDER.COM create mode 100644 LadderTP/LADDER.DAT create mode 100644 LadderTP/LADDER.PAS create mode 100644 LadderTP/LADFIELD.PAS create mode 100644 LadderTP/LADICONS.PAS create mode 100644 LadderTP/LADMAIN.PAS create mode 100644 LadderTP/LADPROCS.PAS create mode 100644 LadderTP/LADTYPE.PAS create mode 100644 LadderTP/LADUTILS.PAS create mode 100644 LadderTP/LADVAR.PAS create mode 100644 LadderTP/README.md create mode 100644 LadderTP/TP/READ.ME create mode 100644 LadderTP/TP/TINST.COM create mode 100644 LadderTP/TP/TINST.DTA create mode 100644 LadderTP/TP/TINST.MSG create mode 100644 LadderTP/TP/TURBO.COM create mode 100644 LadderTP/TP/TURBO.MSG create mode 100644 LadderTP/TP/TURBO.OVR diff --git a/LadderTP/LADACTOR.PAS b/LadderTP/LADACTOR.PAS new file mode 100644 index 0000000..6a56d30 --- /dev/null +++ b/LadderTP/LADACTOR.PAS @@ -0,0 +1,411 @@ +{ + ReverseDirection makes the actor to go in the opposite direction, + it only works when the actor is moving left or right +} +PROCEDURE ReverseDirection(VAR a : ActorType); +BEGIN + CASE a.Dir OF + LEFT : a.Dir := RIGHT; + RIGHT : a.Dir := LEFT; + END; +END; + +{ + OnSolid returns true if standing on something solid i.e. Floor, + Disappearing floor or a Ladder +} +FUNCTION OnSolid(a : ActorType) : BOOLEAN; +BEGIN + OnSolid := (m.Field[a.Y + 1][a.X] IN ['=', '-', 'H', '|']) + OR (m.Field[a.Y][a.X] = 'H'); +END; + +FUNCTION EmptySpace(x, y : INTEGER) : BOOLEAN; +BEGIN + IF (x < 1) OR (x > LevelCols) THEN + EmptySpace := TRUE + ELSE + EmptySpace := NOT (m.Field[y][x] IN ['|', '=']); +END; + +{ + AboveLadder returns true when the actor is a above a Ladder +} +FUNCTION AboveLadder(a : ActorType) : BOOLEAN; +BEGIN + AboveLadder := m.Field[a.Y + 1][a.X] = 'H'; +END; + +{ + OnEater returns true when the actor is standing on a Eater +} +FUNCTION OnEater(a : ActorType) : BOOLEAN; +BEGIN + OnEater := m.Field[a.Y][a.X] = '*'; +END; + +{ + ClampToPlayfield makes sure that if the actor tries to walk or jump off + the playfield edges the actor stays inside the playfield and starts falling +} +PROCEDURE ClampToPlayfield(VAR a : ActorType); +BEGIN + IF a.Dir IN [LEFT, JUMPLEFT] THEN BEGIN + IF a.X < 1 THEN BEGIN + a.X := 1; + a.Dir := STOPPED; + a.DirRequest := NONE; + END; + END; + + IF a.Dir IN [RIGHT, JUMPRIGHT] THEN BEGIN + IF a.X > LevelCols THEN BEGIN + a.X := LevelCols; + a.Dir := STOPPED; + a.DirRequest := NONE; + END; + END; +END; + +{ + InitActor set the fields of an Actor type to reasonable + initial values +} +PROCEDURE InitActor(VAR a : ActorType; t : KindType; xy : XYtype); +BEGIN + a.AType := t; + a.X := xy.x; + a.Y := xy.y; + a.Ch := 'X'; + a.JumpStep := 0; + CASE t OF + ALAD: + BEGIN + a.Ch := 'g'; + a.Dir := STOPPED; + a.DirRequest := NONE; + END; + AROCK: + BEGIN + a.Ch := 'o'; + a.Dir := PENDING; + a.DirRequest := NONE; + END; + END; +END; + +{ + Set the Lad's character based on their current direction +} +PROCEDURE UpdateLadChar(VAR a : ActorType); +BEGIN + WITH a DO + CASE Dir OF + STOPPED: Ch := 'g'; + RIGHT, JUMPRIGHT: Ch := 'p'; + LEFT, JUMPLEFT: Ch := 'q'; + FALLING: Ch := 'b'; + UP, DOWN: Ch := 'p'; + JUMP: + CASE a.DirRequest OF + NONE, STOPPED: Ch := 'g'; + RIGHT, JUMPRIGHT: Ch := 'p'; + LEFT, JUMPLEFT: Ch := 'q'; + END; + END; +END; + +{ + Update an actor's direction to the latest's request +} +PROCEDURE UpdateDir(VAR a : ActorType); +BEGIN + a.Dir := a.DirRequest; + a.DirRequest := NONE; +END; + +{ + MoveActor handles the movements of an Actor +} +PROCEDURE MoveActor(VAR a : ActorType); +LABEL + loopAgain; +VAR + jd : ActionType; + i : INTEGER; + dispenser : DispenserPointerType; +BEGIN + +loopAgain: { If just started falling we need to retest all conditions } + + { A STONE can only be LEFT/RIGHT/DOWN/FALLING or PENDING } + IF a.AType = AROCK THEN BEGIN + IF (a.Dir = PENDING) AND (a.DirRequest = NONE) THEN + EXIT; + + { If stopped select a random direction } + IF a.Dir = STOPPED THEN BEGIN + CASE Random(2) OF + 0: IF (a.X > 1) THEN + IF EmptySpace(a.X - 1, a.Y) THEN + a.DirRequest := LEFT + ELSE + a.DirRequest := RIGHT + ELSE + a.DirRequest := RIGHT; + 1: IF (a.X < LevelCols) THEN + IF EmptySpace(a.X + 1, a.Y) THEN + a.DirRequest := RIGHT + ELSE + a.DirRequest := LEFT + ELSE + a.DirRequest := LEFT; + END; + END; + + { Just reverse direction if at the playfield edge } + IF (a.X = 1) OR (a.X = LevelCols) THEN + ReverseDirection(a); + + { Start to fall if not on solid ground } + IF (a.Dir <> FALLING) AND NOT OnSolid(a) THEN + a.DirRequest := FALLING; + + { If Der rock just rolled over the top of a ladder then randomize direction } + IF AboveLadder(a) AND (a.Dir IN [LEFT, RIGHT]) THEN + CASE Random(4) OF + 0: a.DirRequest := LEFT; + 1: a.DirRequest := RIGHT; + ELSE a.DirRequest := DOWN; + END; + + { If on an Eater kill the stone } + IF OnEater(a) THEN BEGIN + dispenser := dispensers; + IF numDispensers > 1 THEN BEGIN + FOR i := 1 TO Random(numDispensers) DO + dispenser := dispenser^.next; + END; + InitActor(a, AROCK, dispenser^.xy); + m.AnyRocksPending := TRUE; + END; + END; { of stone only handling --------------------- } + + { If stopped or going left or going right and } + { request to do something else, then try to do it } + IF (a.DirRequest <> NONE) THEN BEGIN + CASE a.Dir OF + STOPPED, PENDING: + IF a.DirRequest IN [LEFT, RIGHT, UP, DOWN, FALLING] THEN + UpdateDir(a); + + JUMPUP: + IF a.DirRequest = LEFT THEN + a.Dir := JUMPLEFT + ELSE IF a.DirRequest = RIGHT THEN + a.Dir := JUMPRIGHT; + + RIGHT: + IF a.DirRequest IN [LEFT, STOPPED] THEN + UpdateDir(a); + + LEFT: + IF a.DirRequest IN [RIGHT, STOPPED] THEN + UpdateDir(a); + + UP, DOWN: + IF a.DirRequest IN [STOPPED, UP, DOWN, RIGHT, LEFT] THEN + UpdateDir(a); + + JUMPUP: + IF a.DirRequest = LEFT THEN + a.Dir := JUMPLEFT + ELSE + a.Dir := JUMPRIGHT; + + JUMPRIGHT, JUMPLEFT: + IF a.DirRequest = STOPPED THEN + UpdateDir(a); + + PENDING: + UpdateDir(a); + + END; + END; + + { Handle starting of jumps } + IF (a.DirRequest = JUMP) THEN BEGIN + IF OnSolid(a) THEN BEGIN + CASE a.Dir OF + + STOPPED, FALLING: BEGIN + a.DirRequest := STOPPED; + a.Dir := JUMPUP; + a.JumpStep := 1; + END; + + LEFT: BEGIN + a.DirRequest := a.Dir; + a.Dir := JUMPLEFT; + a.JumpStep := 1; + END; + + JUMPLEFT: BEGIN + a.DirRequest := LEFT; + a.Dir := JUMPLEFT; + a.JumpStep := 1; + END; + + RIGHT: BEGIN + a.DirRequest := a.Dir; + a.Dir := JUMPRIGHT; + a.JumpStep := 1; + END; + + JUMPRIGHT: BEGIN + a.DirRequest := RIGHT; + a.Dir := JumpRIGHT; + a.JumpStep := 1; + END; + END + END ELSE BEGIN + CASE a.Dir OF + JUMPUP, FALLING: a.DirRequest := STOPPED; + JUMPRIGHT: a.DirRequest := RIGHT; + JUMPLEFT: a.DirRequest := LEFT; + END; + END; + END ELSE IF (a.DirRequest = UP) AND (m.Field[a.Y][a.X] = 'H') THEN BEGIN + { If at a ladder and want to go up } + a.Dir := UP; + a.DirRequest := NONE; + END ELSE IF(a.DirRequest = DOWN) AND + ((m.Field[a.Y][a.X] = 'H') OR (m.Field[a.Y + 1][a.X] = 'H')) THEN BEGIN + a.Dir := DOWN; + a.DirRequest := NONE; + END; + + CASE a.Dir OF + + JUMPUP, JUMPLEFT, JUMPRIGHT: BEGIN + { Do the jumping } + jd := jumpPaths[a.Dir, a.JumpStep]; + IF (a.X + dirs[jd].x >= 1) AND (a.X + dirs[jd].x <= LevelCols) THEN BEGIN + CASE m.Field[a.Y + dirs[jd].y][a.X + dirs[jd].x] OF + + '=', '|', '-' : BEGIN + { If bumped into something try falling } + IF OnSolid(a) THEN BEGIN + a.Dir := a.DirRequest; + a.DirRequest := NONE; + END ELSE BEGIN + CASE a.Dir OF + JUMPUP: a.DirRequest := STOPPED; + JUMPRIGHT: a.DirRequest := RIGHT; + JUMPLEFT: a.DirRequest := LEFT; + END; + a.Dir := FALLING; + END; + a.JumpStep := 0; + END; + + 'H': BEGIN { Jumping onto a ladder } + a.Y := a.Y + dirs[jd].y; + a.X := a.X + dirs[jd].x; + a.Dir := STOPPED; + a.DirRequest := NONE; + a.JumpStep := 0; + END; + + ELSE BEGIN + { Just jumping in air } + a.X := a.X + dirs[jd].x; + a.Y := a.Y + dirs[jd].y; + a.JumpStep := SUCC(a.JumpStep); + IF (a.JumpStep > JumpsLen) THEN BEGIN + UpdateDir(a); + a.JumpStep := 0; + END ELSE IF (jumpPaths[a.Dir][a.JumpStep] = ACTIONEND) THEN BEGIN + UpdateDir(a); + a.JumpStep := 0; + END; + END; + END; + END ELSE BEGIN + IF OnSolid(a) THEN BEGIN + a.Dir := a.DirRequest; + a.DirRequest := NONE; + END ELSE BEGIN + a.Dir := FALLING; + a.DirRequest := STOPPED; + a.JumpStep := 0; + END; + END; + END; + + STOPPED: + IF NOT OnSolid(a) THEN + a.Dir := FALLING; + + FALLING: BEGIN + { If falling then continue doing that until not in free space anymore, } + { then continue the previous direction (if any) } + IF OnSolid(a) THEN + IF a.DirRequest = NONE THEN + a.DirRequest := STOPPED + ELSE + a.Dir := a.DirRequest + ELSE + a.Y := Succ(a.Y); + END; + + UP: + { Climb up until ladder is no more } + IF m.Field[a.Y - 1][a.X] IN ['H', '&', '$'] THEN + a.Y := Pred(a.Y) + ELSE + a.Dir := STOPPED; + + DOWN: + { Climb down until ladder is no more } + IF a.Dir = DOWN THEN + IF m.Field[a.Y + 1][a.X] IN ['H', '&', '$', ' ', '^', '.'] THEN + a.Y := Succ(a.Y) + ELSE + a.Dir := STOPPED; + + LEFT: BEGIN + { Stepped out into the void? Then start falling, } + { but remember the previous direction } + IF NOT OnSolid(a) THEN BEGIN + a.DirRequest := a.Dir; + a.Dir := FALLING; + GOTO loopAgain; + END; + IF EmptySpace(a.X - 1, a.Y) THEN + a.X := Pred(a.X) + ELSE + a.DirRequest := STOPPED; + END; + + RIGHT: BEGIN + { Stepped out into the void? Then start falling, } + { but remember the previous direction } + IF NOT OnSolid(a) THEN BEGIN + a.DirRequest := a.Dir; + a.Dir := FALLING; + GOTO loopAgain; + END; + IF EmptySpace(a.X + 1, a.Y) THEN + a.X := Succ(a.X) + ELSE + a.DirRequest := STOPPED; + END; + END; + + { Don't allow actor to end up outside of the playfield } + ClampToPlayfield(a); + IF a.AType = ALAD THEN + UpdateLadChar(a); +END; + diff --git a/LadderTP/LADCONF.COM b/LadderTP/LADCONF.COM new file mode 100644 index 0000000000000000000000000000000000000000..6547494a6509a45e5f3a79bea8ef1ad4eb3ac409 GIT binary patch literal 22784 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 literal 0 HcmV?d00001 diff --git a/LadderTP/LADCONST.PAS b/LadderTP/LADCONST.PAS new file mode 100644 index 0000000..9ae0a08 --- /dev/null +++ b/LadderTP/LADCONST.PAS @@ -0,0 +1,20 @@ +CONST + Version = '1.33TP'; + DataFileName = 'LADDER.DAT'; + ConfigFileName = 'LADCONF.COM'; + NumHighScores = 5; { # of stored high scores } + DataFileStrLength = 31; { # chars in data file terminal config strings } + DataFileNameLength = 29; { # chars in high score names } + CursOffStr = #$1B'[?25l'; { turn cursor off string } + CursOnStr = #$1B'[?25h'; { turn cursor on string } + NumPlaySpeeds = 5; { # of different playing speeds } + BonusTimeDecInterval = 3000; { decrement bonus time every 3 seconds } + + NumLevels = 7; { # of distinct levels } + LevelRows = 20; { # of rows in a level map } + LevelCols = 79; { # of chars in a level map } + MaxDispensers = 3; { max # of rock dispensers on a level } + + JumpsLen = 6; { max # of positions in a jump sequence } + + diff --git a/LadderTP/LADDER.COM b/LadderTP/LADDER.COM new file mode 100644 index 0000000000000000000000000000000000000000..7cada4a419bd955b7350208fa9e1f7f11b1eee0f GIT binary patch literal 33792 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 OkZ*z60U=Hc<^K!u0hh}F literal 0 HcmV?d00001 diff --git a/LadderTP/LADDER.DAT b/LadderTP/LADDER.DAT new file mode 100644 index 0000000000000000000000000000000000000000..d3a2299c2557af8b98693b8156a0bb5caf14b061 GIT binary patch literal 512 zcmWf1adlP*3(+++Fi_BN^b7XXR6qet($OeE0M NIL DO BEGIN + dispenserPtr := dispensers^.next; + DISPOSE(dispensers); + dispensers := dispenserPtr; + END; + IF m.Level > NumLevels THEN BEGIN + ClrScr; + WriteLN('Level ', m.Level, ' out of range'); + CursOn; + Halt; + END; + WITH levels[m.Level] DO BEGIN + m.Name := Name; + m.InitialBonusTime := InitialBonusTime; + m.NumRocks := rocks; + + { dispose of any previous rocks } + WHILE m.Rocks <> NIL DO BEGIN + rock1Ptr := m.Rocks^.Next; + Dispose(m.Rocks); + m.Rocks := rock1Ptr; + END; + { allocate new rocks } + FOR x := 1 TO Rocks DO BEGIN + rock1Ptr := m.Rocks; + New(rock2Ptr); + m.Rocks := rock2Ptr; + m.Rocks^.Next := rock1Ptr; + END; + m.AnyRocksPending := TRUE; + END; + { Prepare the field to be loaded with a new level } + FOR y := 1 TO LevelRows DO + FOR x := 1 TO LevelCols DO + m.Field[y][x] := ' '; + dispensers := NIL; + numDispensers := 0; + FOR y := 1 TO LevelRows DO + FOR x := 1 TO LevelCols DO + CASE levels[m.Level].layout[y][x] OF + 'p': + BEGIN + { The lad will be put there by the rendered, so no need to have } + { it on the map } + lad.x := x; + lad.y := y; + END; + 'V': + BEGIN + m.Field[y][x] := 'V'; + NEW(newDispenser); + newDispenser^.xy.x := x; + newDispenser^.xy.y := y; + newDispenser^.next := dispensers; + dispensers := newDispenser; + numDispensers := Succ(numDispensers); + END; + '.': { TODO - handle the rubber balls } + m.Field[y][x] := '.' + ELSE + m.Field[y][x] := levels[m.Level].layout[y][x]; + END; +END; + diff --git a/LadderTP/LADICONS.PAS b/LadderTP/LADICONS.PAS new file mode 100644 index 0000000..5f93e04 --- /dev/null +++ b/LadderTP/LADICONS.PAS @@ -0,0 +1,244 @@ +{ Initialized constants for Ladder } + +CONST + { + p - The place where the lad starts. + V - Der Dispenser. Der Rocks roll out of it to squash you flat. + * - Der Eaters. They eat the Der Rocks but oddly do not harm you in the slightest + = - Floor. You walk on it. + H - Ladder. You climb it. + | - Wall. You can't walk through it. You're not a ghost....yet. + . - Rubber Ball. It's very bouncy. This difference is, it bounces you. + $ - Treasure. The lad must get here to finish the level. + & - Gold Statue. Money!Money!Money!Money!Money! + ^ - Fire. Turns you into extra crispy bacon. + - - Disposable Floor. Well, you can walk on it once. + } + levels : ARRAY[1..NumLevels] OF LevelType = ( + ( + Name : 'Easy Street'; + InitialBonusTime : 35; + Rocks : 5; + Layout : ( + ' V $ ', + ' H ', + ' H H ', + ' =========H================================================== ', + ' H ', + ' H ', + ' H H H ', + '================H==========H================== ========H=====================', + ' & H H | | ', + ' H Easy Street ', + ' H H ', + ' =========H==========H========= ======================= ', + ' H ', + ' H ', + ' H H ', + '======================== ====================== =========H============== ', + ' H ', + ' H ', + '* p H *', + '===============================================================================' + ) + ), + ( + Name : 'Long Island'; + InitialBonusTime : 45; + Rocks : 8; + Layout : ( + ' $ ', + ' & H ', + ' H |V V| H ', + '====H======================= ========================= ====================== ', + ' H ', + ' H ', + ' H & | . . H ', + '========================== ====== =================== ===================H== ', + ' H ', + ' | H ', + ' H | . . H ', + '====H===================== ====== ================ ====================== ', + ' H ', + ' H | ', + ' H | . . H ', + '========================= ======== ============== ==================H== ', + ' H ', + '============== | H ', + ' Long Island | p * | * H ', + '===============================================================================' + ) + ), + ( + Name : 'Ghost Town'; + InitialBonusTime : 35; + Rocks : 5; + Layout : ( + ' V V V $ ', + ' $$$ ', + ' p H H $$$$$ H', + '==========H=== =H==============H', + ' H H H', + ' H & H H', + ' ============== ==== = ====== = ==== =====H===== H', + ' G ^^^ ^^^^^ ^^^^ ^^^^ ^^^ ^^^ $', + ' h | ', + ' o | H & | ', + ' s ======================H============================== =========== ', + ' t & H ', + ' H ', + ' | H H H ', + ' T ==================H=================H===================H======= ', + ' o H H ', + ' w H ', + ' n ^ H ', + '* ^^^ H *', + '===============================================================================' + ) + ), + ( + Name : 'Tunnel Vision'; + InitialBonusTime : 36; + Rocks : 5; + Layout : ( + ' V V ', + ' ', + ' H H | H ', + '=====H=====--======H========================== ===----====H=========== ', + ' H H |&& H ', + ' H H ================== H ', + ' H H tunnel H H ', + ' H =======---===----=================H= H H ', + ' H | vision H H H ', + ' H =========---& -----============H H H ', + ' H H H | H H ', + ' H H=========----===----================ H ==============', + ' H & H ', + ' H | H ', + '====---==== H | H ', + '| | ================---===---=================== H ', + '| === | H H p ', + '| $ | H ===H=======', + '|* $$$ *| * * * *H *H ', + '===============================================================================' + ) + ), + ( + Name : 'Point of No Return'; + InitialBonusTime : 35; + Rocks : 7; + Layout : ( + ' $ ', + ' H V ', + ' H ', + ' HHHHHHHHHHHHH .HHHHHHHHHHHHHH H p ', + ' & V H ==H==========', + ' H H ', + ' H H . H ', + '===H==============-----------============H==== H ', + ' H H H ', + ' H =====H============== ', + ' H H H ', + ' H &..^^^.....^..^ . ^^ H==--------- H ', + ' H ============================H & H H ', + ' H === === === H ---------=================H======', + ' H H H ', + ' H & H & H ', + ' ==========-------------------------=======----------=================== ', + ' ', + '^^^* ^^^^^^^^^^^^^^^^^^^^^^^^^* *^^^^^^^^^^*Point of No Return*^^^^', + '===============================================================================' + ) + ), + ( + Name : 'Bug City'; + InitialBonusTime : 37; + Rocks : 6; + Layout : ( + ' Bug City HHHHHHHH V ', + ' HHH HHH ', + ' H >mmmmmmmm ', + ' H=============== ==================== H ', + ' H |===== \ / V =====H==========', + ' H \/ H ', + ' H | $ H ', + ' H H | H H ', + ' H ====H======= p |&H H H ', + ' H H ======================H ====== ', + ' H H &| H H ', + ' H H &| H H }{ =====H==== ', + '===H===& H =====================H H H ', + ' H H H H ', + ' H H & H ', + ' ======H=== ======= H <> & H ', + ' H========== ===== = ============', + ' }i{ H ', + '* H *', + '===============================================================================' + ) + ), + ( + Name : 'GangLand'; + InitialBonusTime : 32; + Rocks : 6; + Layout : ( + ' =Gang Land= V ', + ' == _ == . ', + ' p H | [] |_| | & . H ', + '===========H | |_| | H === ===================H ', + ' V H ============= H====== H ', + ' H H & H ', + ' H H | | H ', + ' H H ^^^&&^^^ & ^ ^^^ H H | =============H ', + ' H======H =======================H===========H===== & H ', + ' H H H | &&& H ', + ' H H H | &&&&& H ', + ' H H H | =============H ', + ' =====------================= H | $ $ ', + ' | H | $$$ $$$ ', + '====------=== | H | $$$$$ $$$$$ ', + ' | = | ============= ============ ', + ' | $ ^ & ', + ' |^^^^^^^^^^^^^^ $ ^ ====== ', + '* . & ^ H*^ ^ ^ ^^^^^^^^^^^^', + '===============================================================================' + ) + ) + ); + + { + A moving jump is UR/UR/R/R/DR/DR + or UL/UL/L/L/DL/DL + A standing jump is U/U/-/D/D + + ==================== + ----234-----23------ + ---1---5----14------ + --0-----6---05------ + ==================== + } + jumpPaths : Array[JUMPRIGHT..JUMPLEFT] OF ActionArrayType = ( + (UPRIGHT, UPRIGHT, RIGHT, RIGHT, DOWNRIGHT, DOWNRIGHT), + (UP, UP, STOPPED, DOWN, DOWN, ACTIONEND), + (UPLEFT, UPLEFT, LEFT, LEFT, DOWNLEFT, DOWNLEFT) + ); + + dirs : ARRAY[STOPPED..JUMPLEFT] OF XYtype = ( + (x: 0; y: 0), { STOPPED } + (x: 0; y:-1), { UP } + (x: 1; y:-1), { UPRIGHT } + (x: 1; y: 0), { RIGHT } + (x: 1; y: 1), { DOWNRIGHT } + (x: 0; y: 1), { DOWN } + (x:-1; y: 1), { DOWNLEFT } + (x:-1; y: 0), { LEFT } + (x:-1; y:-1), { UPLEFT } + (x: 0; y: 1), { FALLING } + (x: 0; y: 0), { JUMP } + (x: 0; y: 0), { JUMPRIGHT } + (x: 0; y: 0), { JUMPUP } + (x: 0; y: 0) { JUMPLEFT } + ); + + ReadmsWait : ARRAY [1..NumPlaySpeeds] OF INTEGER = (100, 50, 25, 13, 7); + diff --git a/LadderTP/LADMAIN.PAS b/LadderTP/LADMAIN.PAS new file mode 100644 index 0000000..22ba7de --- /dev/null +++ b/LadderTP/LADMAIN.PAS @@ -0,0 +1,221 @@ +{ + Note that this code makes free use of the dreaded GOTO command. +} +VAR + msecs, bonusTimeTicks, moveInterval, x, y : INTEGER; + ch : CHAR; + rockPtr : RockPointerType; + +LABEL + restartGame, restartLevel, newLevel; + +BEGIN { MAIN } + dispensers := NIL; { initialize our linked lists for dispenser } + m.Rocks := NIL; { and rocks } + lastScore := -1; + playSpeed := 1; + ReadDataFile; + +restartGame: + + m.LadsRemaining := 5; + m.Level := 1; + m.Score := 0; + levelCycle := 1; + displayLevel := 1; + nextNewLad := 100; + CursOn; + Randomize; + MainMenu; + moveInterval := ReadmsWait[playSpeed]; + ClrScr; + CursOff; + +newLevel: + + { Load a level and show it } + LoadMap(ladXY, dispensers, numDispensers); + +restartLevel: + + m.RemainingBonusTime := m.InitialBonusTime - 2 * (levelCycle - 1); + InitActor(lad, ALAD, ladXY); + DisperseRocks; + + { Show the initial map on screen } + DrawMap; + msecs := 0; + bonusTimeTicks := 0; + + WHILE TRUE DO BEGIN + + Delay(1); + msecs := Succ(msecs); + IF msecs >= moveInterval THEN BEGIN + { move the Lad and rocks every X milliseconds } + msecs := 0; + bonusTimeTicks := bonusTimeTicks + moveInterval; + IF bonusTimeticks >= BonusTimeDecInterval THEN BEGIN + { every 3 seconds, decrement the bonus time/time remaining value } + bonusTimeTicks := bonusTimeTicks - BonusTimeDecInterval;; + m.RemainingBonusTime := Pred(m.RemainingBonusTime); + GotoXY(74, 21); + Write(m.RemainingBonusTime : 2); + IF m.RemainingBonusTime <=0 THEN BEGIN + { died: do the animation and check if we still have lives left } + IF LadDeath THEN + GOTO restartLevel; + GOTO restartGame; + END; + END; + + IF m.AnyRocksPending THEN BEGIN + { pending rocks? see if it's time to start moving } + rockPtr := m.Rocks; + m.AnyRocksPending := FALSE; + WHILE rockPtr <> NIL DO BEGIN + IF (rockPtr^.Dir = PENDING) THEN + IF (Random(10) = 0) THEN + rockPtr^.DirRequest := FALLING + ELSE + m.AnyRocksPending := TRUE; + rockPtr := rockPtr^.Next; + END; + END; + + { Move the lad according to players wishes } + IF (lad.Dir <> STOPPED) OR (lad.DirRequest <> NONE) THEN BEGIN + x := lad.X; y := lad.Y; + GotoXY(x, y); Write(m.Field[y][x]); + MoveActor(lad); + GotoXY(lad.X, lad.Y); Write(lad.Ch); + IF (x <> lad.X) AND (y = lad.Y) THEN BEGIN + { get rid of disappearing flooring } + IF m.Field[y + 1][x] = '-' THEN BEGIN + m.Field[y + 1][x] := ' '; + GotoXY(x, y + 1); Write(' '); + END; + END; + + CASE m.Field[lad.Y][lad.X] OF + + '$' : BEGIN { at the Gold: level done } + UpdateScore(ScoreMoney); + displayLevel := Succ(displayLevel); + IF (m.Level > levelCycle) OR (m.Level = NumLevels) THEN BEGIN + { done with current cycle, recycle to 1st level } + m.Level := 1; + levelCycle := SUCC(levelCycle); + END ELSE BEGIN + m.Level := Succ(m.Level); + END; + GOTO newLevel; + END; + + '^': BEGIN { death by fire } + IF LadDeath THEN + GOTO restartLevel; + GOTO restartGame; + END; + + '&': BEGIN + { found a statue, adjust the score, remove the statue } + UpdateScore(ScoreStatue); + m.Field[lad.Y][lad.X] := ' '; + END; + + '.': BEGIN {trampoline: choose a random direction } + CASE Random(5) OF + 0: BEGIN + lad.Dir := LEFT; + lad.DirRequest := NONE; + lad.JumpStep := 0; + END; + 1: BEGIN + lad.Dir := RIGHT; + lad.DirRequest := NONE; + lad.JumpStep := 0; + END; + 2: BEGIN + lad.Dir := JUMPUP; + lad.DirRequest := STOPPED; + lad.JumpStep := 1; + END; + 3: BEGIN + lad.Dir := JUMPLEFT; + lad.DirRequest := LEFT; + lad.JumpStep := 1; + END; + 4: BEGIN + lad.Dir := JUMPRIGHT; + lad.DirRequest := RIGHT; + lad.JumpStep := 1; + END; + END; + END; + END; + END; { of Lad movement handler -------------------------- } + + { Move the rock(s) } + rockPtr := m.Rocks; + WHILE rockPtr <> NIL DO BEGIN + { Don't draw the rock if it's pending } + IF rockPtr^.Dir <> PENDING THEN BEGIN + IF Collision(rockPtr) THEN + IF LadDeath THEN + GOTO restartLevel + ELSE + GOTO restartGame; + x := rockPtr^.X; + y := rockPtr^.Y; + GotoXY(x, y); + Write(m.Field[y][x]); + END; + MoveActor(rockPtr^); + { Don't draw the rock if it's pending } + IF rockPtr^.Dir <> PENDING THEN BEGIN + IF Collision(rockPtr) THEN + IF LadDeath THEN + GOTO restartlevel + ELSE + GOTO restartGame; + GotoXY(rockPtr^.X, rockPtr^.Y); + Write(rockPtr^.Ch); + END; + rockPtr := rockPtr^.Next; + END; { of rock movement handler ------------------------- } + { end of tick handler =================================== } + END; + IF KeyPressed THEN BEGIN + Read(Kbd, ch); + ch := UpCase(ch); + IF ch = leftKey THEN BEGIN + lad.DirRequest := LEFT + END ELSE IF ch = rightKey THEN BEGIN + lad.DirRequest := RIGHT + END ELSE IF ch = upKey THEN BEGIN + lad.DirRequest := UP + END ELSE IF ch = downKey THEN BEGIN + lad.DirRequest := DOWN + END ELSE IF ch = ' ' THEN BEGIN + lad.DirRequest := JUMP; + END ELSE IF ch = #$1B THEN BEGIN + CursOn; + GotoXY(1, 23); Write('Type RETURN to continue: '); + REPEAT + WHILE NOT KeyPressed DO; + Read(Kbd, ch); + UNTIL ch IN [#$0D, #$03]; + IF ch = #$03 THEN { ^C goes back to main menu } + GOTO restartGame; + GotoXY(1, 23); ClrEOL; + CursOff; + END ELSE IF ch = #$03 THEN BEGIN + GOTO restartGame + END ELSE BEGIN + lad.DirRequest := STOPPED + END; + END; { of keypress handler ================================ } + END; +END. + diff --git a/LadderTP/LADPROCS.PAS b/LadderTP/LADPROCS.PAS new file mode 100644 index 0000000..9692307 --- /dev/null +++ b/LadderTP/LADPROCS.PAS @@ -0,0 +1,393 @@ +PROCEDURE Instructions; +BEGIN + ClrScr; + WriteLN; + WriteLN('You are a Lad trapped in a maze. Your mission is is to explore the'); + WriteLN('dark corridors never before seen by human eyes and find hidden'); + WriteLN('treasures and riches'); + WriteLN; + WriteLN('You control Lad by typing the direction buttons and jumping by'); + WriteLN('typing SPACE. But beware of the falaling rocks called Der rocks.'); + WriteLN('You must find and grasp the treasures (shown as $) BEFORE the'); + WriteLN('bonus time runs out.'); + WriteLN; + WriteLN('A new Lad will be awarded for every 10,000 points.'); + WriteLN('Extra points are awarded for touching the gold'); + WriteLN('statues (shown as &). You will receive the bonus time points'); + WriteLN('that are left when you have finished the level.'); + WriteLN; + WriteLN('Type an ESCape to pause the egame.'); + WriteLN; + WriteLN('Remember, there is more than one way to skin a cat. (Chum)'); + WriteLN; + WriteLN('Good luck Lad.'); + WriteLN; + WriteLN; + WriteLN; + Write('Type RETURN to return to main menu: '); + Read; +END; + +PROCEDURE ConfigureLadder; +VAR + configPgm : FILE; + Ok : BOOLEAN; +BEGIN + {$I-} + Assign(configPgm, ConfigFileName); + WriteLN('Linking to configuration program'); + Execute(configPgm); + Ok := IOresult = 0; { IOresult must be called after failed Execute } + {$I+} + WriteLN; + WriteLN('Unable to link to LADCONF.COM'); + WriteLN('Ladder configuration program missing'); + Halt; +END; + +PROCEDURE MainMenu; +VAR + ch : CHAR; + insult : BOOLEAN; + i, msecs : INTEGER; + configPgm : FILE; +BEGIN + REPEAT + ClrScr; + WriteLN(' LL dd dd'); + WriteLN(' LL dd dd tm'); + WriteLN(' LL aaaa ddddd ddddd eeee rrrrrrr'); + WriteLN(' LL aa aa dd dd dd dd ee ee rr rr'); + WriteLN(' LL aa aa dd dd dd dd eeeeee rr'); + WriteLN(' LL aa aa dd dd dd dd ee rr'); + WriteLN(' LLLLLLLL aaa aa ddd dd ddd dd eeee rr'); + WriteLN; + WriteLN(' Version : ', Version); + WriteLN('(c) 1982, 1983 Yahoo Software Terminal: ', dataFileContents.TerminalName); + WriteLN('10970 Ashton Ave. Suite 312 Play speed: ', playSpeed); + Write( 'Los Angeles, Ca 90024 '); + WriteLN('Up = ', upKey, ' Down = ',downKey ,' Left = ', leftKey, ' Right = ', rightKey); + WriteLN(' Jump = Space Stop = Other'); + WriteLN; + WriteLN('P = Play game High Scores'); + WriteLN('L = Change level of difficulty'); + WriteLN('C = Configure Ladder'); + WriteLN('I = Instructions'); + WriteLN('E = Exit Ladder'); + WriteLN; + WriteLN; + Write('Enter one of the above: '); + { show high scores } + FOR i := 1 TO NumHighScores DO BEGIN + GotoXY(40, i + 15); + Write(i, ') '); + IF highScores[i].Score <> 0 THEN + Write(highScores[i].Score:4, '00 ', highScores[i].Name); + END; + IF lastScore <> -1 THEN BEGIN + GotoXY(40, 22); + Write('Last Score: ',lastScore,'00'); + END; + GotoXY(25, 22); + + { randomly prompt the user to get a move on } + insult := FALSE; + msecs := 0; + REPEAT + Delay(1); + msecs := Succ(msecs); + IF msecs >= 1000 THEN BEGIN + msecs := 0; + IF insults THEN BEGIN + IF insult THEN BEGIN + GotoXY(1, 24); + ClrEol; + insult := FALSE; + GotoXY(25, 22); + END ELSE BEGIN + i := Random(10); + IF i > 7 THEN BEGIN + insult := TRUE; + GotoXY(1, 24); + IF i = 8 THEN + Write('You eat quiche!') + ELSE + Write('Come on, we don''t have all day!'); + GotoXY(25, 22); + END; + END; + END; + END; + + ch := #0; + IF KeyPressed THEN BEGIN + Read(Kbd, ch); + ch := UpCase(ch); + IF ch = 'L' THEN BEGIN { change playing speed } + playSpeed := SUCC(playSpeed MOD NumPlaySpeeds); + GotoXY(52, 11); Write(playSpeed); + GotoXY(25, 22); + END ELSE IF ch = 'I' THEN + Instructions; + END; + UNTIL ch IN ['P','C','I','E']; + UNTIL ch in ['P', 'C', 'E']; + IF ch = 'E' THEN BEGIN + Write('Exiting...'); + GotoXY(1, 24); + ClrEOL; + GotoXY(1, 23); + Halt; + END ELSE IF ch = 'C' THEN BEGIN { run configuration program } + GotoXY(1, 23); + ConfigureLadder; + END; +END; + + +{ + Read the LADDER.DAT file. This is the same file used in the original + game. We don't use the cursor control stuff (that's handled by Turbo + Pascal, but do use the control keys, flags and high scores. + + I'm sure this code could be better, but it does the job. +} +PROCEDURE ReadDataFile; +VAR + dataFile,configPgm : FILE; + i, j : INTEGER; +BEGIN + {$I-} + Assign(dataFile, DataFileName); + Reset(dataFile); + IF IOresult <> 0 THEN BEGIN + ConfigureLadder; + END; + BlockRead(dataFile, dataFileContents, SizeOf(dataFileContents) DIV 128); + IF IOresult <> 0 THEN BEGIN + WriteLN('Ladder not configred'); + WriteLN; + ConfigureLadder; + END; + WITH dataFileContents DO BEGIN + sound := Flags[0] = 'Y'; + insults := Flags[1] = 'Y'; + downKey := Keys[0]; + leftKey := Keys[1]; + rightKey := Keys[2]; + upKey := Keys[3]; + FOR i := 1 TO NumHighScores DO BEGIN + highScores[i].Name[0] := CHAR(Highs[i][0]); + IF Highs[i][0] = 0 THEN + highScores[i].Score := 0 + ELSE + highScores[i].Score := Highs[i][1] OR (Highs[i][2] SHL 8); + FOR j := 1 TO Highs[i][0] DO + highScores[i].Name[j] := CHAR(Highs[i][j + 2]); + END; + END; + Close(dataFile); + {$I+} +END; + +{ + Update the high scores in LADDER.DAT. See the comments in + ReadDataFile. +} +PROCEDURE WriteDataFile; +VAR + dataFile : FILE; + i, j : INTEGER; +BEGIN + {$I-} + Assign(dataFile, DataFileName); + Reset(dataFile); + IF IOresult <> 0 THEN BEGIN + WriteLN('Reset failed on LADDER.DAT'); + Halt; + END; + WITH dataFileContents DO BEGIN + FOR i := 1 TO NumHighScores DO BEGIN + Highs[i][0] := Length(highScores[i].Name); + Highs[i][1] := Lo(highScores[i].Score); + Highs[i][2] := Hi(highScores[i].Score); + FOR j := 1 TO Highs[i][0] DO + Highs[i][j + 2] := ORD(highScores[i].Name[j]); + END; + BlockWrite(dataFile, dataFileContents, SizeOf(dataFileContents) DIV 128); + IF IOresult <> 0 THEN BEGIN + WriteLN('BlockWrite failed on LADDER.DAT'); + Halt; + END; + END; + Close(dataFile); + {$I+} +END; + +{ + kill the lad off in a horrible death of mixed up characters. +} +FUNCTION LadDeath : BOOLEAN; +CONST + NumSymbols = 11; + symbols : ARRAY[1..NumSymbols] OF CHAR = ('p', 'b', 'd', 'q', 'p', 'b', 'd', 'q', '-', '-', '_'); +VAR + i, j : INTEGER; + name: STRING[DataFileNameLength]; + ch : CHAR; +BEGIN + FOR i := 1 TO NumSymbols DO BEGIN + Beep; + GotoXY(lad.X, lad.Y); Write(symbols[i]); + Delay(150); + END; + m.LadsRemaining := Pred(m.LadsRemaining); + GotoXY(8, 21); Write(m.ladsRemaining : 2); + LadDeath := m.LadsRemaining > 0; + IF m.LadsRemaining <= 0 THEN BEGIN + FOR i := 1 TO NumHighScores DO BEGIN + WriteLN(highScores[i].Score); + IF m.Score >= highScores[i].Score THEN BEGIN + FOR j := NumHighScores - 1 DOWNTO i DO BEGIN + highScores[j + 1] := highScores[j]; + END; + ClrScr; + GotoXY(10, 7); + FOR j := 1 TO 7 DO + Write('YAHOO! '); + WriteLN; + WriteLN; + CASE levelCycle OF + 1 : WriteLN('You really don''t deserve this but...'); + 2 : WriteLN('Not bad for a young Lad'); + 3 : WriteLN('Amazing! You rate!!'); + 4 : WriteLN('Looks like we have a Lad-Der here'); + 5 : WriteLN('Yeah! Now you are a Lad-Wiz!'); + 6 : WriteLN('Wow! You are now a Lad-Guru!'); + ELSE WriteLN('You are a true Lad-Master!!!'); + END; + WriteLN; + While KeyPressed DO + Read(Kbd, ch); + Write('Enter your name: '); + CursOn; + Read(name); + CursOff; + GotoXY(1, 17); + Write('Updating high scores...'); + highScores[i].Score := m.Score; + highScores[i].Name := name; + WriteDataFile; + EXIT; + END; + END; + END; +END; + +PROCEDURE DrawMap; +VAR + x, y : INTEGER; + ch : CHAR; +BEGIN + FOR y := 1 TO LevelRows DO BEGIN + GotoXY(1, y); + FOR x := 1 TO LevelCols DO + Write(m.Field[y][x]); + END; + { Draw the lad at rest } + GotoXY(lad.X, lad.Y); Write('g'); + { Initialize the entire status line } + GotoXY(1, 21); + Write('Lads ',m.LadsRemaining : 2, + ' Level ', displayLevel : 2, + ' Score ', m.Score : 5, '00', + ' Bonus time ', m.RemainingBonusTime : 2, '00'); + GotoXY(1, 23); Write('Get ready!'); + Delay(1000); + WHILE KeyPressed DO + Read(Kbd, ch); + GotoXY(1, 23); Write(' '); +END; + +{ + Adjusts the score according to some event. +} +PROCEDURE UpdateScore(scoreEvent : ScoreType); +BEGIN + CASE scoreEvent OF + + ScoreStatue: BEGIN + m.Score := m.Score + m.RemainingBonusTime; + Beep; + END; + + ScoreReset: m.Score := 0; + + ScoreRock: BEGIN + m.Score := m.Score + 2; + Beep; + END; + + ScoreMoney: BEGIN + WHILE m.RemainingBonusTime > 0 DO BEGIN + GotoXY(1, 23); Write('Hooka!'); Beep; Delay(100); + GotoXY(1, 23); Write(' '); Delay(100); + m.Score := Succ(m.Score); + m.RemainingBonusTime := Pred(m.RemainingBonusTime); + GotoXY(36, 21); Write(m.Score : 5); + GotoXY(74, 21); Write(m.RemainingBonusTime : 2); + END; + END; + END; + { give a new lad if over 10,000 points } + IF m.Score >= nextNewLad THEN BEGIN + m.ladsRemaining := Succ(m.ladsRemaining); + nextNewLad := nextNewLad + 100; + GotoXY(8, 21); Write(m.ladsRemaining : 2); + END; + GotoXY(36, 21); + Write(m.Score : 5); +END; + +{ + Check to see if the Lad has collided with, or jumped over a rock. +} +FUNCTION Collision(rockPtr : RockPointerType) : BOOLEAN; +BEGIN + Collision := FALSE; + IF lad.X = rockPtr^.X THEN BEGIN + IF lad.Y = rockPtr^.Y THEN BEGIN + Collision := TRUE; + END ELSE IF (lad.Y = rockPtr^.Y - 1) AND + (m.Field[lad.Y + 1][lad.X] = ' ') THEN BEGIN + { score for jumping rocks } + UpdateScore(ScoreRock); + END ELSE IF (lad.Y = rockPtr^.Y - 2) THEN + IF (m.Field[lad.Y + 1][lad.X] = ' ') AND (m.Field[lad.Y + 2][lad.X] = ' ') THEN BEGIN + { score for jumping rocks } + UpdateScore(ScoreRock); + END; + END; +END; + +{ + Set each rock up in a random dispenser. +} +PROCEDURE DisperseRocks; +VAR + rockPtr : RockPointerType; + dispenserPtr : DispenserPointerType; + i : INTEGER; +BEGIN + rockPtr := m.Rocks; + WHILE rockPtr <> NIL DO BEGIN + dispenserPtr := dispensers; + IF numDispensers > 1 THEN + FOR i := 1 TO Random(numDispensers) DO + dispenserPtr := dispenserPtr^.Next; + InitActor(rockPtr^, AROCK, dispenserPtr^.xy); + rockPtr := rockPtr^.Next; + END; + m.AnyRocksPending := TRUE; +END; + diff --git a/LadderTP/LADTYPE.PAS b/LadderTP/LADTYPE.PAS new file mode 100644 index 0000000..61778e8 --- /dev/null +++ b/LadderTP/LADTYPE.PAS @@ -0,0 +1,96 @@ +TYPE + Str80Type = STRING[80]; + ScoreType = (ScoreReset, ScoreRock, ScoreStatue, ScoreMoney); + + NameStringType = STRING[20]; + LayoutType = ARRAY[1..LevelRows] OF ARRAY[1..LevelCols] OF CHAR; + LevelType = RECORD + Name : NameStringType; + InitialBonusTime : INTEGER; + Rocks : INTEGER; + Layout : LayoutType; + END; + + { The Action constants define what the Actor currently is, } + { or is requested to be, doing } + ActionType = ( + PENDING, + NONE, + STOPPED, + UP, + UPRIGHT, + RIGHT, + DOWNRIGHT, + DOWN, + DOWNLEFT, + LEFT, + UPLEFT, + FALLING, + JUMP, { Generic jump set by keyhandler } + JUMPRIGHT, + JUMPUP, + JUMPLEFT, + ACTIONEND + ); + + ActionArrayType = ARRAY[1..JumpsLen] OF ActionType; + + KindType = ( ALAD, AROCK ); + + RockPointerType = ^ActorType; + { The Actor struct holds info about an actor ie, the Lad or a Rock } + ActorType = RECORD + AType : KindType; + X,Y : INTEGER; + Ch : CHAR; + Dir, DirRequest : ActionType; + JumpStep : INTEGER; + Next : RockPointerType; + END; + + { The MapData hold all info about a map } + MapDataType = RECORD + Name : NameStringType; + Field : LayoutType; + LadsRemaining : INTEGER; + NumRocks : INTEGER; + Rocks : RockPointerType; + AnyRocksPending : BOOLEAN; + Level : INTEGER; + Score : INTEGER; + InitialBonusTime : INTEGER; + RemainingBonusTime : INTEGER; + ScoreText : Str80type; + END; + + XYtype = RECORD + x, y : INTEGER; + END; + + DispenserPointerType = ^DispenserType; + DispenserType = RECORD + xy : XYtype; + next : DispenserPointerType; + END; + + { layout of LADDER.DAT data file } + DataFileType = RECORD + TerminalName : STRING[DataFileStrLength]; + MoveCsrPrefix : STRING[DataFileStrLength]; + MoveCsrSeparator : STRING[DataFileStrLength]; + MoveCsrSuffix : STRING[DataFileStrLength]; + UnkEscSeq : STRING[DataFileStrLength]; { not sure what this is... initialization? } + ClrScrStr : STRING[DataFileStrLength]; + Flags : ARRAY[0..DataFileStrLength] OF CHAR; + Keys : ARRAY[0..DataFileStrLength] OF CHAR; + Highs : ARRAY[1..NumHighScores] OF ARRAY[0..DataFileStrLength] OF BYTE; + Unused1 : ARRAY[0..DataFileStrLength] OF BYTE; + Unused2 : ARRAY[0..DataFileStrLength] OF BYTE; { padding to next 128 bytes } + Unused3 : ARRAY[0..DataFileStrLength] OF BYTE; + END; + + HighScoreType = RECORD + Score : INTEGER; + Name : STRING[DataFileNameLength]; + END; + diff --git a/LadderTP/LADUTILS.PAS b/LadderTP/LADUTILS.PAS new file mode 100644 index 0000000..48e32a6 --- /dev/null +++ b/LadderTP/LADUTILS.PAS @@ -0,0 +1,24 @@ +{ + Some terminal routines not handled by Turbo Pascal. + + CursOff: turn the cursor off (set the string in LADCONST.PAS) + CursOn: turn the cursor on (set the string in LADCONST.PAS) + Beep: ring the terminal bell +} + +PROCEDURE CursOff; +BEGIN + Write(CursOffStr); +END; + +PROCEDURE CursOn; +BEGIN + Write(CursOnStr); +END; + +PROCEDURE Beep; +BEGIN + IF sound THEN + Write(#7); +END; + diff --git a/LadderTP/LADVAR.PAS b/LadderTP/LADVAR.PAS new file mode 100644 index 0000000..bf329b4 --- /dev/null +++ b/LadderTP/LADVAR.PAS @@ -0,0 +1,17 @@ +VAR + dispensers : DispenserPointerType; { rock dispensers linked list } + numDispensers : INTEGER; { # of dispensers on current level } + lastScore : INTEGER; { score from last completed game } + playSpeed : INTEGER; + m : MapDataType; + lad : ActorType; + ladXY : XYtype; { starting position of lad } + nextNewLad : INTEGER; { score for next new lad awarded } + dataFileContents : DataFileType; + highScores : ARRAY[1..NumHighScores] OF HighScoreType; + sound : BOOLEAN; { TRUE for sound } + insults : BOOLEAN; { TRUE for insults } + levelCycle : INTEGER; + displayLevel : INTEGER; { displayed map level } + upKey, downKey, leftKey, rightKey : CHAR; { lad direction control keys } + diff --git a/LadderTP/README.md b/LadderTP/README.md new file mode 100644 index 0000000..d954225 --- /dev/null +++ b/LadderTP/README.md @@ -0,0 +1,108 @@ +# Ladder + +The classic CP/M game Ladder reverse engineered in Turbo Pascal. + +Original GitHub repository: https://github.com/mecparts/Ladder + +Additional information and compiled version by Anna Christina Naß + +I've added a compiled ``LADDER.COM`` file for just playing the game (on a VT100 +terminal at about 8 MHz, eg. a RC2014), and added more information on +compiling the game. + +## Keys + +The file ``LADDER.DAT`` is the configuration file that holds the key definitions. +These can be changed by using ``LADCONF.COM`` (the terminal definition +in LADCONF is not used! This LADDER uses the Turbo Pascal terminal definitions). + +The default keys in this ``LADDER.DAT`` are: + + Up = 8 Down = 2 Left = 4 Right = 6 + Jump = Space Stop = Other + +(Jump and Stop are not configurable) + +Also, "bell" sound is enabled and "wise crack marks" are disabled. + +## Compiling notes from Anna: + +To compile LADDER, just use Turbo Pascal from the ``TP/`` directory. +It's TP 3.0A for CP/M-80, only without the demo source code. + +* Copy the TP files together with the LADDER files to one disk +* The terminal definition is already set to ANSI and the speed is set to 8 MHz (for a + standard RC2014), so running TINST is not needed +* Run Turbo Pascal using TURBO +* Set the compiler options to "compile -> Com-file" (press O, C, Q) +* Compile ``LADDER.PAS``: press C (Compile), then enter ``ladder`` as Work file name. + +This should result in a ``LADDER.COM`` file. + +The rest of this file is mostly the README from the original repository. + +# Original README content: + +## About +This is a rewrite in Turbo Pascal of the classic CP/M game "Ladder", +originally written by Yahoo Software (not Yahoo!). + +Ladder is an ASCII character based platform arcade game similar to +Donkey Kong. You travel through levels with platforms and ladders +where rocks fall down from the top while you collect statues +before reaching the exit. + +Back in 1999 Stephen Ostermiller made a version of [Ladder in +Java](http://ostermiller.org/ladder/). Later, Mats Engstrom of +SmallRoomLabs started another version in of [Ladder in +golang](https://github.com/SmallRoomLabs/ladder). Between my own +memories of playing the original game on a Kaypro, and Stephen +Ostermiller's and Mats Engstrom's code, I was able to come up +with this version. + +This version will use the original LADCONF.COM configuration program +and LADDER.DAT configuration file. Since this version is a Turbo +Pascal program, the terminal configuration portion of LADCONF +isn't used, though it still does set up the movement keys, sound +and back chatter options. + +## Compiling the game + +You'd need Turbo Pascal, of course. You'll also need to edit +LADCONST.PAS to set the cursor on and off sequences for your +terminal. LADDER.PAS is the main part of the program. I've +successfully compiled this on a 58K CP/M system, so available RAM +isn't a particularly critical limitation. + +Once you've compiled LADDER.COM, copy LADCONF.COM to the same user area. +If you don't have a LADDER.DAT file, when you run LADDER the first time +it'll automatically load LADCONF to set up the movement keys and +options, then transfer you back to LADDER. + +## Limitations + +At the moment, once you've successfully completed the 7th distinct level +(Gang Land), the program just cycles through all 7 seven levels over and +over again until the bonus time becomes too short to actually finish a +level. If anyone knows what the original program actually did (I never +managed to get anywhere near to completing the original game), let me +know and I'll see what I can do. + +The Delay(ms) call in Turbo Pascal only works for a Z80 running +at up to 32MHz (and TINST will only allow you to specify a value of up +to 20MHZ if I recall correctly). So if you're trying to run this on a +system with an effective clock speed of greater than 32MHz, you're going +to have to come up with another mechanism. That's not an insurmountable +roadblock though; on my 144MHz-Z80-equivalent RunCPM box running on a +Teensy 4.0, I patched the Turbo Pascal runtime to make a call to a BDOS +extension I created to call the Arduino's delay() function. Works like +a charm. If your system includes any kind of millisecond counter you can +read, that's a good spot to start looking. + +## References + +[Original Ladder game](http://www.classiccmp.org/cpmarchives/cpm/Software/WalnutCD/lambda/soundpot/f/ladder13.lbr)
+[Ladder in Java](http://ostermiller.org/ladder/)
+[Ladder in golang](https://github.com/SmallRoomLabs/ladder)
+ + diff --git a/LadderTP/TP/READ.ME b/LadderTP/TP/READ.ME new file mode 100644 index 0000000..c4bc6e4 --- /dev/null +++ b/LadderTP/TP/READ.ME @@ -0,0 +1,181 @@ + + Welcome to TURBO PASCAL Version 3.0! + ------------------------------------ + + In spite of all efforts, some errors have found their way into + the new TURBO 3.0 manual. This file contains all the necessary + corrections and additions, and we apologize for any inconvenience + this may cause you. + + Please make a working copy of your TURBO disk and store the ori- + ginal in a safe place. For help making a backup copy, please + refer to appendix M of the TURBO PASCAL Reference Manual. + + NOTEº  Youò  TURBÏ  PASCAÌ disë haó beeî pre-installeä  foò  youò +    Microbeå disë system¬ paù nï attentioî tï thå manuaì witè regardó +    to installing TURBO PASCAL. + + + ******************************************* + * * + * Need help with TURBO? Please see * + * Appendix N in your Reference Manual * + * for answers to common questions. * + * * + ******************************************* + + + ------------------- + + + Contents of the READ.ME File + ---------------------------- + 1. CORRECTIONS to the 3.0 Reference Manual [ All versions ] + 2. OMMISSIONS from the 3.0 Reference Manual [ All versions ] + 3. New FEATURES [ CP/M-80 ] + 4. ADDITIONAL FILE LIST [ CP/M-80 ] + + + ------------------- + + + CORRECTIONS + ----------- + + +Page 253 - MOV AL,[BP-1] +------------------------ + The correct statement is: MOV AL,[BP+4] + + +Page 293 - TURBO-BCD will compile and run any program +----------------------------------------------------- + Well - almost. The Real functions Sin, Cos, ArcTan, Ln, Exp, + and Sqrt and the pre-declared constant Pi are not available + in TURBOBCD. Š + + ------------------- + + + OMISSIONS + --------- + + +User Written Error Handlers +--------------------------- + In Turbo Pascal 3.0 you may write your own error handler, + which is called in case of an I/O or Run-time error. The + procedure must have the following header: + + procedure Error(ErrNo, ErrAddr: Integer); + + The name of the procedure and its parameters are unim- + portant, as long as it is a procedure with two value + parameters of type Integer. + + The value passed in ErrNo is the error type and number. The + most significant byte, i.e. "Hi(ErrNo)", contains the error + type, and the least significant byte, i.e. "Lo(ErrNo)", + contains the error number (see Appendix F or G in the Turbo + Pascal Manual). + + The following error types are defined: + + 0 User Break (Ctrl-C). + 1 I/O error. + 2 Run-time error. + + In case of a user interrupt (Ctrl-C), the low byte of + "ErrNo" is always 1. "ErrAddr" contains the address (offset + in Code Segment for 16 bit versions) of the error. + + To activate the error handler, assign its offset address + to the standard variable "ErrorPtr", i.e. + + ErrorPtr:=Ofs(Error); { 16 bit } or + ErrorPtr:=Addr(Error); { 8 bit } + + There are no limits to what an error handler may do. Typi- + cally it will close all open files, output an error mes- + sage, and call the Halt standard procedure to terminate the + program. If an error handler returns, i.e. if it does + not call Halt, or if an error occurs within an error + handler, Turbo Pascal will itself output the error message + and terminate the program. + + + + + ------------------- Š + + NEW FEATURES OF CP/M-80 IMPLEMENTATION OF + TURBO 3.0 + - AN OVERVIEW - + ----------------------------------------- + +Inline +------ + A constant identifier used in an INLINE statement does not + always generate two bytes of code. + +Files +----- + New FIB formats. + Optional 4th parameter on Blockread/Write returns number of + blocks actually read. + SeekEoln function. + SeekEof function. + + +Misc. +----- + Exit procedure - To exit the current block + OvrDrive procedure - To specify the drive on which to find overlays + ParamCount function - Gives number of characters in the command buffer + ParamStr function - Gives the string of characters in the command line + +Overlays +-------- + + Overlay files are opened and closed every time they are + accessed. Therefore, there is never a need to specifically + close an overlay file. + + The Y compiler directive is no longer supported. Instead, + the OvrPath (MS-DOS) or OvrDrive (CP/M) standard proce- + dures may be used to specify the drive and subdirectory + in which overlay files reside. + + Please note that run-time error F0 indicates that your over- + lay file is missing or is called recursively. (This error + number is omitted from the Reference Manual but is included + elsewhere in this file.) + + + ------------------- + + TURBO PASCAL Version 3.0 + CP/M-80 + Additional File List + + In addition to the list of files mentioned in Chapter 1 of + your TURBO Reference Manual, the following files are included + on your TURBO disk: Š + Sample programs + --------------- + LISTER PAS - simple program to list your Pascal source + CMDLIN PAS - get parameters from the command line + + MC PAS - sample spreadsheet program - MAIN MODULE + MC-MOD00 INC - sample spreadsheet program - INCLUDE MODULE 00 + MC-MOD01 INC - sample spreadsheet program - INCLUDE MODULE 01 + MC-MOD02 INC - sample spreadsheet program - INCLUDE MODULE 02 + MC-MOD03 INC - sample spreadsheet program - INCLUDE MODULE 03 + MC-MOD04 INC - sample spreadsheet program - INCLUDE MODULE 04 + MC-MOD05 INC - sample spreadsheet program - INCLUDE MODULE 05 + MC HLP - spreadsheet help file + MCDEMO MCS - spreadsheet data file (not for use with TURBO-87) + + --------------------------------------------------------------------- + + \ No newline at end of file diff --git a/LadderTP/TP/TINST.COM b/LadderTP/TP/TINST.COM new file mode 100644 index 0000000000000000000000000000000000000000..f7304963e2f3ea264b74fe6d02aea6182c035f82 GIT binary patch literal 25472 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 DD>nmz literal 0 HcmV?d00001 diff --git a/LadderTP/TP/TINST.DTA b/LadderTP/TP/TINST.DTA new file mode 100644 index 0000000000000000000000000000000000000000..b77c1c1fd8a979db4667435a65d0215c085c8012 GIT binary patch literal 4480 zcmb`L-BaT>5Wpqb!*Mr2`RK#-)Vb=R541xXJGr#XFn!1+%p8RjN)m3kywm~p@Jte? zj%lC|nLhMi=>OYY$u71NW0Rg|(8pSmf7xBFR=g(vko9`A*%lS6T&b0-7SWGsaO*5= zFRV;{nUGV%6oL@CmXIboj2|cZgq*#kgs{{~um~kD6x185{Cz|OQ$Gz9-9QTZnP$;Y zjJKf6_yEdms4WF`;mYaQb4NkRuETJI!aDPr)0Anp zs`4Dl-NjJgQ)d0=_K}(uD{`S$dC#&AEbCn~>6r;@5tH{SKM{lXemk&L&mN-88p1G; zg8iUppQy40J_TaNdr;B?T!`xB7};(fHpIE(j{4qoPwb1n8^BZ?^4OCLg_99rIjD_y z&YyA+xFad-nibkG7s{M%C72;3V4uytjEULo3nlwX$=D3HA)BFv*=z?&t*O*Xpf5@` zAD|8=V;}WYKvO19L1{;49HAKB#zmk;9L5n1YX!v>6yE`3hvrMJ1S2WgK6dWMz9*(` za3gNqfg4CG-+Y<7Z?#+^7j@G0~lVy^SUbpS+1&)$7o8fs6BypRb@ ziPIl_GNH0(Jq2p#L^^({?aGe>=?e&2rOGmzS|%i9XbOC49;#|DZ9c}ojj1XxPGvxW zPdz(v`_d2YV~Z7X^a2rmd8oCPd*yq5DaA#zJC@g2eU~2+QisFBV}@~ze-w&weTEsl`!&X?uE4obK6Rqnm{mbO zl>ue`aytxBaH@WuZoWmS%l~ln^G0dERuj8NoepLi>dA#NR-&Q0rUnxNqIM!3rhns0 z`WKc^t2ht3!8XJ449_2$S_wtu^S0-ESHgxYy*?ffq-dO#Te(mf=F5*$2opWoyKhrN zjpS4ey=ys`;FM*d=&Mf@JlpM7sr$AX;j20qYK5yD?_rX*r@ + + +14 CURSOR MOVEMENTS: + +20 Character left +21 Alternative +22 Character right +23 Word left +24 Word right +25 Line up +26 Line down +27 Scroll down +28 Scroll up +29 Page up +30 Page down +31 To left on line +32 To right on line +33 To top of page +34 To bottom of page +35 To top of file +36 To end of file +37 To begining of block +38 To end of block +39 To last cursor position + + +15 INSERT & DELETE: + +40 Insert mode on/off +41 Insert line +42 Delete line +43 Delete to end of line +44 Delete right word +45 Delete character under cursor +46 Delete left character +47 Alternative + + +16 BLOCK COMMANDS: + +48 Mark block begin +49 Mark block end +50 Mark single word +51 Hide/display block +52 Copy block +53 Move block +54 Delete block +55 Read block from disk +56 Write block to disk + + +17 MISC. EDITING COMMANDS: + +57 End edit +58 Tab +59 Auto tab on/off +60 Restore line +61 Find +62 Find & replace +63 Repeat last find +64 Control character prefix + +101 Nothing + ^Q: Quit, ^R: Last page, ^C: Next page, : Select terminal: + Wait Sorting Definitions + Change to: + (Y/N)? + y + n + Text file name: + Command: + Numeric entry expected + Legal range is + , please re-enter: + Choose one of the following terminals: + None of the above ( Max. 20 Characters ) + Delete a definition ( Max. 20 Characters ) + Which terminal? (Enter no. or ^Q to exit): + Delete terminal? (Enter no. or ^Q to exit): + Do you want to modify this definition before installation? + Terminal type: + Send an initialization string to the terminal? + Initializaion defined as a command string? (No = a file) + Send a reset string to the terminal + Reset defined as a command? (No = a file) + CURSOR LEAD-IN command: + CURSOR POSITIONING COMMAND to send between line and column: + CURSOR POSITIONING COMMAND to send after both line and column: + Column first + OFFSET to add to LINE: + OFFSET to add to COLUMN: + Binary address + Number of ASCII digits (2 or 3): + CLEAR SCREEN command: + Does CLEAR SCREEN also HOME cursor + HOME command: + DELETE LINE command: + INSERT LINE command: + ERASE TO END OF LINE command: + START HIGHLIGHTING command: + END HIGHLIGHTING command: + Number of rows (lines) on your screen: + Number of columns on your screen: + Delay after CURSOR ADDRESS (0-255 ms): + Delay after CLEAR, DELETE and INSERT (0-255 ms): + Delay after ERASE TO END OF LINE and HIGHLIGHT (0-255 ms): + Is this definition correct? + Hardware dependent information + Operating frequency of your microprocessor in MHz (for delays): +pendent information + Operating frequency of your microprocessor in MHz (for delays): + \ No newline at end of file diff --git a/LadderTP/TP/TURBO.COM b/LadderTP/TP/TURBO.COM new file mode 100644 index 0000000000000000000000000000000000000000..91d01936fedd6e93874ba063dd5b36e669f7d8da GIT binary patch literal 30720 zcmce<3wTu3)jxdB+%mb(BwWrUT+W%{axx)dh?opRG7y*$Zx9P8AQA)#5eW$TCPj)_4zU#f(Gf48yjJHJGuEI^s}q9Cgqjs2RTBIwt|zzR&mn zp6C0XFPfZv_FjAKwbx#I?X}k4``|wzvOg?s+u7Z|t@)N+qP(<3oVUPvxwxcZm81T4#ySakUXEE z<2YUM`iiSKZSnf8N_yTklrwKRfRJ~!nzw`U96ONL+g}y1jl_G|DL$5}5x?jUGG3FL z#Rc2q>@hBw-v4%s=8f-YPVN&viA$gIf-Wwd;;j=ju@fVML%p_sIU~+q*TsY{!oJjr zV9&Dw*9`uid+s@bpF#e0oewBWg%8;=e%SsRFT9INaq0IwtJFxp<&kTDk$+>FCWgvE zrRZ5+IHe?>;Dz@_T<>xHvI$lCD&FIy098{#QII|_pFxTHJQcml3q(&``ZF)QMTxli zGfw&e&zrd9lVR7d`3BcR{GCHAstLRP3opOo??PJoj3W{r=Ghnt$S`o33F(*o{L5uc zL9n=3%GMgRrFnC6e(LzJ8)&)Onw=l$r1m;Rcy9J@(-k{1kS1Etz# zaY1tdCwyVf;RK^OpA)p^OfKe&yQ1h)(a<1!nA`iDoX_6ZrVB+QJ+w!LL|@p>bCy%q z*SW5WDA(ODXS@9sPEPt}x^)33J*G83%<%%cBpuY64{&@Al6`H>6~{R18=Unx=kBct zbKpnNKUwRSw0@V?@6h@$*ZND9w50WMcXCU)L);+etE*zi_)U}mDI!;v}~`gi2Y8Nu5}iqzvalQN0Cc3bRAz@C}@iN zq#L(I($TsSV(&eI|5Xd&_q+2+HP|4X$ zUk8g&(TFOUR0Z|r>`q&u=~S@Ly-3iw#ZH^)n;V;Ad(xYR)81pp#o%7{oUUhNI)2zeUFu~1;d^Jlws^Mxh_iWK_$)?d@Jd!xk zVQaUA>CbJpoxy0VDQ|@Z-eMtW&s>x zDRK)G2uh%AJlo0%{{U2%+V!2bD-2wMx=&micHirlMWnz?hc?p^bl<1GCkj7mH+&}W zXU!ZJ97+Hp5fkVk@m!!Z$ll8qM%YuC!e?sMz@=HNBLh&!{yi%&tmb_|H9sXVjtdOi z6l@pscy0_#ZD93=tCtW*_Vl|=qIQ+rSdu77IQYyO@l0^jXiq@6oNdkslwc6(Nkyiw zf{8u-qS2c+IkfftK_Ckz_CCJ%t9=$1{*B2GNsOZzvfq8AhIF^#%)48z*s=VIkDrAJ}^jL@O5WnZ?-_thmEDrBjiz z--Lpz&&3+|sxdf8wLDaIE`Yr>VLD z%C6|3oCCdQ%N0+fdqN)c&Bx)G59tMoFB-RSqvRD`95dCNbh}}2JTwR z>J6ExYD^A6GqrMdoLk+t=Psx2K#$Ydb-#1g zeNJ0-zdU_#$o?U>aq1*)i6t{U6u%bZ){s09_6hnu)v~3b>%QujoV>SR&I6dTK=IrH zGzk3YR-r}ha@niR#unvUhPpIUVRPqZdd5}tej*_m(fyh92%ZZ|*vxU}za)F56PbKQD&c|PW^ zBI?Km1(3x2va(1Sp(9FAd(NB`gl<@oy5`3hl~%mj`n-MWr_Nou$GF^Md%lYwWA7gx z$IqNHw+=HU)P-(F*n|0zp7J{$7y+3Pb`N-Qr_#WjG1SN=D*iLqZBVF~6Jd|!gX+Aj z6zG5=bMP}+rU@PRxk3sGdeY4pjbP9Be>MEQsXeED`-5^<&ks*He|U56l|Ppklq zn7Vi7fn{rN?w$0_r=z>~zy9Uq_IVipD3}X2^wDTlhYpNjtej90XR=bE^CJ=duLkoE zPf5L3(HJ`PY;L~L5S9L#=hhe_Fs!2%whJso6`IQ*M_^`0Es+Ro%MYCeXGnH-k;0-T zE@d$AL}LU-e4VUxN|mP+=6gdRbT+u}AAdbsxO(52FMjLD+;^+*zAVH3=YIYDHqZV$ z=eStmekJD)I8Ge5U;6D^`B(OQ2)@5~3EzKw3Ev-&O4<2tJ;)hTpeb;Z1j+w%;%8gF zU{Xb1AxM=lFt|oMrEoVd3*JQ30^Jqe%10YD(d)I*6}sp$eNeiC^IWs~#vq@6rTMpS zNq0&?UU#|qvd^VEz6$c~^UPmPmiE6+raa*c!tRjvb8bkYm>aUGYNHHRNn7Xura3hw zYeHv9$ooS*@{~}QF?81bqnDkNpaGz=h0pQVc+<9k|J!6Q1>HZ!ssO{MBRjO$2&2b+ zZ%IvPul$u~IZU<9ZN>qh#fq7j#yNFqi&L127t-33GGux zLI!)wlzaMK)1H2Lvb!ARIUxB1(?s#hiC;Z!LZR?w$Qy9ip~PJZ8V!4so@NEnUc+47 z@hr#Jhh5Q~FmQyN(Oz!U)-UQtOWk8O&uDy3nV4tD0X2?Mo9S$yzt;?H(-S$qzwN)8 z&C5A<#$eWSmc8kS$XAbca!C)XE$B(#;V`gg3q~*Jz{PJrP|nFl@GmsAMm&o)M%+2Z zF7ij=cArk36ygz-zaQd-D!-LUyH`sychD95s9Cs`_md*-} z^q;<>An6$iEeb8FmcBX<3AfaU-z1_^SAjCCQzx~uaRjts8k|k_pT;DHno+0R4>9c) zPx&RR&_BC>&zb)Fja#1Ay%H?W^Z#)$(N%Vgy;l6{s&~$HEm*`SN`L>S!Kr71-q(J% zm=>F}gF|~U3i$uq&6n^NBegesPF0}iu$Cr69xrI}IJUSDCXo?_;Mwj^_y%b)yqaxf zSzRd375PLSSM>Zr@qIvjiTt;y5`3*f)42rfF?yT(7`>i_n}HW4eNH$*UN+{?f`lY; zbqhveE=m%&pcn2{pI|6m2FL9&$%^&>Bl9*G!hIDVa-%W(>zu*FPQWFMS>NYI<1o|= zZYv!BpzA{f6tY-Rd|u8P$}41gF3e9#4dUsm z9_XT;5SYMO#zO(FG#rituA1+taLb^z-K|P!8a^dnC zvDp3wT*KoOo^a|7=UHL`GJ0+3i7>fFG$=8iyc$aNA=;y3&v8Ad9Qwr8SsJwUmImEL z!8kH74rzlto3%_#OAaIYstY|Kq|6&Q!?eL603N2gwScbmZXs$d*-LQljxF#-*PEH%-`W=;wW#@X47u#Z(u8rC2Ec1EIud`Me+ zA_#!7@<+{)m-spR;W!Do2r?DP8KEa~3JXjh#cm4{y+v|i=!tZeoSV)S zKc$Q;Q4@NCSlgh;FuEq1Y_@o>%D>xU^FI@0barCQzzxQ0jy%TI)ExOAuI9)eIself z{4du>+`+*7MyTN12n&r!ppwg*hye+>KO?c~@&9F#FFY89$k2+z&=(;ufn+9<(Mql? zY8zsI$sp&JW@9uS!|*Im+~>@bbL!)6aS+1pGkqDW)#(Gh;L2Yn#e6p5b6;4o4-~vZ zOg0Gz(FkyamP)^!oTn3Cksh0zrxy;aUU^;Jvf67_)u9Zo;DQx4cEjZGxuIZ;!nHZ| z7f_l;PPub|-JJ!3&AGggYtE%$Wf6~HWf4uHP_H~i8Q+&=6F8ZJ(a(VoZp7$+i1f4g&g-~7mSu_AC_H9ANzt@` z`(EN;9HFgFTXOwL4l$`1;M`h&mIVa$o*W3UJ`4D6F5@f&Wq#v4u-gcR2Qn1;@0>6` z(*Zu<))7X9vN&5`L;<9j!$b`e79(ewKVX|5bU*k{PyllCqKP1&9OsKV+kDyR*2Yjv z2*li{3Ao}EmjFO$t2{UKnClc5s+R>wLuqNhXrk8!adKC`SlHeFmB%tTlqW$z!ang^ zsGAejPj9f)RO1bhHrvU4o#G@iXZtL$iuWP!U{IKJ#bUtnh%{heY#0JoRs;rTI{3n#llw{%$y*bvZd9o2DgS`Zv)U7+VBvvYjzRp@J22Z!-A!q9znKz%7D5e(z04TAT0VPgJCpI0C5-wvAB84m{mYq2Z{hd zgH9%5tL4lK)`FX-(NouYRCNt={ccGnX{Tn)V@3s@dHK|!{8wrI6!ViDZvj#>$1C$2 zx{c@OalHRYPUQ}PPoS0*CiKgvgerxX`2n{`&4J4lG)s_yv!cVcteu!3-;l7OqU&w0 zppef7dV`>Z!QQJS$&; zAZfnpnZ=`27!yv2SX94p5t zp|lR9d=?uTjU})Cj2pd8GrChdx|Tt%TBe^SXQ~7bMIqc{*=mkZ z4CKjG?{HM4kWbjuE+jJ1%m5m&D;pnj@n|oHDDh}7AMNBvTQ#FwwVBb~n&>WVAN3BM zGw9Uq9d^w$`xji09%q#0!}y#=@p&4U>SNW0G`? zgO}Fd+$I~r1xOusFknD{GT{-7?#7A`7feKBz8F+Ub_YaL*00`BNc$q5<)odE@dY+W z9Lem=L?-r&4n$8~ht*fhemy-JyReaTn=OHOw1%opA|ZEAUv|KuF-*7RaWE}&d$DV$ zOJ`yQ(+i(&7|$`LGi4>G=YCn2Gf^CZd$T$i_6?P7n(2Q;(*xI_El69D7RxEM8?@2D zCTsUT7l3Iy(udtiCTUZ6^rW=|(U_U%1T*Q;KossNFX-u^8Dd^-m|*R%VYd@ZNM3!E z#CjqI_%*O9V+cz|gbVNK7bn0bZd{t1bzMhOySTZ%Y14L2D6J8*mEGto=QbcPuOwIQ zZY|rjZATM_H?gU`y{%p3yx8Nz>m2dgr8U$Pdr~J%M8=A?U1C#f+wSID#2rmL+S#!%!LW;BEEe}w!MH*Hj0cQ1eE0;8g*KX>#c~gtn(cQ7DX$OY} z4H@imD!#s{y<=Njt9V(tV_q$&HWaJ*ORt@~yv*sCBi`V2&}C8dx9!-8Dx&!M?pD11ZPV>d=vLEk)6KhgA@|U> zb_Glf@1_bjtI+M@Uw7^Tw>tp3x~Xdyh)%AbRcDv$O4($XrgEL#UWd*sYj0{oS$qg8 zku5Aoj<~sdS5t>5b1}#vLQO|tHX>1i1Vo`mG=aRaM#M6=$OR4A{>vq4tt}1~K!n(0 z8z7h>urxTzEBa7I{l1WKbD(uB1L8a6N%Qgs)cV`5P3^nHOz1xuwbt{khUH7ISXH;|TYsAK`x)Ic-n1L! z+wH=voYMAEZRuLu^x3xAvuDqpy?pkb*}G@N{OhcWFfJb-Yq50`>44rcw%F>%_Pi&+ zGRrXf7fcxGmou$BGueAHm3nK&q@Pk{>Bvm$jWYp( zGW)DL>k^OEU)RN9Aw4}S);|C+!~UZ5 z`M}A2m?0ELIxQUczfNi{H)|P5b1RhF*0$ZPTR8u9~A&f}o(f;tfwBpAY+v)=A~m4y@9rXMyc;0-pqM@M}dJd?6FBzC9c>?C-T9 z;80jU7>D-_uEE%IqrA(oA3=~4UB~yki^O;GOhD+bZ^z#u3C3$BypckFGFl4LNheYC zY-?}2c^54XLe^MD$983P*}A)>g=1i@LhsYFTyKCc=S7#t9&| z27ZRNV#wo%c=DQ6m(EE{XDcS*p#x>s;~pZQ4s&X34pQ0J3PI(=C_gDGE2n57Atm5l zSRJojN{|5t7_4XpCT> z%q4pP=O2<8bwGVqx708A#6O?feE5liRWPv>;alEXx z>$Tw!t3rnrK3v~ZLLb#WjHUDgIuwU z)GDn5;6Ke^<=OzTv~3Hm1pw?G5;a$`P(q050s}O*clI!;`DJn!N@1U4ngxmtGJ%z#u@&I2b zoWQG1IHq<>)ggTta917}xCpx_SZ!l7Ng?KUD@V*&dGqr^eawvO#047M%fQ%)S8Vk-Z~ZM(6xWoKK*Hf59$ zzL`>D!7asL5sjT&f?T2$ zi;7tbW0A-ZX5-a-qvURou3yQ{mj%rGe?%e*x0*r%iarnb%O9)9D#uJun!lh)p%-=J z6Iix};;y$mBhshZxby`VmnuAQNiW6y+`S6p+Ql84NG&b4vQM?Jit5`(MqD={@}C*2 z**KDyhm6$W+KQGrbP)YI!BLY48J|LE6-v8R`{lCY_hobZ1VPD(1Rw z;cKRypK?6k@wH$;TM#5ewypQ%K8QhATIUvz9?_aUohoOzMdZM-d7sZK5dM40)I;y{ z6XaafSkb1KUu2q~Y&v=kM=jc`t)@+`=@qwmqpkYrR)e+8Yh(XCC!SXfh=je(OGfp# z=iIannZU9{v6@yk?Z6UG^SPl_TnkzfwP#wG@B$v{P7%KZ&X3MQK$&coZD z{-9cJ$SL~iK%tEshFNu$B3T!-%mTiTbOtnnbygk8+;VAEJ>&;g_|faiJ^bSea*TSvdCO! znd>N*|1LdLz6ZNHSzzeNeQSuJ@gZq}$6VtuqyKD<^5$swIMv7W)}>m7IOP z$DH!ALkk@bjfM=%Mvk)DR4459?%J4jzJ~=D`5!7rh4em$HZ2~Lws`2|RUA+AT}!a* z^2pp6V#3P%)k_W2mG`PZjhrPNUz(W-ySR#49RY^X`IBs&siWKG3O+Vr3A=5{KwRw( zaP^MZdf7d5u`7CpIQCj~D!uPmT73P8c4WleNVDVcV)`4*J3knY`HCOx*#cfarqo+E{zi^`72-v7_=l+O@8Qz}?^h zH`x~pnXekEBJFf$N}QdtCeM>N1N*G@8Z4UdEI1R=OWRr~DY#a9&|_p=*$RJNal^=g z|E#v*_NMmE_HFRHIM;f>WU(_eh6&?)4k-Mwd-BpT5R^fq$Snf$61cB($1b0?p@~QWqb4;CbRNxv zP7x@mVmRaTngck{H~-yLBk*zFbENhM#zh6^Io%Gqj1EWg^XPCS{^D>X{zALqFVFSC zM$uLa=PZXEX@{uA9*rKSi7|2gitv-lg8H*vkAT-`DC2GfI4pB<%r2C1*wH8&T}>V~ z>=xqPX-?Eu76q|ah;4fQMaSQw^LgQ_v|cpPt9*!t+D3VwrFCKkdtsjVwa|xMcs&W` zL~J?cq^IDdG!NaR5r2wu;l7Qi89m53zKd!dy*3~qRL+wKNcta~hctpSm-D5F2)!Mc z2flyz;qO8UaK^OaCJ%de9@A6^*Rhi|%i!j5=5~*N>O6L;W@XdPmQ6P|iJjYa-NKpg z_uwr5shS4WHRjCEdf3!?5R2xSY|`7-k^kE_E|Pvx?q295I*kX|O|V-%y8^~S| z;?<@~r93yzK18uvN?BWvzOvADlc)bs!F;?mir-IO-QvkkE^YB30G$%*h5#RSP9#WK zTP!?NC_D+$komf=f*rUFx{Rs~U^G-qUhLS_PK)9N8X>&aqM>`*lbai6XO@h5EGqM2j+thrT&guFxiYVBRIjIm0mxb-sIG#y~F)Mg`RBo z%ECoza>RdZVNse791Ni3dhA~wzRaO};^e!*gTeUr%_Sw4l0*!fxwkEm4FFgnZUW&@ zwo3ZCON2*`%zdo{Gh?(>Ke|gdNj`hMyK; zi@0JmRCt(lw(BPzD6Uw15aV@U!-#{|6Ya_Xr{agca)*5sPL&?;z&pEb$;hFS+LUM< zVtF;JxE7OzZrs^n?0-?6>#rfX$61A^Yjr}3bTbeoT-*5L+5@5%xp5T-`>(2)@JqF|I1mwprXCcSz8*nY zD&~xh;c^TkSNNOKn6hFA)aHFuS*@s5D+*5_OF`67j}iqLf@`&EhfH6C5|XcyTJ&Tb zvc7>JpGLFekdzkQP?}TvhHVm+#R%M?H-J`T^a8KRjzfQcROMdDGU#kJ#8T_hF^9daq!jfC}duSx^|zLa!PZ24ggav&QBZlt^hQui;1|x}N0`1Y$R6AiOo~*UDHID^jX=E4I#| zg$d^%ZNNFHzjk(AEj?!nXViWVvuCT=jaB{`3qd)wpEBmo6EuK;gj3O7iv-m_D}07k z>{ZyjKV0Y-f!#{aukm!j723uhtO|_I&m29d56t4)MzD~kFc0dn`G>AJ&caiG`3{}@ z4gM%Q7jbkh7PP^o5xyuTT_7YO`o|UqoZ5rpm$qOjw6*Y7I(MKKrob`b421~l{eQ1! zcU80BR>MxO@0atb%n@fFEyUrfcT6b-2HI_zJXHmYW2DC{zJ$$sizg8S;~k}HVRHQ~ zio%(qV0l!<@+-EZ+VrlHqr)++Gs1r$gq3l4@d)!)r(k0%w?UT+ZfXSv$%JL%;^g{e zgvSX_;0h%n33I4;KqlIMEIS{98_ ztP->~j8Q-tS5U@l2*s_%VK6aj)5}f7%h34BWsFPb&jSjoR3YDCp!a1S_r7~8zU5Kt zn9h>81Q%gOW9i8|4Dp97)IbJ~LEteYPb=59^r8l53W59)|17d+6kmNd{mM3$E_uxP&*ejk5 zs;kzqYuCZHq#3^4W5>Wua?=utfkEO5&$gRvsud7-earIztT*gZp9ceBt@)yOf_1ep ztY?CE%Akt6C|2jOfu$FZ2Ys?dZKi0n)SZiT5L<8%W#=pyKR7Rw83)Zcwg-<6-i@*i zCwG*HElpc@QRm3Ys$03TVWmrK*u6_^+bVYKgl9uVaNpAt$=bHt?c$XyRs-z1YggBK z#>!ak66~?W2OWFJ*d9{uBA&pG&Fe3@H>@6F{|ReT8%wT|>$;BPUTXay&xy$cyvtg63=k@b!%T zlyern;4Hkadh~9tVugnaYARNGU<=`IP|X~z)NzW5huJc|&ceC_{XD!am<%BG$e$NG zVU8+k+~0k=R@>bVH(dA_P@|Q4oAj%e+RWCRTa@FaSJCeh0)*wKg3cxzL zh~)kYNKkVz)!Ep6|C$NTc@xD97&yybjW3>XzhgGU|Hn>Ao{s1cs9Q1w-4|!c>X_*a z+73@0?a&8DZ_@`+mJJ-owLsDUw*g?}Yn%lT3M--+qQacCRpW7Y za4@vzJFcmiSvMdQ+T9-OVvllj zpNUIwJ~0)vFZQsyCCT+}4=zt80?HM0+;yigUo3#AUME$snc;j;`GB;}8;lPTI4XjM z1f0yeCB0U+ha%0|Fx<;aO7S}4E#h-E#UB2=rg$lTo*uQD;w6;&|LQ-w+w=d&51-2y z@g&6Ta!IOlWo*wYc<)EG}#tSc7Y~)vL;){XKKv&KSyIWXv{pHgN@Z{_nh?` z%I&3Pb7#0}AIJ0z<Rf}Q`2UB*E<70)|eNYfL3ESE_GMj=dJj$x8f(> zir;!G9`;t8@K)q?SNzml@prE^>a~9AWw+f{YF*v!&aJrL>mI52l^5rj|KdeJ%lf9* z8u3P@H@jg8(B2h$v<2&6skPI)dIJxG1>Yp-@LG3!tzIwtpY77KyOIak(K>8p(lP(8 z7WQt-sMXNj=O1imoo#GwYxZt&65F+mjke;n6`mul@>zCm8?(2$5#i<8?c327s`twV z^M34kwXj{=UBB{%_D#YKm5D=cp7n0W5!3GN5>80nvfV9>zq`%jDcbvN*$y1dVEiopw#KNwJy&L^ATI?O(INP=(hJFQI zfANmogA>!BBhJ>LVQQIGxAI$e14~YCnn#Fq=M}=o2#f03gI5TjAjGO?>?$FSKx!t- zxf(mNCxqd2#;c33pkA@(+m}o8yUkB~DgOVY^iyx|{6wY0Hg-L1r|qz-Q@UXa2!<6# z#6RsdWcQ+H*q>3DngyozVF1Bcd(<1ZYr5n1C%y4e>}gXB{YkI%Hhs}S8rx1+>dXcf z^Zah*L~CN~!V7JYU%EdI!fxz?JXE~x1tKvP+h@bl(ScaQ3#%Ua=MVhs&2;-b;JX~B%RO3dU)FS9gQ7as?9`U9s z4ts+*PR!QqfRwN;?W}Ew>nC1z;|_z?eI5_fIrjSQ3{n7_RSa=3=&?6BYD zWvf;q)|Onqoz`|++}`MA+g64NJV(sN$;S+uc@wbQUC}lK#9?qsp2!xr38^9W?zV9E zOBnGA=GhJi%*xUoK}hy>Kn-};25*CXvzPXWaJNgxDq8_t!q%<~+t*TS7QDh7+w8R< z0zg#b_Drf({u>a5X~oAEXfkMcN^!rR5NpM~MDu1Z_G(o+SwUOW`afQFr#@=OBho6D zvOiuGhuYY@Tg*XHDSb#U7-LH6$0{7gWSAATfycbaDFuZFLVyfcqgUA%#vHb|+Pw8+ zQ%PyxC>Ep3uFc+>`|4@e3by>>?QqK!Q9X-soX(DJ!+6SB=`3{3LieHR#<&4T?7AUj zK@dc>dye#O_d_il-3B%v0OXwHda%8%-HCI<7?HO2;Q$7yjK=q$2ffgc6~FclvX^%pS$Yl09i-CkMRST` z9&ZQP%KyprQ7=+s@;lmU;KY@KmjJD8?cB}d)+3)g2s}O=3H`_*OSX!c-4#FbvaePM z**WN^M*3ox^#-pmwzKp$5?7q2>i{&y{3(q2pzCM&h{PrmC4P?mJ)w!H0@4#q4da2NAr1WVKG*EoNcHLRGu*X&_`w*)5vc8`~0nzF24JPHGU7 z5x6QjyaAGG%7z60+4;-_3S+{=UedXxl#gbwVO_0ZG>`zppuIwCaH0cR^DeK#EG%T; zS)v!nmX+dOL@9l5Dq*9=LFvm(%8Ms3q0p6zd%O_co{H~!6IdOr-}5HuDoUxKqh8T( zJdf+@m#^x*qhWAaX)joypo}NLF<=0@PYmMBuMPvzi}@ewEtS8FlOj+@>GwNgKGVCt z6MYr;dfEI2ygXm4jFJ5=4D0v2ao0WG5!ZL|`!nx|^b_xVEO04ELka|?KwAtH#n7?j zs_%F)@ysyvbFnHWu$)SndaN%opH6>dXgRCct{IID()AZhytI_a_!?8%wFVS$qp3nlEj?U?#(=XP)c$O#udOfs>rVhtG(H+pd)%!-oh zwzJVD^x#3Iu{hRY5PZ49(q-rhdIA+$RIieP6&*IfLLyNG7p$0yxoUP9WeaAv9WdxT z*%)YZ76+!Fle3fSzk`)Up01$IQt-MXhkCaw9pAZKvgsj7f*y5voRw&U%qg}Di5@Nl zbwF);6-5?M*wKrNc{=Qoo*L&1MCs4%SJJHj%w$~Ho1}By=iNvHhBe@lkyB^PdpHY8 zrUd3S<}YN|v)j#yHdG-rSMwP9N*F=ol97PMePf$-pBLMj_j-fu@diN6py7A@$lE_a zL!lo|8;?PgEM-4i5g#0%Sg)+`x$Y&Y@2VlZvB5Yhfb;mc3Wg;??TOh00mG!AMaZ=8 z^TsV`Cx%bpV7%q8O99_WQwh;IWz8uqE%ljjHsSGx0LY%Po4t%g@wEZ=A%3mj3b5t) zy$8R)!|!SQ`rBvloEF^~pxZ>MfFlIBw$;8Hr>EM$DmHbc&wc|W_a-p8QCXYzK8K09 zIj(4zcL$-r*{!4m3C!9^a|`zk_qMag+c*0lL^114UL0b%5lXIdrO)&hVXxdh;Q9q- zzt^DH7VxP3m>)Ti49x<;_zKHh$ry6~g9 zY%n>T8d26(ET<@&pAueHM2|#JnJUw$J6SY6rkOb-+66x#iPDW;gOL<03}{f&7c_74 z3KM!up`u8eCs(bdXTl7@0$f39q3J7M(Aw=q?c~+n7=GL|q#L7|z0gs~N)Ec97pDE< zQe2{6h=n5FSbDtz+o`~UEA}yPt@u%VsI(LxeA0zu!aLBc#qw#NZ&~Sz*lnddWB#6% zeH9OQD}r9OZq=yuQ7=>zAzHtiWX|HalF-tUtkCrW!8s?mT<3yEMzu7A{< z$Hltt!@Qo+B1{5T>W4L)#b6}ov99+$_$us-8hH`P@P2ITlErtlox z2^VANy0_bGHgt;psAagOFF5BAFb=rU=WZV4~4kw~Tyt$816UkPeY<3|r=4Hb(&Kq#>@QFAw|lVOx+Sy4hqHx5F6)G3oLC_T4F)zX?xB~!hPt5GX&POe%o+Lfy#W6Nbr3OQq-6rbcj0*DD z0&j${VXy^3oj-DxI&DDGRi!kM6Jehoo8AStT5w9P6xHS5&^;bJA9OwD#gQw6BWuP? z(a-~i!$j!b?w*UnBR$vquWcJMQ-?^CLDeV^mR@wS9pB3-5obUwG=oFJ6!QH_n{j3d&rQv2(GJ%(Z<;&wyS0#F zOcNiz97*nDUu-<}1M>G`P*@qTH4~6U%uwcsy$0;~I89oAVacgBqhjTe(qA@KDn>r^t>%pL4^Yh7EsHL_5R58aT#xn4Es%=RWPxTC&= zap3oYL8>^*nPLuxODr>FN|`3X24!yUf=fIVUk9z&u4^ji+KqlkG&QimAI1$4yYI zhukif9$)8{%VYO)05lur(P zbGZSMBmHQSP$YFsg2P`Z)lEw0$T?EOBq|rR(uzqyNt)t0^hf&RB-bO}{zDKDjBjhI*V zP4r@c#%}acn95GCQwC{-ks}nt6Q*oUc>yLar7}@OVMx45e?S;Z7Nk9s!5*_TdoomC zmh>N!!A`AYQ|K6JJz`u>+<9%X|G^uiegWbU6|BGW5-%_=HtD|w(5ngwScyxx21TVP zbK3qpFA9Z!ki0&8gLJyc{7Mn7#(h#`eyIq@w;_5Nz%g@79HEHD4k=T3V_b|# zM6Fci+l^yf1sl7`Y5-%iTUKIxTd1frD= zPV?V<<3-ZczGdR;C|Nk$3&C_}iPXd5k+GirFP%?GBh!GZU;1L2@HC<7Zj|1hesNmI zgmUT1>0=x~*)$D4pfQ7%0?4P*buX>k_X5W`vT z&;~ykjQ!S@Tk zXZWFEzu}#NhYY_l+;89u`wY(-9y5#<_zeNW3kHsR)9|)|;rWr_Q$q}v{Y?tJU+?w} z;6?_u+^dj`0=Q!RVm>XOS>uZ*dJ6Kfx?MHWC0Pp1vkTFM66vE%^XHl9#&mRIrV>TP zjRF`3WVs6eMU^QqEIfc~27H3%{|{0%)RY9T^0O|n80sZgtp-@_-lv=C(eq53zh~pW z6g{pM{eg;DNTvP#f1^D_wAauoj~N6*fOwOsFun`7lcq@XiENW}#-Pm5uR%I-lL&i4 z;WCz75Cywj1!3WqfNn==u#T>Ec_x6~FPa^PBLtkn|3?h1vp?)}T?k-ArgB?2?ZDCX|L z;2Nbz$OxKb+yjCO9X4Q}4%<)!ZYBITnJVSN*Hkf2${e%3x)jNS)s*XfA*> zHNYfRLh+v)GJ|R3tI$s?C_w063}26YQ?YA>pSNCwNNWew2ya6$&0~<~~t4wJ(j5pY9l#K}0URu}OO{)2@fZRTVG00wR z73-usl>la>6>+h^AhcGO4`2J>8(u(#IfIae&AX)^>k-R_s-eO`r9gU!YWWn8#E*a& zwrUJeD6sU&#lF8&G?4AocMA0zcZ;|h!(naqo3^OIH=r(onOFq!9&evE!op1{bT`-} zePJMx(@JMENkIjh=#2&&UpdC7Ju`%>r1~5|lD?ZGOp*5I2$QAyJfT3ElPly({khPx z>1=4(%X8v{E7OG9M-e_Y5HjiAd=%lct|*G3AYjNsF3uIZOO^Kh2qFwLQB(9m4<)5- zxtQ!}X{KE1Kk%)7!uBwSFEd~*fHJcsp{-Ao9SrCfT(2zz4ujkG=15AYiaSSc;WvEfnyV2|JgQ6m%&vT*?N z+BV^R>7nVkxeWSxryGpKy3tnYxqL$=AXOaI8A^Yp)6+qBq)Ga+38pTTt@Qq6ux%J$ zc9Ei!@y(GY#W1zS2=#l?^+o3E$+l@MGB=WK6KM*^RJ$8S_Y(=>50ZPD@R(FLP56zw zZ-hF4)<8E%%%mi^>7lqiAC?l+K`5}M3|ajH$Ws0#h<~kQR4YNjqK;3}bHWiI9dk#G zV>2aNbw(jiup?n!UE4-{CoqcZikT2Bnn*$>0vnr}X|EOXk6XQ1FwyMtTs-k~PzN!cw zY6CoHnya|C#3nUMGYsZJgD?RKYSu+_Nzxe1C-k|pDdCoK;7HmjwnC9Fj2QHViFzH8 zUf1V}??P7zryy3d$xv^QMNDhjp)151WRVMs;kM9nL?IGs4bA3UaWZOaaF`T0I;crS zvEpMtXd*`}P;4-(syKVx6>xGDa69>-M~Ut%hlu8;j6j8?q%u8L!dz@^U@)NjFZZ`X|`GSbVJedFB zVs*K&2_%fdomN8T(xF|52xDvzZQX`2E4Fvt5_&-NZfhpxTmr2)07^gv9P->yJwCui z!HnCt3-HdxEF7*-`o>!j*8ikgwvGii%EuyUZppyOTDM&%z3kly%vN+}$}QMQD%>WY zVb^cN-TynbDLVphcMU*h+*ufNgndCw8AvMwVgC3nh~Cue&knAI5rimBZ-cVO>=QqZ zcah&n5gXt|3zdA#Z>P=HG(P}sJ3x*e=Ev4XC}%JR0SYBXXWtG5E#eEgI)~IRmyFOL zmZoZi&#OgqPkPjuqvY69)j0f{jQ|XWpFk|Ca7?&l8yzLmauNvQJXRCZ{NmJ}8o7LI zbV`I7SVyu^U0_gm8x}4yME^ zHR@RO1u?L=&Zsc3Pl<=<1{ih@0F1zucD^tMuSJuJjHw+}L5-I%8C{QKYR6O_WnN&6 z+B51*&V`XJ9UIxP{y{)hQKLyVjxAGzFnt2F z>Kh|u=|uX1WB(dOUvS!aa)rxe{gia+z!d+kwkcBqnS})%E-Whgv0?AMHNay_0{c?S zx=L{q*+5#XFGyMek+Bs@z^u2lwK?Jot}w6JGl)-H8A^K#aK6$<-w;mEM!2dG7;WNK zoF&MkuZ-e-2BN%`>Dl5E<$J{xx~#%mruy~b+2ULH_h^I#N+KwAz?7$oK!}$Yt5cELyo_*Ej>fNjNQ`i&?3$eMbNc~Ue3{tv^qHt zpH`lPfBdE#{$B|`J@Kd+I2J?08w@)~XuW zgjj1aJ`(~xiH-*#)*m3i=Zn+98iJN5CfC0UrInXlAM+~Tc+la?nzWr#g&L2y-wZhH zyw9AeyluuAOX=_4&}$IcjL_YK?C&i;*V|rlgVuCgc2=LxqZ4E}ePqKCpFW&T3aV$0 zfM_#L3JKp;Tdk3^aWrc*#x`unH>+VE+TZoMPI&8a$CDf7S1& zDe)}Fzob!$sCM#z`ft(DKS<+~PI%`J^a*-Y?hg#2PxZhw2oyF1O&@KEEwjbZ-|>gf z^Z~ZP(Jq}>8W{R-`*dnQ4D#1`&SY37O$X-nAc!C5!(!((*Z9&7w4huL*6+4 zk%E6N#uBU)o)g}?Sc3gvH8+A!dWZKQY>s`>4s82k2R!EgpY4!rwu&~^TMwg`eWO; z>iDzcxM_Z@X~!ln|KQd`y0}$WRclqUHsksH93MH~nY*)NC$(2`jsO8IsnU+^Xj(x0 zg9Lx_4?|lKFl}RW5>gYOsp7^icI!B;b6XQwB|_4)Ra7bs%8-UGeBLD~(gc=u@B6;@ z-n;Mnz90AFec$K1`^otAiT_G55o`qx`@JrhW*zb^76TKzu3!nVWGxoQP)rz+p_0{8 zw6Jh}<(pH1!%GS;IJC4n^V0DO7P>>iC%_oRbocN`b!q(!E;WW~A8MZ&J3i$W><5Sf zXuuGnhUHjS=+iPZa~Uoat2-Z!D(#gH_Y&wE?D!%8f2U6#z|yh`GaSg_zV+fz7Tl2cTZqP?_LZ_0fVv|2tP+KDD&8B zJ%x<8-|<~Y~Cwgj!>$>pvi0GZtq+5xi&iNnEt65KWs{K&0Ta23pe&p8wPYccR9$CdSu;Lm#wrZma#5fYB(_X>Ru_4@?s zr2H+y3r@!0DI9Rp{-E%j6Y+mR=ypW^IU(c>2r>|!`-NwmsPL2%6Evq!P@JUjMbsq6 z?NQFHm;D3*hJ1Sm?hRY`=jvSG;Le{}V{g6p*30YXojup)PT;fDx*%WWy*~HBKG?eg z+Gdlt?@{1=CkR(*E+g;{K9ixWW9Tv1jf?KV5uP^iUN8?1ZU=bHvlx+lCcrb^z$?3! zEf}(5PTh&oz~{mT`Z6CM{C1Al#)~J-Gb`s#-0A)f;5b*TUH7g1_qb6me@I((mttSH zV0^m2Vois?1%2HPjZZ;;JwJCpr4EH%v)u5i1sptF1`q)Lv#y%pU0Lnm>pw ziX45s^J8w5f3t{d@M5u8a0@TeU6l|ljH}`MP|=FJ?tKWb3(Ho|Jqu0>T<9%m7O*w| zWh##2jh7?ZcHRlJ^mgrd5-`wKc-aEL_m3 z!D^&`^?y6usxF0=ZUj1UoDa0(I2G{WSXtbCXK@TF-w%W*AqYsy?YCaxXao=3TVt@5 zZ-?XY1w5Ixf6DOnfi+@P+sLKS2J2&nB9W#RQW|a0xX7v6XpJ(BG_?_Xv`(3ok?*qtaFKYXcQ=!`9G>LjMiPxn%9H$dGl|RLN&e(=u)RxT zyfXIaZ9=Z2K_U>1c+ak#Bcv6IUxUWm;Y5r7ctdy)wh@ScAJ947^Q}0;e=Y8jAKFgA zz8sbpFg)&(`e zsA?tM&?M!L>Qx%iRXJspjW~n4^>TDJr5I98QPKJ}viCPVlQNC4ng>o8blYoWljWu~ zZTKRrPpY@5X$DWD3tMn?kwsHlxjB|nL_<>Re&VLc>eAJl`am34_8S^YGHUNNVrnB{ zh*U2(rTSE3wk16v8I^r$Ns%R`{A!vQv!SRupcu2e$=l?Dhbkp+RQjMPp_Y7lyw^P2u^$R*v{kfR!0!m0^rusobgsOj?E9QuPS#%bfKqv+ zV!W}XfbR8oQ&f`+k%G*WKBE#UB-Od+3+O{4watQ_5~nYkNsX0$XQq<8Cp=StrvPR8 z4O3H7O6ixT8Z9lEG%}}~`j;9J95nkYrY_aLfnw)IOsa_nt)DjKx@EG=jdP}?*gr61 z8lC>3=~i>*$Au)-XhKAB_SiZNiN9ZvXQ$10b;i^O=#6<373?TTD%w3I+rKI>_3Aq~ z$n|0Yjogpu_y!@@FBPCJrbB%nx)ds87y4Niwa|4|`kR?x37V!-?Vp7N&A8MjsI_LF tAKujEuZL+g+QYxGhU%cegIs}#5m%9(VS?`Tc*Ord;y?HS-@X6< literal 0 HcmV?d00001 diff --git a/LadderTP/TP/TURBO.MSG b/LadderTP/TP/TURBO.MSG new file mode 100644 index 0000000..701b32b --- /dev/null +++ b/LadderTP/TP/TURBO.MSG @@ -0,0 +1,101 @@ + are not allowed + can not be + constant + does not + expression + identifier + file + here + Integer + File +Illegal + or +Undefined + match + real +String +Textfile + out of range + variable + overflow + expected + type +Invalid + pointer +01';' +02':' +03',' +04'(' +05')' +06'=' +07':=' +08'[' +09']' +10'.' +11'..' +12BEGIN +13DO +14END +15OF +17THEN +18TO DOWNTO +20Boolean +21  +22  +23  +24  +25  +26  +27  +28Pointer +29Record +30Simple +31Simple +32 +33 +34 +35 +36Type +37Untyped +40 label +41Unknown syntax error +42 in preceding definitions +43Duplicate label +44Type mismatch +45 +46 and CASE selector +47Operand(s) operator +48 result +49  length +50 length +51 subrange base +52Lower bound > upper bound +53Reserved word +54 assignment +55 exceeds line +56Error in integer +57Error in +58 character in +60s +61 s ands +62Structureds +63s +64s and untypeds +65Untypeds +66I/O +67 s must be parameters +68 componentss +69dering of fields +70Set base +71 GOTO +72Label not within current block +73 FORWARD procedure(s) +74INLINE error +75 use of ABSOLUTE +90 not found +91Unexpected end of source +97Too many nested WITH's +98Memory +99Compilerd WITH's +98Memory +99Compiler \ No newline at end of file diff --git a/LadderTP/TP/TURBO.OVR b/LadderTP/TP/TURBO.OVR new file mode 100644 index 0000000000000000000000000000000000000000..bd9292e22a743c7de744baf3dbafc40805996ecc GIT binary patch literal 1152 zcmc&y(MwZd6h9|*aHZY6(`eg+ec!Iwva-6!f*~S`6-bIw5@g0;Y9rckE>mZ*2cLS$ zZ9Z01^al(Hhc6)vVhb*~XcG01%T~x-W?|q%Tj$J9U6QZFI+lMxVDak&hJ==CEk{2#6uL{ zoK8t0;32T&Gotn1onj5?blkp1$twwx(o$2LXiZdrx`xHFMQ0G>EoI3TqcVjlt)$CW zdfU1gW9{9S_Exxyjg@*tBl(%v7hpraJ6?Aq>m5Ah@s1Aq1I+Ciy~R9U=JtEW2H907 zb9vqDrYFF9JLu1@y4_6w4X6oO+v#xDwn1x?*5SzJ>sDncoRxls_4cQUdUY!zTBtr{ zH7qinP33c#M#uIgOw(cW&lEa0!|_5}F5j>bF2u6Z#vcpuxt-@_Gf1Sy)Q=GW0czkV z)WdN&2^XOcu7eAPskZ@`fDlYmpJ(9}yn!^lgAcF*-(VdKC}0(uu@*aU7;obkwXGhX z!gF{5bMO-8p;RKmvjcLUoU0DbCFwnROP72;FXa6vM$KO{)Hnyo4p2v;c8i0_2DBEf zc0mnB?^es@=ARB2S3;21+_G8|$w)m>-Vazsldl^^GD@ypo74}yCyI>RDWG2Nh|c)V hfwXp}i;_jQSZ)4YbiFSImzJ46272f|Y}S3g|1a5Q0>}UW literal 0 HcmV?d00001 diff --git a/README.md b/README.md index a8a5256..10b76e8 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ See this repository: https://git.imzadi.de/acn/backgammon-vt100 * [2048](2048/) * [Ladder](Ladder/) +* [Ladder (Turbo Pascal version)](LadderTP/) * [Rogue](Rogue/) * [Wanderer](Wanderer/) * [CatChum](CatChum/) @@ -34,7 +35,6 @@ See this repository: https://git.imzadi.de/acn/backgammon-vt100 * [Gorilla.bas](https://github.com/sblendorio/gorilla-cpm): GORILLA.BAS port to CP/M in Turbo Modula-2. Supported terminals: VT52, VT100, ANSI, ADM-31, KayPro, C128, Memotech monochrome, CPC / Zenith Z19 * [Hangman](https://github.com/sblendorio/hangman-cpm): C implementation for CP/M of the classic "hangman" included in "bsdgames" popular package for UNIX -* [Ladder](https://github.com/mecparts/Ladder): Turbo Pascal reimplementation of Ladder (see above) ## HD image