{$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.