kolibrios/programs/games/lrl/src/LRLRoutines.pp
bw a03f69b310 removed game cursor & alt+1/2/3/9 -> ctrl+1/2/3/9
git-svn-id: svn://kolibrios.org@1007 a494cfbc-eb01-0410-851d-a64ba20cac60
2009-01-29 04:32:44 +00:00

969 lines
22 KiB
ObjectPascal

{$codepage utf8}
{$mode objfpc}
{$asmmode intel}
unit LRLRoutines;
interface
procedure ImagePut(var Screen, ImageBuffer; X, Y, WinX1, WinY1, WinX2, WinY2: Integer);
procedure ImagePutTransparent(var Screen, ImageBuffer; X, Y, WinX1, WinY1, WinX2, WinY2: Integer);
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 ScreenMode(Mode: Integer);
function ScanToChar(Code: Word): Char;
procedure KeyboardInitialize;
function Keypressed: Boolean;
function ReadKey: Word;
procedure KeyboardFlush;
procedure MouseInitialize;
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 Palette256Set(var Palette256);
procedure Palette256Get(var Palette256);
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 SetInterrupt(Int: Byte; NewAddress: Pointer): Pointer;
procedure FadeClear;
procedure FadeTo(pal: Pointer);
procedure DecompressRepByte(var InArray, OutArray; InArraySize: Word; var OutArraySize: Word);
function GetInterrupt(Int: Byte): Pointer;
procedure WaitForEvent(Timeout: DWord = 0);
procedure AssignFile(var AFile: File; AFileName: String);
function LastDosTick(): Longword;
const
KEY_GREY = $E000;
KEY_UP_BASE = $8000;
KEY_ESC = $0100;
KEY_1 = $0200;
KEY_2 = $0300;
KEY_3 = $0400;
KEY_4 = $0500;
KEY_5 = $0600;
KEY_6 = $0700;
KEY_7 = $0800;
KEY_8 = $0900;
KEY_9 = $0A00;
KEY_0 = $0B00;
KEY_SUBTRACT = $0C00;
KEY_ADD = $0D00;
KEY_BACK = $0E00;
KEY_Q = $1000;
KEY_W = $1100;
KEY_E = $1200;
KEY_R = $1300;
KEY_T = $1400;
KEY_Y = $1500;
KEY_U = $1600;
KEY_I = $1700;
KEY_O = $1800;
KEY_P = $1900;
KEY_LBRACKET = $1A00;
KEY_RBRACKET = $1B00;
KEY_ENTER = $1C00;
KEY_CTRL = $1D00;
KEY_A = $1E00;
KEY_S = $1F00;
KEY_D = $2000;
KEY_F = $2100;
KEY_G = $2200;
KEY_H = $2300;
KEY_J = $2400;
KEY_K = $2500;
KEY_L = $2600;
KEY_SEMICOLON = $2700;
KEY_QUOTE = $2800;
KEY_LSHIFT = $2A00;
KEY_Z = $2C00;
KEY_X = $2D00;
KEY_C = $2E00;
KEY_V = $2F00;
KEY_B = $3000;
KEY_N = $3100;
KEY_M = $3200;
KEY_COMMA = $3300;
KEY_DECIMAL = $3400;
KEY_DIVIDE = $3500;
KEY_RSHIFT = $3600;
KEY_ALT = $3800;
KEY_CAPITAL = $3600;
KEY_F1 = $3B00;
KEY_UP = $4800;
KEY_LEFT = $4B00;
KEY_GREY5 = $4C00;
KEY_RIGHT = $4D00;
KEY_END = $4F00;
KEY_DOWN = $5000;
KEY_PGDN = $5100;
type
ScanToCharRecord = record
Scan: Word;
CL: Char;
CU: Char;
Caps: Boolean;
end;
var
ScreenTitle: PChar = nil;
ScanToCharTable: array[1..45] of ScanToCharRecord = (
(Scan: KEY_0; CL: '0'; CU: ')'; Caps: False), (Scan: KEY_1; CL: '1'; CU: '!'; Caps: False),
(Scan: KEY_2; CL: '2'; CU: '@'; Caps: False), (Scan: KEY_3; CL: '3'; CU: '#'; Caps: False),
(Scan: KEY_4; CL: '4'; CU: '$'; Caps: False), (Scan: KEY_5; CL: '5'; CU: '%'; Caps: False),
(Scan: KEY_6; CL: '6'; CU: '^'; Caps: False), (Scan: KEY_7; CL: '7'; CU: '&'; Caps: False),
(Scan: KEY_8; CL: '8'; CU: '*'; Caps: False), (Scan: KEY_9; CL: '9'; CU: '('; Caps: False),
(Scan: KEY_SUBTRACT; CL: '-'; CU: '_'; Caps: False), (Scan: KEY_ADD; CL: '='; CU: '+'; Caps: False),
(Scan: KEY_Q; CL: 'q'; CU: 'Q'; Caps: True), (Scan: KEY_W; CL: 'w'; CU: 'W'; Caps: True),
(Scan: KEY_E; CL: 'e'; CU: 'E'; Caps: True), (Scan: KEY_R; CL: 'r'; CU: 'R'; Caps: True),
(Scan: KEY_T; CL: 't'; CU: 'T'; Caps: True), (Scan: KEY_Y; CL: 'y'; CU: 'Y'; Caps: True),
(Scan: KEY_U; CL: 'u'; CU: 'U'; Caps: True), (Scan: KEY_I; CL: 'i'; CU: 'I'; Caps: True),
(Scan: KEY_O; CL: 'o'; CU: 'O'; Caps: True), (Scan: KEY_P; CL: 'p'; CU: 'P'; Caps: True),
(Scan: KEY_LBRACKET; CL: '['; CU: '{'; Caps: False), (Scan: KEY_RBRACKET; CL: ']'; CU: '}'; Caps: False),
(Scan: KEY_A; CL: 'a'; CU: 'A'; Caps: True), (Scan: KEY_S; CL: 's'; CU: 'S'; Caps: True),
(Scan: KEY_D; CL: 'd'; CU: 'D'; Caps: True), (Scan: KEY_F; CL: 'f'; CU: 'F'; Caps: True),
(Scan: KEY_G; CL: 'g'; CU: 'G'; Caps: True), (Scan: KEY_H; CL: 'h'; CU: 'H'; Caps: True),
(Scan: KEY_J; CL: 'j'; CU: 'J'; Caps: True), (Scan: KEY_K; CL: 'k'; CU: 'K'; Caps: True),
(Scan: KEY_L; CL: 'l'; CU: 'L'; Caps: True),
(Scan: KEY_SEMICOLON; CL: ';'; CU: ':'; Caps: False), (Scan: KEY_QUOTE; CL: ''''; CU: '"'; Caps: False),
(Scan: KEY_Z; CL: 'z'; CU: 'Z'; Caps: True), (Scan: KEY_X; CL: 'x'; CU: 'X'; Caps: True),
(Scan: KEY_C; CL: 'c'; CU: 'C'; Caps: True), (Scan: KEY_V; CL: 'v'; CU: 'V'; Caps: True),
(Scan: KEY_B; CL: 'b'; CU: 'B'; Caps: True), (Scan: KEY_N; CL: 'n'; CU: 'N'; Caps: True),
(Scan: KEY_M; CL: 'm'; CU: 'M'; Caps: True),
(Scan: KEY_COMMA; CL: ','; CU: '<'; Caps: False), (Scan: KEY_DECIMAL; CL: '.'; CU: '>'; Caps: False),
(Scan: KEY_DIVIDE; CL: '/'; CU: '?'; Caps: False)
);
implementation
uses
SysUtils;
const
BUFFER_WIDTH = 320;
BUFFER_HEIGHT = 200;
type
PRGBColor = ^TRGBColor;
TRGBColor = packed record
R, G, B: Byte;
end;
PRGBPalette = ^TRGBPalette;
TRGBPalette = array[Byte] of TRGBColor;
var
ScreenRGBPalette: TRGBPalette;
ScreenRGBBuffer : PRGBColor = nil;
ScreenRGBTemporary: PRGBColor = nil;
ScreenPalBuffer : array[0..BUFFER_HEIGHT - 1, 0..BUFFER_WIDTH - 1] of Byte;
WindowWidth : Longint;
WindowHeight: Longint;
ScreenWidth : Longword;
ScreenHeight: Longword;
CurrentScreenMode: Integer = 0;
LastKeyEvent: Word = $FFFF;
LastKeyUp : Boolean = True;
LastKeyDown: Boolean = False;
CtrlDown : Boolean = False;
ShiftDown : Boolean = False;
LShiftDown : Boolean = False;
RShiftDown : Boolean = False;
CapsPressed: Boolean = False;
procedure Paint;
begin
kos_begindraw();
kos_definewindow(10, 10, 100, 100, $64000000);
if CurrentScreenMode <> 0 then
begin
kos_setcaption(ScreenTitle);
if Assigned(ScreenRGBBuffer) then
kos_drawimage24(0, 0, ScreenWidth, ScreenHeight, ScreenRGBBuffer) else
kos_drawrect(0, 0, ScreenWidth, ScreenHeight, $FF00FF);
end;
kos_enddraw();
end;
procedure UpdateRGBBuffer;
var
XStep, YStep: Longword;
procedure Horizontal;
var
X, Y, I: Longword;
B: PByte;
C: PRGBColor;
begin
C := ScreenRGBTemporary;
for Y := 0 to BUFFER_HEIGHT - 1 do
begin
I := 0;
B := @ScreenPalBuffer[Y, 0];
for X := 0 to ScreenWidth - 1 do
begin
C^ := ScreenRGBPalette[PByte(B + (I shr 16))^];
Inc(I, XStep);
Inc(C);
end;
end;
end;
procedure Vertical;
var
Y, I: Longword;
S: PRGBColor;
C: PRGBColor;
begin
I := 0;
S := ScreenRGBTemporary;
C := ScreenRGBBuffer;
for Y := 0 to ScreenHeight - 1 do
begin
Move(PRGBColor(S + (I shr 16) * ScreenWidth)^, C^, ScreenWidth * SizeOf(C^));
Inc(I, YStep);
Inc(C, ScreenWidth);
end;
end;
var
I, J: Longint;
B: PByte;
C: PRGBColor;
begin
if (ScreenWidth = BUFFER_WIDTH) and (ScreenHeight = BUFFER_HEIGHT) then
begin
{перенос один в один}
B := @ScreenPalBuffer;
C := ScreenRGBBuffer;
for I := 0 to BUFFER_HEIGHT - 1 do
for J := 0 to BUFFER_WIDTH - 1 do
begin
C^ := ScreenRGBPalette[B^];
Inc(B);
Inc(C);
end;
end else
begin
{масштабирование}
XStep := (BUFFER_WIDTH shl 16) div ScreenWidth;
YStep := (BUFFER_HEIGHT shl 16) div ScreenHeight;
Horizontal;
Vertical;
end;
Paint;
end;
procedure ImagePut(var Screen, ImageBuffer; X, Y, WinX1, WinY1, WinX2, WinY2: Integer);
var
Width, Height: Longint;
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 < BUFFER_HEIGHT) and (I >= WinY1) and (I <= WinY2) then
begin
if X < WinX1 then
J := WinX1 - X else
J := 0;
if X + Width - 1 > WinX2 then
K := WinX2 - X - J + 1 else
K := Width - J;
Move((P + J)^, (@Screen + I * BUFFER_WIDTH + X + J)^, K);
end;
Inc(P, Width);
end;
end;
procedure ImagePutTransparent(var Screen, ImageBuffer; X, Y, WinX1, WinY1, WinX2, WinY2: Integer);
var
Width, Height: Longint;
I, J, K, L: Integer;
PI, PO: PByte;
begin
Width := PWord(@ImageBuffer)[0];
Height := PWord(@ImageBuffer)[1];
PI := @ImageBuffer + 4;
for I := Y to Y + Height - 1 do
begin
if (I >= 0) and (I < BUFFER_HEIGHT) and (I >= WinY1) and (I <= WinY2) then
begin
if X < WinX1 then
J := WinX1 - X else
J := 0;
if X + Width - 1 > WinX2 then
K := WinX2 - X - J + 1 else
K := Width - J;
Inc(PI, J);
PO := @Screen + I * BUFFER_WIDTH + X + J;
for L := 1 to K do
begin
if PI^ > 0 then
PO^ := PI^;
Inc(PI);
Inc(PO);
end;
Dec(PI, J + K);
end;
Inc(PI, Width);
end;
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, ScreenPalBuffer, SizeOf(ScreenPalBuffer));
UpdateRGBBuffer;
end;
procedure ImageClear(var Buffer);
begin
FillChar(Buffer, BUFFER_WIDTH * BUFFER_HEIGHT, 0);
end;
procedure ScreenMode(Mode: Integer);
var
ThreadInfo: TKosThreadInfo;
begin
if Mode <> CurrentScreenMode then
begin
if Assigned(ScreenRGBBuffer) then FreeMem(ScreenRGBBuffer);
if Assigned(ScreenRGBTemporary) then FreeMem(ScreenRGBTemporary);
case Mode of
-2: begin
ScreenWidth := BUFFER_WIDTH div 2;
ScreenHeight := BUFFER_HEIGHT div 2;
end;
1..3: begin
ScreenWidth := BUFFER_WIDTH * Mode;
ScreenHeight := BUFFER_HEIGHT * Mode;
end;
end;
if CurrentScreenMode = 0 then Paint;
kos_threadinfo(@ThreadInfo);
with ThreadInfo, WindowRect do
begin
WindowWidth := Width - ClientRect.Width + Longint(ScreenWidth);
WindowHeight := Height - ClientRect.Height + Longint(ScreenHeight);
kos_movewindow(Left, Top, WindowWidth, WindowHeight);
end;
CurrentScreenMode := Mode;
ScreenRGBBuffer := GetMem(ScreenWidth * ScreenHeight * SizeOf(ScreenRGBBuffer^));
ScreenRGBTemporary := GetMem(ScreenWidth * BUFFER_HEIGHT * SizeOf(ScreenRGBTemporary^));
UpdateRGBBuffer;
end;
end;
function ScanToChar(Code: Word): Char;
var
I: Word;
begin
for I := Low(ScanToCharTable) to High(ScanToCharTable) do
with ScanToCharTable[I] do
if Scan = Code then
begin
if not CapsPressed then
if not ShiftDown then
Result := CL else
Result := CU
else
if not ShiftDown then
if not Caps then
Result := CL else
Result := CU
else
if not Caps then
Result := CL else
Result := CL;
Exit;
end;
Result := #0;
end;
procedure KeyboardInitialize;
begin
kos_setkeyboardmode(1);
end;
function ReadKeyLoop: Word;
var
Event: Word;
begin
kos_maskevents(ME_PAINT or ME_KEYBOARD);
repeat
Event := kos_getevent();
if Event = SE_PAINT then Paint;
until Event = SE_KEYBOARD;
Result := kos_getkey();
end;
function TranslateKey(Key: Word): Word;
begin
if Key = KEY_GREY then
Result := kos_getkey() else
Result := Key;
LastKeyDown := Result < KEY_UP_BASE;
LastKeyUp := not LastKeyDown;
if LastKeyUp then Dec(Result, KEY_UP_BASE);
if Result = KEY_CTRL then
begin
CtrlDown := LastKeyDown;
Result := $FFFF;
end else
if Result = KEY_LSHIFT then
begin
LShiftDown := LastKeyDown;
ShiftDown := LShiftDown or RShiftDown;
Result := $FFFF;
end else
if Result = KEY_RSHIFT then
begin
RShiftDown := LastKeyDown;
ShiftDown := LShiftDown or RShiftDown;
Result := $FFFF;
end else
if CtrlDown then
case Result of
KEY_1: begin Result := $FFFF; if LastKeyDown then ScreenMode(1); end;
KEY_2: begin Result := $FFFF; if LastKeyDown then ScreenMode(2); end;
KEY_3: begin Result := $FFFF; if LastKeyDown then ScreenMode(3); end;
KEY_9: begin Result := $FFFF; if LastKeyDown then ScreenMode(-2); end;
KEY_0: begin Result := $FFFF; if LastKeyDown then ScreenMode(100); end;
end;
end;
function Keypressed: Boolean;
begin
if (LastKeyEvent < KEY_UP_BASE) and LastKeyDown then
Result := True else
begin
kos_maskevents(ME_KEYBOARD);
if kos_getevent(False) = SE_KEYBOARD then
begin
LastKeyEvent := TranslateKey(kos_getkey());
if LastKeyEvent < KEY_UP_BASE then
Result := LastKeyDown else
Result := False;
end else
begin
LastKeyEvent := $FFFF;
Result := False;
end;
end;
end;
function ReadKey: Word;
begin
repeat
if LastKeyEvent < KEY_UP_BASE then
Result := LastKeyEvent else
Result := TranslateKey(ReadKeyLoop);
LastKeyEvent := $FFFF;
until (Result < KEY_UP_BASE) and LastKeyDown;
end;
procedure KeyboardFlush;
begin
end;
procedure ProcessKeyboard;
begin
LastKeyEvent := TranslateKey(kos_getkey());
end;
const
MK_LBUTTON = 1;
MK_RBUTTON = 2;
MK_MBUTTON = 4;
MouseButtonsCount = 3;
var
MouseButtonsState : DWord;
MouseButtonsPressed : array[1..MouseButtonsCount] of DWord;
MouseButtonsReleased: array[1..MouseButtonsCount] of DWord;
procedure ProcessMouse;
var
I: Longint;
Buttons, ButtonMask: DWord;
NowPressed, WasPressed: Boolean;
begin
Buttons := kos_getmousebuttons();
for I := 1 to MouseButtonsCount do
begin
ButtonMask := 1 shl (I - 1);
NowPressed := (Buttons and ButtonMask) <> 0;
WasPressed := (MouseButtonsState and ButtonMask) <> 0;
if NowPressed and not WasPressed then Inc(MouseButtonsPressed[I]) else
if not NowPressed and WasPressed then Inc(MouseButtonsReleased[I]);
end;
MouseButtonsState := Buttons;
end;
procedure MouseInitialize;
var
I: Longint;
begin
MouseButtonsState := kos_getmousebuttons();
for I := 1 to MouseButtonsCount do
begin
MouseButtonsPressed[I] := 0;
MouseButtonsReleased[I] := 0;
end;
ProcessMouse;
end;
function MSMouseInArea(x1, y1, x2, y2: Integer): Boolean;
var
X, Y: Integer;
begin
MSMouseGetXY(X, Y);
Result := (X >= x1) and (X <= x2) and (Y >= y1) and (Y <= y2);
end;
function MSMouseDriverExist: Boolean;
begin
Result := True;
end;
procedure MSMouseGetXY(var X, Y: Integer);
var
WinPos: TKosPoint;
begin
WinPos := kos_getmousewinpos();
X := Round(Double(WinPos.X) * BUFFER_WIDTH / ScreenWidth);
if X < 0 then X := 0 else
if X >= BUFFER_WIDTH then X := BUFFER_WIDTH - 1;
Y := Round(Double(WinPos.Y) * BUFFER_HEIGHT / ScreenHeight);
if Y < 0 then Y := 0 else
if Y >= BUFFER_HEIGHT then Y := BUFFER_HEIGHT - 1;
end;
function MSMouseButtonStatusGet: Word;
begin
Result := Word(kos_getmousebuttons());
end;
function MSMouseButtonWasPressed(Button: Word; var x, y: Integer): Boolean;
begin
Inc(Button);
if Button < MouseButtonsCount then
begin
Result := MouseButtonsPressed[Button] > 0;
MouseButtonsPressed[Button] := 0;
end else
Result := False;
MSMouseGetXY(x, y);
end;
function MSMouseButtonWasReleased(Button: Word; var x, y: Integer): Boolean;
begin
Inc(Button);
if Button < MouseButtonsCount then
begin
Result := MouseButtonsReleased[Button] > 0;
MouseButtonsReleased[Button] := 0;
end else
Result := False;
MSMouseGetXY(x, y);
end;
procedure MSMouseSetXY(x, y: Integer);
begin
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 Palette256Darken(var Palette256; StartElement, EndElement, Decrement, MinValue: Byte);
var
I, J: Byte;
PB : PByte;
begin
PB := @Palette256;
Inc(PB, StartElement * 3);
for I := StartElement to EndElement do
for J := 1 to 3 do
begin
if PB^ > MinValue then
if PB^ < Decrement then
PB^ := MinValue else
Dec(PB^, Decrement);
Inc(PB);
end;
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;
PB: PByte;
begin
PB := @Buffer + BufferOffset;
for I := 1 to Count do
begin
if PB^ > 0 then
Inc(PB^, Amount);
Inc(PB);
end;
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 32 do
begin
Palette256Transform(Pal1^, Pal^);
Palette256Transform(Pal1^, Pal^);
Palette256Set(Pal1^);
kos_delay(1);
end;
FreeMem(Pal1, 768);
end;
procedure DecompressRepByte(var InArray, OutArray; InArraySize: Word; var OutArraySize: Word);
var
I, J: Word;
PIn : PByte;
POut: PByte;
begin
I := 0;
PIn := @InArray;
POut := @OutArray;
while I < InArraySize do
begin
Inc(I);
if PIn^ = 0 then
begin
Inc(PIn);
J := PIn^;
Inc(I, 2);
Inc(PIn);
Inc(OutArraySize, J);
while J > 0 do
begin
POut^ := PIn^;
Inc(POut);
Dec(J);
end;
Inc(PIn);
end else
if PIn^ < 4 then
begin
J := PIn^;
Inc(I);
Inc(PIn);
Inc(OutArraySize, J);
while J > 0 do
begin
POut^ := PIn^;
Inc(POut);
Dec(J);
end;
Inc(PIn);
end else
begin
POut^ := PIn^;
Inc(PIn);
Inc(POut);
Inc(OutArraySize);
end;
end;
end;
function GetInterrupt(Int: Byte): Pointer;
begin
Result := nil;
end;
procedure WaitForEvent(Timeout: DWord = 0);
var
Event: Word;
begin
kos_maskevents(ME_PAINT or ME_KEYBOARD or ME_MOUSE);
Event := kos_waitevent(Timeout);
case Event of
SE_PAINT: Paint;
SE_KEYBOARD: ProcessKeyboard;
SE_MOUSE: ProcessMouse;
end;
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.