500 lines
11 KiB
ObjectPascal
500 lines
11 KiB
ObjectPascal
|
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);
|
|||
|
|
|||
|
{ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><>ப<EFBFBD> }
|
|||
|
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;
|
|||
|
|
|||
|
{ <20>뢮<EFBFBD> <20><>ப<EFBFBD> }
|
|||
|
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.
|