Lode Runner Live game

git-svn-id: svn://kolibrios.org@670 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
bw 2007-11-01 12:36:59 +00:00
parent f259abc5ff
commit 4cc19614ca
12 changed files with 2860 additions and 0 deletions

83
programs/games/lrl/LRL.pp Normal file
View File

@ -0,0 +1,83 @@
program LodeRunnerLive;
{$apptype gui}
uses
LRLRoutines,
LRLSprites,
LRLLevels,
LRLMainMenu,
{LRLHighScores,
LRLEditor,}
LRLIntroduction;
const
Version: array [1..34] of char = 'Lode Runner LIVE. Version 1.0'#13#10#13#10'$';
procedure LRLInitialize;
begin
kos_setkeyboardmode(0);
ImagesInitialize;
end;
procedure LRLDeinitialize;
begin
ImagesDeinitialize;
end;
procedure LRLGameStart;
var
cl: Integer;
begin
Palette256Set(LRLPalette^);
ShowLives := True;
ShowScore := True;
ShowLevel := True;
LRLLives := 5;
LRLScore := 0;
cl := 1;
repeat
LRLPlayLevel(cl);
KeyboardFlush;
if GameResult = 10 then
begin
Inc(LRLLives);
LRLScore := LRLScore + 10000 * longint(cl);
Inc(cl);
end else
Dec(LRLLives);
until (LRLLives = 0) or (GameResult = 100);
{(GameResult <> 100) and LRLBestScore(LRLScore) then
begin
LRLInsertScore(LRLEnterName, LRLScore);
LRLShowHighScores;
end;}
end;
procedure LRLShell;
var
MenuSelection: word;
begin
MenuSelection := 1;
repeat
LRLSelectItem(MenuSelection);
if MenuSelection = 1 then LRLGameStart;
{if MenuSelection = 2 then LRLEditLevels;
if MenuSelection = 3 then LRLShowHighScores;}
until MenuSelection = 4;
end;
begin
LRLInitialize;
LRLIntro;
LRLShell;
LRLDeinitialize;
end.

View File

@ -0,0 +1,304 @@
unit LRLEditor;
interface
uses DOSFileAccess, LRLRoutines, LRLSprites, LRLLevels;
procedure LRLEditLevels;
implementation
var
CurrentLevel: word;
CurrentTool: word;
TotalLevels: word;
MouseX, MouseY: integer;
TimeToRefresh: boolean;
RefreshDelay: word;
RefreshRemain: word;
OldTimer: POINTER;
procedure LRLRedrawLevel;
var
i, j: integer;
begin
ImageClear(LRLScreen^);
for i := 1 to 16 do
for j := 1 to 30 do
with LRLLevel.Field[j, i] do
ImagePut(LRLScreen^, LRLEnvironment[Image].Image[Count].Data^, j * 10, i * 10, 0, 0, 319, 199);
for i := 1 to 10 do
with LRLLevel.Player[i] do
begin
if Controller <> 0 then
ImagePutTransparent(LRLScreen^, LRLFigure[Colour, SpriteData].Image[Sprite].Data^,
Position.x * 10 + Position.xoffs, Position.y * 10 + Position.yoffs, 0, 0, 319, 199);
end;
ImageFill(LRLFontBuffer^, 12, 12, 252);
ImagePut(LRLScreen^, LRLFontBuffer^, 10, 184, 0, 0, 319, 199);
for i := 1 to 13 do
begin
if i > 9 then
ImagePut(LRLScreen^, LRLFigure[i - 9, 1].Image[1].Data^, i * 15 - 4, 185, 0, 0, 319, 199)
else
ImagePut(LRLScreen^, LRLEnvironment[i].Image[1].Data^, i * 15 - 4, 185, 0, 0, 319, 199);
end;
for i := 1 to 6 do
begin
if LRLEditorButton[i].Lit then
ImagePut(LRLScreen^, LRLEditorButton[i].LightIcon^, LRLEditorButton[i].x1,
LRLEditorButton[i].y1, 0, 0, 319, 199)
else
ImagePut(LRLScreen^, LRLEditorButton[i].DarkIcon^, LRLEditorButton[i].x1,
LRLEditorButton[i].y1, 0, 0, 319, 199);
end;
LRLDrawOrnamental(0, 0, 31, 17, 1);
end;
procedure RefreshRunner;
{INTERRUPT;
ASSEMBLER;}
asm
DEC RefreshRemain
JNZ @DoTimer
MOV AX,RefreshDelay
MOV RefreshRemain,AX
MOV TimeToRefresh,-1
@DoTimer:
PUSHF
CALL OldTimer
end;
procedure LRLMoveMouse;
var
s, s2: string[20];
begin
MSMouseGetXY(Mousex, Mousey);
if not MSMouseInArea(200, 180, 325, 205) then
begin
if CurrentTool < 10 then
ImagePut(LRLScreen^, LRLEnvironment[CurrentTool].Image[1].Data^,
Mousex - 5, Mousey - 5, 0, 0, 319, 199)
else
ImagePut(LRLScreen^, LRLFigure[CurrentTool - 9, 1].Image[1].Data^,
Mousex - 5, Mousey - 5, 0, 0, 319, 199);
end;
if not MSMouseInArea(-2, -2, 55, 20) then
begin
ImageFill(LRLFontBuffer^, 50, 15, 0);
ImagePut(LRLScreen^, LRLFontBuffer^, 0, 0, 0, 0, 319, 199);
STR(CurrentLevel, s);
STR(TotalLevels, s2);
ImageStringGet(s + '/' + s2, LRLFont^, LRLFontBuffer^, 251);
ImagePut(LRLScreen^, LRLFontBuffer^, 25 - ImageSizex(LRLFontBuffer^) div 2, 0, 0, 0, 319, 199);
end;
ImagePutTransparent(LRLScreen^, LRLMousePointer^, Mousex, Mousey, 0, 0, 319, 199);
end;
procedure RePress;
var
x, y: integer;
begin
MSMouseButtonWasPressed(1, x, y);
MSMouseButtonWasReleased(1, x, y);
MSMouseButtonWasPressed(4, x, y);
MSMouseButtonWasReleased(4, x, y);
end;
procedure LRLEditLevels;
var
Keypress: word;
NeedToFade: boolean;
DrawNow: boolean;
i, j: integer;
x, y: integer;
Cmd: word;
begin
if not MSMouseDriverExist then Exit;
Repress;
ShowLives := False;
ShowScore := False;
Palette256Set(LRLPalette^);
OldTimer := SetInterrupt($8, @RefreshRunner);
Keypress := 0;
RefreshDelay := 1;
RefreshRemain := 1;
CurrentLevel := 1;
CurrentTool := 2;
TotalLevels := LRLLevelCount;
TimeToRefresh := True;
DrawNow := False;
MSMouseSetXY(160, 100);
LRLLoadLevel(CurrentLevel);
repeat
if TimeToRefresh then
begin
LRLRedrawLevel;
LRLMoveMouse;
ScreenApply(LRLScreen^);
TimeToRefresh := False;
end;
if Keypressed then
begin
Keypress := Readkey;
end;
if MSMouseButtonWasReleased(1, x, y) then
begin
LRLScore := 0;
FadeClear;
ImageClear(LRLScreen^);
ScreenApply(LRLScreen^);
Palette256Set(LRLPalette^);
LRLPlayLevel(CurrentLevel);
FadeClear;
ImageClear(LRLScreen^);
ScreenApply(LRLScreen^);
Palette256Set(LRLPalette^);
LRLLoadLevel(CurrentLevel);
Repress;
end;
if MSMouseButtonWasPressed(0, x, y) then
begin
DrawNow := True;
end;
if MSMouseButtonWasReleased(0, x, y) then
begin
DrawNow := False;
Cmd := 0;
for i := 1 to 6 do
LRLEditorButton[i].Lit := False;
for i := 1 to 6 do
begin
if MSMouseInArea(LRLEditorButton[i].x1, LRLEditorButton[i].y1,
LRLEditorButton[i].x2, LRLEditorButton[i].y2) then
begin
Cmd := LRLEditorButton[i].Command;
BREAK;
end;
end;
if (Cmd = 1) then
LRLSaveLevel(CurrentLevel);
Repress;
if (Cmd = 2) then
begin
LRLInsertLevel(CurrentLevel);
Inc(CurrentLevel);
TotalLevels := LRLLevelCount;
LRLLoadLevel(CurrentLevel);
Repress;
end;
if (Cmd = 3) and (CurrentLevel < TotalLevels) then
begin
Inc(CurrentLevel);
LRLLoadLevel(CurrentLevel);
Repress;
end;
if (Cmd = 4) then
begin
for i := 1 to 16 do
for j := 1 to 30 do
LRLLevel.Field[j, i].Image := 1;
for i := 1 to 10 do
LRLLevel.Player[i].Controller := 0;
Repress;
end;
if (Cmd = 5) and (TotalLevels > 1) then
begin
LRLDeleteLevel(CurrentLevel);
TotalLevels := LRLLevelCount;
if CurrentLevel > TotalLevels then
CurrentLevel := TotalLevels;
LRLLoadLevel(CurrentLevel);
Repress;
end;
if (Cmd = 6) and (CurrentLevel > 1) then
begin
Dec(CurrentLevel);
LRLLoadLevel(CurrentLevel);
Repress;
end;
MSMouseGetXY(Mousex, Mousey);
if (Mousey > 180) then
begin
for i := 1 to 13 do
begin
if (Mousey > 184) and (Mousey < 195) and (Mousex > i * 15 - 5) and (Mousex < i * 15 + 6) then
begin
CurrentTool := i;
BREAK;
end;
end;
end;
end;
if DrawNow then
begin
for i := 1 to 6 do
LRLEditorButton[i].Lit := False;
for i := 1 to 6 do
begin
if MSMouseInArea(LRLEditorButton[i].x1, LRLEditorButton[i].y1,
LRLEditorButton[i].x2, LRLEditorButton[i].y2) then
begin
LRLEditorButton[i].Lit := True;
BREAK;
end;
end;
MSMouseGetXY(Mousex, Mousey);
x := (Mousex) div 10;
y := (Mousey) div 10;
if (x > 0) and (x < 31) and (y > 0) and (y < 17) then
begin
for i := 1 to 10 do
begin
if (LRLLevel.Player[i].Controller <> 0) and (LRLLevel.Player[i].Position.x = x) and
(LRLLevel.Player[i].Position.y = y) then
begin
if (CurrentTool <> 2) and (CurrentTool <> 3) and (CurrentTool <> 4) and
(CurrentTool <> 7) then
begin
LRLLevel.Player[i].Controller := 0;
BREAK;
end;
end;
end;
if CurrentTool < 10 then
LRLLevel.Field[x, y].Image := CurrentTool
else
begin
if (LRLLevel.Field[x, y].Image = 2) or (LRLLevel.Field[x, y].Image = 3) or
(LRLLevel.Field[x, y].Image = 4) or (LRLLevel.Field[x, y].Image = 1) then
begin
if CurrentTool = 10 then
begin
LRLLevel.Player[1].Controller := 1;
LRLLevel.Player[1].Position.x := x;
LRLLevel.Player[1].Position.y := y;
LRLLevel.Player[1].Colour := 1;
end
else
begin
j := 2;
for i := 2 to 10 do
begin
if LRLLevel.Player[i].Controller = 0 then
begin
j := i;
BREAK;
end;
end;
LRLLevel.Player[j].Controller := 2;
LRLLevel.Player[j].Position.x := x;
LRLLevel.Player[j].Position.y := y;
LRLLevel.Player[j].Colour := CurrentTool - 9;
end;
end;
end;
end;
end;
until (LO(Keypress) = 27);
SetInterrupt($8, OldTimer);
end;
end.

View File

@ -0,0 +1,234 @@
unit LRLHighScores;
interface
uses
LRLRoutines, LRLSprites, StrUnit;
procedure LRLLoadHighScores;
procedure LRLShowHighScores;
function LRLBestScore(Score: longint): boolean;
procedure LRLInsertScore(Name: string; Score: longint);
procedure LRLSaveHighScores;
function LRLEnterName: string;
implementation
const
HighsFileName = 'LRL.HSR';
HighsFileHeader: string[29] = 'Lode Runner Live High Scores'#26;
type
TSupers = packed record
Name: string[20];
Score: longint;
end;
var
MainScreen: POINTER;
HighFrame: POINTER;
HighTable: array[1..5] of TSupers;
procedure LoadData;
var
j: word;
begin
GETMEM(MainScreen, 64004);
GETMEM(HighFrame, 45000);
DFAFilePositionSet(ImageFile, LRLImagesFilePosition, DFASeekFromStart);
DFAFileRead(ImageFile, MainScreen^, 7940, j);
DecompressRepByte(MainScreen^, HighFrame^, 7940, j);
DFAFileRead(ImageFile, MainScreen^, 64004, j);
end;
procedure DisposeData;
begin
FREEMEM(MainScreen, 64004);
FREEMEM(HighFrame, 45000);
end;
procedure LRLShowHighScores;
var
p: POINTER;
i: integer;
s: string;
begin
LRLLoadHighScores;
GETMEM(p, 768);
DataFill(p^, 768, 0, 0);
Palette256Set(p^);
FREEMEM(p, 768);
LoadData;
ImagePut(LRLScreen^, MainScreen^, 0, 0, 0, 0, 319, 199);
ImagePut(LRLScreen^, HighFrame^, 6, 50, 0, 0, 319, 199);
for i := 1 to 5 do
begin
ImageStringGet(CHR(i + 48) + '. ' + HighTable[i].Name, LRLFont^, LRLFontBuffer^, 110);
ImagePut(LRLScreen^, LRLFontBuffer^, 55, 85 + i * 17, 8, 0, 319, 199);
STR(HighTable[i].Score, s);
ImageStringGet(s, LRLFont^, LRLFontBuffer^, 46);
ImagePut(LRLScreen^, LRLFontBuffer^, 260 - ImageSizex(LRLFontBuffer^), 85 + i * 17, 8, 0, 319, 199);
end;
ScreenApply(LRLScreen^);
FadeTo(LRLMenuPalette);
READKEY;
FadeClear;
ImageClear(LRLScreen^);
ScreenApply(LRLScreen^);
DisposeData;
end;
procedure LRLLoadHighScores;
var
InFile: TDFAFileHandle;
i, j: word;
high: TSupers;
dummy: string[30];
begin
high.Name := 'Lode Runner';
DFAFileOpen(InFile, HighsFileName, DFAAccessReadWrite);
if DFALastResult(InFile) <> 0 then
begin
DFAFileCreate(InFile, HighsFileName, DFAAttributeArchive);
DFAFileWrite(InFile, HighsFileHeader[1], 29, i);
for i := 1 to 5 do
begin
high.score := 60000 - i * 10000;
DFAFileWrite(InFile, high, SIZEOF(high), j);
end;
end;
DFAFilePositionSet(InFile, 0, DFASeekFromStart);
DFAFileRead(InFile, dummy[1], 29, j);
if (DFALastResult(InFile) <> 0) or
(not DataIdentical(dummy[1], HighsFileHeader[1], 29, 0, 0)) then
begin
WRITELN('Error: Invalid file with high scores! (try to remove LRL.HSR file)');
WRITELN('Žè¨¡ª : <20>¥¢¥à­ë© ä ©« á ४®à¤ ¬¨! (¯®¯à®¡ã©â¥ 㤠«¨âì ä ©« LRL.HSR)');
Halt(1);
end;
DFAFileRead(InFile, HighTable, SIZEOF(TSupers) * 5, j);
DFAFileClose(InFile);
end;
procedure LRLSaveHighScores;
var
InFile: TDFAFileHandle;
i, j: word;
begin
DFAFileOpen(InFile, HighsFileName, DFAAccessReadWrite);
DFAFilePositionSet(InFile, 29, DFASeekFromStart);
DFAFileWrite(InFile, HighTable, SIZEOF(TSupers) * 5, j);
DFAFileClose(InFile);
end;
function LRLBestScore(Score: longint): boolean;
var
i: integer;
begin
LRLBestScore := True;
LRLLoadHighScores;
i := 1;
while True do
begin
if Score >= HighTable[i].Score then
EXIT;
Inc(i);
if i > 5 then
begin
LRLBestScore := False;
EXIT;
end;
end;
end;
procedure LRLInsertScore(Name: string; Score: longint);
var
i, j: word;
begin
LRLLoadHighScores;
i := 1;
while True do
begin
if Score >= HighTable[i].Score then
begin
for j := 4 downto i do
begin
HighTable[j + 1].Name := HighTable[j].Name;
HighTable[j + 1].Score := HighTable[j].Score;
end;
HighTable[i].Name := Name;
HighTable[i].Score := Score;
LRLSaveHighScores;
EXIT;
end;
Inc(i);
if i > 5 then
begin
EXIT;
end;
end;
end;
function LRLEnterName: string;
var
p: POINTER;
i: integer;
RedrawName: boolean;
Keypress: word;
Name: string;
begin
Name := '';
GETMEM(p, 768);
DataFill(p^, 768, 0, 0);
Palette256Set(p^);
FREEMEM(p, 768);
ImageClear(LRLScreen^);
ImagePut(LRLScreen^, LRLLogo^, 3, 3, 0, 0, 319, 199);
ImageStringGet('Congratulations! You are in Top-Five!', LRLFont^, LRLFontBuffer^, 110);
ImagePut(LRLScreen^, LRLFontBuffer^, 160 - ImageSizex(LRLFontBuffer^) shr 1, 85, 0, 0, 319, 199);
ImageStringGet('Enter your name below, Champ', LRLFont^, LRLFontBuffer^, 111);
ImagePut(LRLScreen^, LRLFontBuffer^, 160 - ImageSizex(LRLFontBuffer^) shr
1, 110, 0, 0, 319, 199);
ImageStringGet('---------------------------', LRLFont^, LRLFontBuffer^, 100);
ImagePut(LRLScreen^, LRLFontBuffer^, 160 - ImageSizex(LRLFontBuffer^) shr
1, 155, 0, 0, 319, 199);
ScreenApply(LRLScreen^);
FadeTo(LRLMenuPalette);
RedrawName := True;
repeat
if RedrawName = True then
begin
ImageFill(LRLFontBuffer^, 320, 20, 0);
ImagePut(LRLScreen^, LRLFontBuffer^, 0, 140, 0, 0, 319, 199);
ImageStringGet(Name, LRLFont^, LRLFontBuffer^, 100);
ImagePut(LRLScreen^, LRLFontBuffer^, 160 - ImageSizex(LRLFontBuffer^) shr
1, 140, 0, 0, 319, 199);
ScreenApply(LRLScreen^);
RedrawName := False;
end;
Keypress := READKEY;
if (LO(Keypress) = 8) and (LENGTH(Name) > 0) then
begin
Name[0] := char(Ord(Name[0]) - 1);
RedrawName := True;
end;
if (LO(Keypress) > 31) and (LENGTH(Name) < 20) then
begin
Name := Name + char(LO(Keypress));
RedrawName := True;
end;
until LO(Keypress) = 13;
FadeClear;
Name := StringTrimAll(Name, ' ');
if LENGTH(Name) = 0 then
Name := 'Anonymous';
LRLEnterName := Name;
end;
end.

View File

@ -0,0 +1,135 @@
unit LRLIntroduction;
interface
uses
SysUtils,
LRLRoutines, LRLSprites;
procedure LRLIntro;
implementation
const
IntroText: array[1..14] of String = (
'Lode Runner LIVE. FREEWARE Version 1.0',
'KolibriOS port by bw (Vladimir V. Byrgazov)',
'Copyright (c) 1995 Aleksey V. Vaneev',
'Copyright (c) 2007 bw',
'',
'Send comments to Aleksey V. Vaneev',
'2:5003/15@FidoNet',
'ikomi@glas.apc.org',
'',
'Send comments to bw',
'bw@handsdriver.net',
'',
'',
''
);
SPACE40 = ' ';
var
RefreshDelay: Word;
RefreshRemain: Word;
TimeToRefresh: Boolean;
OldTimer: Pointer;
procedure LRLIntro;
var
i, j, l: Integer;
Count: Word;
k: Word;
MainScreen: Pointer;
begin
RefreshDelay := 1;
RefreshRemain := 1;
GetMem(MainScreen, 64004);
Seek(ImageFile, LRLImagesFilePosition + 7940);
BlockRead(ImageFile, MainScreen^, 64004, k);
Palette256Set(LRLMenuPalette^);
ImageFill(LRLFontBuffer^, 320, 55, 0);
ImageClear(LRLScreen^);
for i := -50 to 4 do
begin
ImagePut(LRLScreen^, LRLFontBuffer^, 0, 0, 0, 0, 319, 199);
ImagePut(LRLScreen^, LRLLogo^, 3, i, 0, 0, 319, 199);
ScreenApply(LRLScreen^);
if Keypressed then
begin
ReadKey;
FreeMem(MainScreen, 64004);
Exit;
end;
Sleep(10);
end;
ImageFill(LRLFontBuffer^, 320, 55, 0);
for i := 0 to 10 do
begin
for k := 0 to 20 do
for j := 0 to 16 do
ImagePutTransparent(LRLScreen^, MainScreen^, 0, 0,
j * 20 - 10 - i, k * 20 - 10 - i,
j * 20 - 10 + i, k * 20 - 10 + i);
Sleep(50);
ImagePut(LRLScreen^, LRLFontBuffer^, 0, 182, 0, 0, 319, 199);
ScreenApply(LRLScreen^);
if Keypressed then
begin
ReadKey;
FreeMem(MainScreen, 64004);
Exit;
end;
end;
Count := 1;
k := 1;
repeat
if TimeToRefresh then
begin
Inc(Count);
TimeToRefresh := False;
end;
if Count >= 2 then
begin
ImageStringGet(SPACE40 + IntroText[k] + SPACE40, LRLFont^, LRLFontBuffer^, 110);
for l := 200 downto 184 do
begin
ImagePut(LRLScreen^, LRLFontBuffer^, 160 - ImageSizeX(LRLFontBuffer^) div 2, l, 0, 0, 319, 199);
ScreenApply(LRLScreen^);
Sleep(20);
end;
Inc(k);
if k > Length(IntroText) then k := 1;
Count := 0;
end;
for I := 1 to 8 do
if Keypressed then
Break else
Sleep(250);
TimeToRefresh := True;
until KeyPressed;
ReadKey;
FadeClear;
FreeMem(MainScreen, 64004);
end;
end.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,116 @@
unit LRLMainMenu;
interface
uses
LRLRoutines, LRLSprites;
procedure LRLSelectItem(var Item: Word);
implementation
var
MainScreen: Pointer;
Selection: array[1..4] of Pointer;
SelectionDark: array[1..4] of Pointer;
SelectionSize: array[1..4] of Word;
SelectionDarkSize: array[1..4] of Word;
procedure LoadData;
var
size, j: Word;
i: Integer;
begin
GetMem(MainScreen, 64004);
Seek(ImageFile, LRLImagesFilePosition + 7940);
BlockRead(ImageFile, MainScreen^, 64004, j);
for i := 1 to 4 do
begin
BlockRead(ImageFile, SelectionSize[i], 2, j);
GetMem(Selection[i], SelectionSize[i]);
BlockRead(ImageFile, Selection[i]^, SelectionSize[i], j);
BlockRead(ImageFile, SelectionDarkSize[i], 2, j);
GetMem(SelectionDark[i], SelectionDarkSize[i]);
BlockRead(ImageFile, SelectionDark[i]^, SelectionDarkSize[i], j);
end;
end;
procedure DisposeData;
var
i: Integer;
begin
FreeMem(MainScreen, 64004);
for i := 1 to 4 do
begin
FreeMem(Selection[i], SelectionSize[i]);
FreeMem(SelectionDark[i], SelectionDarkSize[i]);
end;
end;
procedure LRLSelectItem(var Item: Word);
var
Keypress: Word;
RedrawAll: Boolean;
NeedToFade: Boolean;
p: Pointer;
i: Integer;
begin
GetMem(p, 768);
DataFill(p^, 768, 0, 0);
Palette256Set(p^);
FreeMem(p, 768);
LoadData;
NeedToFade := True;
ImagePut(LRLScreen^, MainScreen^, 0, 0, 0, 0, 319, 199);
RedrawAll := True;
KeyboardFlush;
repeat
if RedrawAll then
begin
for i := 1 to 4 do
if i = Item then
ImagePutTransparent(LRLScreen^, Selection[i]^, 63, 66 + (i - 1) * 30, 0, 0, 319, 199) else
ImagePutTransparent(LRLScreen^, SelectionDark[i]^, 63, 66 + (i - 1) * 30, 0, 0, 319, 199);
ScreenApply(LRLScreen^);
if NeedToFade then
begin
FadeTo(LRLMenuPalette);
NeedToFade := False;
end;
RedrawAll := False;
end;
Keypress := ReadKey;
if (Keypress = $B1) and (Item < 4) then
begin
Inc(Item);
RedrawAll := True;
end;
if (Keypress = $B2) and (Item > 1) then
begin
Dec(Item);
RedrawAll := True;
end;
until Keypress = $0D;
FadeClear;
ImageClear(LRLScreen^);
ScreenApply(LRLScreen^);
DisposeData;
end;
end.

View File

@ -0,0 +1,499 @@
unit LRLRoutines;
{$mode objfpc}
{$asmmode intel}
interface
procedure ImagePut(var Screen, ImageBuffer; X, Y: Integer; Winx1, Winy1, Winx2, Winy2: Word);
procedure ImagePutTransparent(var Screen, ImageBuffer; X, Y: Integer; Winx1, Winy1, Winx2, Winy2: Word);
procedure ImageFill(var ImageBuffer; SizeX, SizeY: Word; Value: Byte);
function ImageSizeX(var ImageBuffer): Word;
function ImageSizeY(var ImageBuffer): Word;
procedure ImageStringGet(Source: String; var FontData, Buffer; ColorOffs: Byte);
procedure ScreenApply(var Buffer);
procedure ImageClear(var Buffer);
procedure Palette256Set(var Palette256);
procedure Palette256Get(var Palette256);
procedure Palette256Grayscale(var Palette256; StartElement, EndElement: Byte);
procedure Palette256Darken(var Palette256; StartElement, EndElement, Decrement, MinValue: Byte);
procedure Palette256Transform(var SourcePalette, DestinationPalette);
function DataByteGet(var Buffer; BufferOffset: Word): Byte;
procedure DataBytePut(var Buffer; BufferOffset: Word; Value: Byte);
function DataWordGet(var Buffer; BufferOffset: Word): Word;
procedure DataWordPut(var Buffer; BufferOffset: Word; Value: Word);
procedure DataMove(var Source, Destination; Count: Word; SourceOffset, DestinationOffset: Word);
procedure DataAdd(var Buffer; Count: Word; Amount: Byte; BufferOffset: Word);
procedure DataFill(var Buffer; Count: Word; Value: Byte; BufferOffset: Word);
function DataIdentical(var Array1, Array2; Count: Word; Array1Offset, Array2Offset: Word): Boolean;
function ReadKey: Word;
function Keypressed: Boolean;
function SetInterrupt(Int: Byte; NewAddress: Pointer): Pointer;
procedure FadeClear;
procedure FadeTo(pal: Pointer);
procedure DecompressRepByte(var InArray, OutArray; InArraySize: Word; var OutArraySize: Word);
function MSMouseInArea(x1, y1, x2, y2: Integer): Boolean;
function MSMouseDriverExist: Boolean;
procedure MSMouseGetXY(var x, y: Integer);
function MSMouseButtonStatusGet: Word;
function MSMouseButtonWasPressed(Button: Word; var x, y: Integer): Boolean;
function MSMouseButtonWasReleased(Button: Word; var x, y: Integer): Boolean;
procedure MSMouseSetXY(x, y: Integer);
procedure KeyboardFlush;
function GetInterrupt(Int: Byte): Pointer;
procedure AssignFile(var AFile: File; AFileName: String);
function LastDosTick(): Longword;
implementation
uses
SysUtils;
const
SCREEN_WIDTH = 320;
SCREEN_HEIGHT = 200;
type
PRGBColor = ^TRGBColor;
TRGBColor = packed record
R, G, B: Byte;
end;
PRGBPalette = ^TRGBPalette;
TRGBPalette = array[Byte] of TRGBColor;
var
ScreenRGBPalette: TRGBPalette;
ScreenRGBBuffer : array[0..SCREEN_HEIGHT - 1, 0..SCREEN_WIDTH - 1] of TRGBColor;
ScreenBuffer : array[0..SCREEN_WIDTH * SCREEN_HEIGHT - 1] of Byte;
AlreadyKeyPressed: Boolean = False;
procedure Paint;
begin
kos_begindraw();
kos_definewindow(500, 100, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1, $01000000);
kos_drawimage24(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, @ScreenRGBBuffer);
kos_enddraw();
end;
procedure UpdateRGBBuffer;
var
I, J: Longint;
B: PByte;
begin
B := @ScreenBuffer;
for I := 0 to SCREEN_HEIGHT - 1 do
for J := 0 to SCREEN_WIDTH - 1 do
begin
ScreenRGBBuffer[I, J] := ScreenRGBPalette[B^];
Inc(B);
end;
Paint;
end;
procedure ImagePut(var Screen, ImageBuffer; X, Y: Integer; WinX1, WinY1, WinX2, WinY2: Word);
var
Width, Height: Word;
I, J, K: Integer;
P: Pointer;
begin
Width := PWord(@ImageBuffer)[0];
Height := PWord(@ImageBuffer)[1];
P := @ImageBuffer + 4;
for I := Y to Y + Height - 1 do
begin
if (I >= 0) and (I < SCREEN_HEIGHT) and (I >= WinY1) and (I <= WinY2) then
begin
if X < WinX1 then
J := WinX1 - X else
J := 0;
K := Width - J;
if WinX1 + K - 1 > WinX2 then
K := WinX2 - WinX1 + 1;
Move((P + J)^, (@Screen + I * SCREEN_WIDTH + X + J)^, K);
end;
Inc(P, Width);
end;
end;
procedure ImagePutTransparent(var Screen, ImageBuffer; X, Y: Integer; Winx1, Winy1, Winx2, Winy2: Word);
begin
ImagePut(Screen, ImageBuffer, X, Y, Winx1, Winy1, Winx2, Winy2);
end;
procedure ImageFill(var ImageBuffer; SizeX, SizeY: Word; Value: Byte);
begin
PWord(@ImageBuffer)^ := SizeX;
PWord(@ImageBuffer + 2)^ := SizeY;
FillChar((@ImageBuffer + 4)^, SizeX * SizeY, Value);
end;
function ImageSizeX(var ImageBuffer): Word;
begin
Result := PWord(@ImageBuffer)^;
end;
function ImageSizeY(var ImageBuffer): Word;
begin
Result := PWord(@ImageBuffer + 2)^;
end;
procedure ImageStringGet(Source: String; var FontData, Buffer; ColorOffs: Byte);
var
Width, Height: Word;
Table: PWord;
P, B: PByte;
X, I, J, K, C: Word;
begin
Height := PWord(@FontData + 2)^;
Table := PWord(@FontData + 4);
{ à áç¥â ¤«¨­ë áâப¨ }
Width := 0;
for I := 1 to Length(Source) do
begin
P := @Table[Ord(Source[I])];
Inc(Width, PWord(P + PWord(P)^)^);
end;
PWord(@Buffer)^ := Width;
PWord(@Buffer + 2)^ := Height;
{ ¢ë¢®¤ áâப¨ }
X := 0;
for I := 1 to Length(Source) do
begin
P := @Table[Ord(Source[I])];
B := PByte(P + PWord(P)^);
C := PWord(B)^;
Inc(B, 2);
P := PByte(@Buffer + 4 + X);
for K := 0 to Height - 1 do
begin
for J := 0 to C - 1 do
begin
if B^ = 0 then
P^ := 0 else
P^ := B^ + ColorOffs;
Inc(P);
Inc(B);
end;
Inc(P, Width - C);
end;
Inc(X, C);
end;
end;
procedure ScreenApply(var Buffer);
begin
Move(Buffer, ScreenBuffer, SizeOf(ScreenBuffer));
UpdateRGBBuffer;
end;
procedure ImageClear(var Buffer);
begin
FillChar(Buffer, SCREEN_WIDTH * SCREEN_HEIGHT, 0);
end;
procedure Palette256Set(var Palette256);
var
I: Longint;
P: PRGBColor;
begin
P := @Palette256;
for I := 0 to 255 do
with ScreenRGBPalette[I] do
begin
R := Round(P^.B / 63 * 255);
G := Round(P^.G / 63 * 255);
B := Round(P^.R / 63 * 255);
Inc(P);
end;
UpdateRGBBuffer;
end;
procedure Palette256Get(var Palette256);
var
I: Longint;
P: PRGBColor;
begin
P := @Palette256;
for I := 0 to 255 do
with ScreenRGBPalette[I] do
begin
P^.R := Round(B / 255 * 63);
P^.G := Round(G / 255 * 63);
P^.B := Round(R / 255 * 63);
Inc(P);
end;
end;
procedure Palette256Grayscale(var Palette256; StartElement, EndElement: Byte);
begin
end;
procedure Palette256Darken(var Palette256; StartElement, EndElement, Decrement, MinValue: Byte);
begin
end;
procedure Palette256Transform(var SourcePalette, DestinationPalette);
var
I: Longint;
S, D: PByte;
begin
S := @SourcePalette;
D := @DestinationPalette;
for I := 0 to 767 do
begin
if S^ < D^ then Inc(S^) else
if S^ > D^ then Dec(S^);
Inc(S);
Inc(D);
end;
end;
function DataByteGet(var Buffer; BufferOffset: Word): Byte;
begin
Result := PByte(@Buffer + BufferOffset)^;
end;
procedure DataBytePut(var Buffer; BufferOffset: Word; Value: Byte);
begin
PByte(@Buffer + BufferOffset)^ := Value;
end;
function DataWordGet(var Buffer; BufferOffset: Word): Word;
begin
Result := PWord(@Buffer + BufferOffset)^;
end;
procedure DataWordPut(var Buffer; BufferOffset: Word; Value: Word);
begin
PWord(@Buffer + BufferOffset)^ := Value;
end;
procedure DataMove(var Source, Destination; Count: Word; SourceOffset, DestinationOffset: Word);
begin
Move((@Source + SourceOffset)^, (@Destination + DestinationOffset)^, Count);
end;
procedure DataFill(var Buffer; Count: Word; Value: Byte; BufferOffset: Word);
begin
FillChar((@Buffer + BufferOffset)^, Count, Value);
end;
function DataIdentical(var Array1, Array2; Count: Word; Array1Offset, Array2Offset: Word): Boolean;
begin
Result := CompareByte((@Array1 + Array1Offset)^, (@Array2 + Array2Offset)^, Count) = 0;
end;
procedure DataAdd(var Buffer; Count: Word; Amount: Byte; BufferOffset: Word);
var
I: Word;
begin
for I := 0 to Count do
Inc(PByte(@Buffer + BufferOffset + I)^, Amount);
{if >0 then += amount}
end;
function ReadKey: Word;
var
Event: Word;
begin
if not AlreadyKeyPressed then
begin
kos_maskevents(ME_PAINT or ME_KEYBOARD);
repeat
Event := kos_getevent();
if Event = SE_PAINT then Paint;
until Event = SE_KEYBOARD;
end;
Result := kos_getkey() shr 8;
AlreadyKeyPressed := False;
{WriteLn('ReadKey -> ', IntToHex(Result, 2));}
end;
function Keypressed: Boolean;
begin
if AlreadyKeyPressed then
Result := True else
begin
kos_maskevents(ME_KEYBOARD);
Result := kos_getevent(False) = SE_KEYBOARD;
AlreadyKeyPressed := Result;
end;
end;
procedure KeyboardFlush;
var
Event: Word;
begin
kos_maskevents(ME_KEYBOARD);
repeat
Event := kos_getevent(False);
if Event = SE_KEYBOARD then kos_getkey();
until Event = 0;
AlreadyKeyPressed := False;
end;
function SetInterrupt(Int: Byte; NewAddress: Pointer): Pointer;
begin
Result := nil;
end;
procedure FadeClear;
var
Pal1, Pal2: Pointer;
i: Integer;
begin
GetMem(Pal1, 768);
GetMem(Pal2, 768);
Palette256Get(Pal1^);
for i := 0 to 32 do
begin
DataMove(Pal1^, Pal2^, 768, 0, 0);
Palette256Darken(Pal2^, 0, 255, i * 2, 0);
Palette256Set(Pal2^);
end;
FreeMem(Pal1, 768);
FreeMem(Pal2, 768);
end;
procedure FadeTo(Pal: Pointer);
var
Pal1: Pointer;
I: Integer;
begin
GetMem(Pal1, 768);
Palette256Get(Pal1^);
for I := 0 to 63 do
begin
Palette256Transform(Pal1^, Pal^);
Palette256Set(Pal1^);
kos_delay(1);
end;
FreeMem(Pal1, 768);
end;
procedure DecompressRepByte(var InArray, OutArray; InArraySize: Word; var OutArraySize: Word);
begin
{asm
PUSH DS
xor DX,DX
xor AX,AX
LDS SI,InArray
LES DI,OutArray
MOV CX,InArraySize
JCXZ @Done
@Loop1:
LODSB
CMP AL,0
JE @VsePonyatno
CMP AL,4
JB @MensheTreh
INC DX
STOSB
JMP @DoLoop
@MensheTreh:
SUB CX,1
MOV BX,CX
MOV CX,AX
ADD DX,AX
LODSB
REP STOSB
MOV CX,BX
JMP @DoLoop
@VsePonyatno:
LODSB
SUB CX,2
MOV BX,CX
MOV CX,AX
ADD DX,AX
LODSB
REP STOSB
MOV CX,BX
@DoLoop:
JCXZ @Done
LOOP @Loop1
@Done:
LES DI,OutArraySize
MOV[ES:DI],DX
POP DS}
end;
function MSMouseInArea(x1, y1, x2, y2: Integer): Boolean;
begin
Result := False;
end;
function MSMouseDriverExist: Boolean;
begin
Result := True;
end;
procedure MSMouseGetXY(var x, y: Integer);
begin
end;
function MSMouseButtonStatusGet: Word;
begin
Result := 0;
end;
function MSMouseButtonWasPressed(Button: Word; var x, y: Integer): Boolean;
begin
Result := False;
end;
function MSMouseButtonWasReleased(Button: Word; var x, y: Integer): Boolean;
begin
Result := False;
end;
procedure MSMouseSetXY(x, y: Integer);
begin
end;
function GetInterrupt(Int: Byte): Pointer;
begin
Result := nil;
end;
procedure AssignFile(var AFile: File; AFileName: String);
begin
Assign(AFile, IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0))) + AFileName);
end;
function LastDosTick(): Longword;
begin
Result := Round(kos_timecounter() * 0.182);
end;
end.

View File

@ -0,0 +1,255 @@
unit LRLSprites;
{$mode objfpc}
{$i-}
interface
uses
SysUtils,
LRLRoutines;
{
all coordinates in standard style:
0 +
0 +----------> x
|
|
|
|
+ v
y
}
type
TLRLImage = packed record
Data: Pointer; { standard 256-colour image data }
Size: Word; { size of image (for destruction) }
end;
PLRLSprite = ^TLRLSprite;
TLRLSprite = packed record
Image: array[1..12] of TLRLImage; { moving image }
ImageCount: Byte; { how many images there }
end;
type
TButton = packed record
Lit: Boolean;
DarkIcon: Pointer;
LightIcon: Pointer;
DarkIconSize: Word;
LightIconSize: Word;
x1, y1: Integer;
x2, y2: Integer;
Command: Word;
end;
var
ImageFile: File;
LRLEnvironment: array[1..20] of TLRLSprite;
LRLFigure: array[1..4, 1..9] of TLRLSprite;
LRLDecoration: array[1..1] of TLRLSprite;
LRLPalette: Pointer;
LRLScreen: Pointer;
LRLMenuPalette: Pointer;
LRLLogo: Pointer;
LRLFont: Pointer;
LRLFontBuffer: Pointer;
LRLMousePointer: Pointer;
LRLImagesFilePosition: longint;
LRLEditorButton: array[1..6] of TButton;
procedure ImagesInitialize;
procedure ImagesDeinitialize;
implementation
const
ImageFileName = 'LRL.IMG';
ImageFileHeader: ShortString = 'Lode Runner Live Images'#26;
ERR_OPENFILE = '<27>¥¢®§¬®¦­® ®âªàëâì ä ©« ª à⨭®ª';
ERR_BADFILE = '<27>¥¢¥à­ë© ¨«¨ ¯®¢à¥¦¤¥­­ë© ä ©« ª à⨭®ª';
procedure LoadImages;
var
InBuffer: Pointer;
i, j, k, l, x, y: Word;
a, b, c: Byte;
begin
GetMem(InBuffer, $FFF0);
AssignFile(ImageFile, ImageFileName);
Reset(ImageFile, 1);
if IOResult <> 0 then
raise Exception.Create(ERR_OPENFILE);
BlockRead(ImageFile, InBuffer^, 24, k);
if (IOResult <> 0) or not DataIdentical(InBuffer^, ImageFileHeader[1], 24, 0, 0) then
raise Exception.Create(ERR_BADFILE);
{ load palette }
GetMem(LRLPalette, 768);
BlockRead(ImageFile, LRLPalette^, 768, k);
{ figures loading loop }
for i := 1 to 9 do
begin
BlockRead(ImageFile, a, 1, k);
LRLFigure[1, i].ImageCount := a;
for j := 1 to a do
begin
GetMem(LRLFigure[1, i].Image[j].Data, 104);
BlockRead(ImageFile, LRLFigure[1, i].Image[j].Data^, 104, k);
x := DataWordGet(LRLFigure[1, i].Image[j].Data^, 0);
y := DataWordGet(LRLFigure[1, i].Image[j].Data^, 2);
LRLFigure[1, i].Image[j].Size := x * y + 4;
for l := 2 to 4 do
begin
LRLFigure[l, i].Image[j].Size := LRLFigure[1, i].Image[j].Size;
LRLFigure[l, i].ImageCount := a;
GetMem(LRLFigure[l, i].Image[j].Data, LRLFigure[l, i].Image[j].Size);
DataMove(LRLFigure[1, i].Image[j].Data^, LRLFigure[l, i].Image[j].Data^, LRLFigure[l, i].Image[j].Size, 0, 0);
DataAdd(LRLFigure[l, i].Image[j].Data^, LRLFigure[l, i].Image[j].Size, (l - 1) shl 5, 4);
end;
end;
end;
{ decoration loading loop }
for i := 1 to 1 do
begin
BlockRead(ImageFile, a, 1, k);
LRLDecoration[i].ImageCount := a;
for j := 1 to a do
begin
GetMem(LRLDecoration[i].Image[j].Data, 104);
BlockRead(ImageFile, LRLDecoration[i].Image[j].Data^, 104, k);
x := DataWordGet(LRLDecoration[i].Image[j].Data^, 0);
y := DataWordGet(LRLDecoration[i].Image[j].Data^, 2);
LRLDecoration[i].Image[j].Size := x * y + 4;
end;
end;
{ environment loading loop }
for i := 1 to 9 do
begin
BlockRead(ImageFile, a, 1, k);
LRLEnvironment[i].ImageCount := a;
for j := 1 to a do
begin
GetMem(LRLEnvironment[i].Image[j].Data, 104);
BlockRead(ImageFile, LRLEnvironment[i].Image[j].Data^, 104, k);
x := DataWordGet(LRLEnvironment[i].Image[j].Data^, 0);
y := DataWordGet(LRLEnvironment[i].Image[j].Data^, 2);
LRLEnvironment[i].Image[j].Size := x * y + 4;
end;
end;
y := 181;
x := 212;
for i := 1 to 6 do
begin
if i = 4 then
begin
y := 191;
x := 212;
end;
LRLEditorButton[i].x1 := x;
LRLEditorButton[i].y1 := y;
LRLEditorButton[i].x2 := x + 32;
LRLEditorButton[i].y2 := y + 9;
LRLEditorButton[i].Lit := False;
LRLEditorButton[i].Command := i;
LRLEditorButton[i].DarkIconSize := 292;
LRLEditorButton[i].LightIconSize := 292;
GetMem(LRLEditorButton[i].DarkIcon, LRLEditorButton[i].DarkIconSize);
GetMem(LRLEditorButton[i].LightIcon, LRLEditorButton[i].LightIconSize);
BlockRead(ImageFile, LRLEditorButton[i].LightIcon^, 292, l);
BlockRead(ImageFile, LRLEditorButton[i].DarkIcon^, 292, l);
Inc(x, 33);
end;
{ load font }
GetMem(LRLFont, 20455);
BlockRead(ImageFile, LRLFont^, 20455, k);
{ load Pointer }
GetMem(LRLMousePointer, 174);
BlockRead(ImageFile, LRLMousePointer^, 174, k);
{ load palette }
GetMem(LRLMenuPalette, 768);
BlockRead(ImageFile, LRLMenuPalette^, 768, k);
{ load logo }
GetMem(LRLLogo, 12524);
BlockRead(ImageFile, LRLLogo^, 12524, k);
LRLImagesFilePosition := FilePos(ImageFile);
FreeMem(InBuffer, $FFF0);
end;
procedure ImagesInitialize;
begin
LoadImages;
GetMem(LRLScreen, 64000);
GetMem(LRLFontBuffer, 32000);
end;
procedure ImagesDeinitialize;
var
i, j, l: Integer;
begin
FreeMem(LRLPalette, 768);
for i := 1 to 9 do
for j := 1 to LRLFigure[1, i].ImageCount do
begin
FreeMem(LRLFigure[1, i].Image[j].Data, 104);
for l := 2 to 4 do
FreeMem(LRLFigure[l, i].Image[j].Data, LRLFigure[l, i].Image[j].Size);
end;
for i := 1 to 1 do
for j := 1 to LRLDecoration[i].ImageCount do
FreeMem(LRLDecoration[i].Image[j].Data, 104);
for i := 1 to 9 do
for j := 1 to LRLEnvironment[i].ImageCount do
FreeMem(LRLEnvironment[i].Image[j].Data, 104);
for i := 1 to 6 do
begin
FreeMem(LRLEditorButton[i].DarkIcon, LRLEditorButton[i].DarkIconSize);
FreeMem(LRLEditorButton[i].LightIcon, LRLEditorButton[i].LightIconSize);
end;
FreeMem(LRLFont, 20455);
FreeMem(LRLMousePointer, 174);
FreeMem(LRLMenuPalette, 768);
FreeMem(LRLLogo, 12524);
FreeMem(LRLScreen, 64000);
FreeMem(LRLFontBuffer, 32000);
Close(ImageFile);
end;
end.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,30 @@
@echo off
rem „«ï ᡮન ¨£àë ­¥®¡å®¤¨¬® ¢ ¯¥à¥¬¥­­®© UNITS (®¯à¥¤¥«¥­  ­¨¦¥)
rem 㪠§ âì à á¯®«®¦¥­¨¥ ¯ ¯ª¨, ¢ ª®â®à®© ­ å®¤ïâáï ®âª®¬¯¨«¨à®¢ ­­ë¥ ¬®¤ã«¨
rem RTL ¤«ï KolibriOS. <20> ¯à¨¬¥à, ¥á«¨ ¨á室­¨ª¨ RTL ­ å®¤ïâáï ¢ ¯ ¯ª¥ my/rtl,
rem ⮠ᮡ࠭­ë¥ ¬®¤ã«¨ RTL - ᪮॥ ¢á¥£® ¢ my/units. Œ®¦¥â ®ª § âìáï
rem ¤®áâ â®ç­ë¬ ¯à®áâ® ¯¥à¥­¥á⨠íâã ¯ ¯ªã (lrl) ¢ ¤¨à¥ªâ®à¨î my.
rem ’ ª ¦¥, ¤«ï ᡮન, ¢ ¬ ¯®­ ¤®¡¨âáï ã⨫¨â  exe2kos.exe ¨ FreePascal 2.2.0.
set NAME=lrl
set NAMEEXE=%NAME%.exe
set NAMEKEX=%NAME%.kex
set BUILD=-FUbuild
set UNITS=-Fu../units
fpc %NAME%.pp -n -Twin32 -Se5 -XXs -Sg -O3pPENTIUM3 -CfSSE -WB0 %BUILD% %UNITS%
if errorlevel 1 goto error
exe2kos.exe %NAMEEXE% %NAMEKEX%
del %NAMEEXE%
move %NAMEKEX% bin
goto end
:error
echo An error occured while building %NAME%
:end

View File

@ -0,0 +1,10 @@
Lode Runner Live 1.0
====================
<EFBFBD>஥ªâ ¯® ¯¥à¥­®áã ¨£àë Lode Runner Live 1.0 á ¯« âä®à¬ë DOS ¢ KolibriOS.
—¨â ©â¥ ª®¬¬¥­â à¨¨ ¯® ª®¬¯¨«ï樨 ¢ build.bat.
<EFBFBD>  ¤ ­­ë© ¬®¬¥­â â¥áâ¨à®¢ « áì ªà®áª®¬¯¨«ïæ¨ï ⮫쪮 ¨§ Windows 2000 SP4
­  32å à §à來®© ¬ è¨­¥.