pax_global_header00006660000000000000000000000064132347272060014520gustar00rootroot0000000000000052 comment=3e3561d1ed0ac79a36937e44e1a04f4ad9c4807f el-ixir-3.0/000077500000000000000000000000001323472720600127335ustar00rootroot00000000000000el-ixir-3.0/.gitignore000066400000000000000000000000621323472720600147210ustar00rootroot00000000000000*~ DEADJOE *.exe *.gpi *.o *.ppu el-ixir *.tar.gz el-ixir-3.0/LICENSE000066400000000000000000000004221323472720600137360ustar00rootroot00000000000000Copyright © 1990 Adam Borowski This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. el-ixir-3.0/Makefile000066400000000000000000000005641323472720600144000ustar00rootroot00000000000000el-ixir: *.pas fpc -XX el-ixir.pas clean: rm -f *.gpi *.o *.ppu el-ixir install: el-ixir mkdir -p "$$DESTDIR/usr/games" install -c el-ixir "$$DESTDIR/usr/games/" dist: rm -rf tmp mkdir tmp VER=`git describe --tags` && \ mkdir "tmp/el-ixir-$$VER" && \ cp -p *.pas Makefile "tmp/el-ixir-$$VER/" && \ cd tmp && \ tar cfz "../el-ixir-$$VER.tar.gz" * rm -rf tmp el-ixir-3.0/README.md000066400000000000000000000041241323472720600142130ustar00rootroot00000000000000EL-IXIR ======= **El-Ixir** is a two-player same-computer game (although it is possible to use a shared tmux for remote play). It appears to have been invented by a company named Isoft in 1981, released as a booter floppy for PC/XT. Alas, no copy seems to be available anywhere on the 'Net. Two other remakes can be found on defunct-but-archived webpages, although each of them has rules slightly different from the original (or at least from how I remember the original). Unlike those two, this remake (which I made somewhere around 1990) tries to be exactly same as the original, in both gameplay and appearance — again, as exact as a 12 years old kid remembered a game he last played at an age of six. What's missing is music and an alternate display mode that used CGA 40x25 text. On the other hand, the game is playable on any modern Unix-like system, with a vt100ish terminal whose character set includes glyphs of IBM ROM BIOS (aka CP437), obviously using Unicode. Rules ===== The object of the game is to connect as much of blocks in your colour to the corners. The players take turns, being presented with four random tiles each turn. ## Moving: To make a move, choose one of the four tiles that were rolled for you. Next, choose a direction (up, left, right, down) and length (1-4). If a block of that length won't fit, it's silently cut to the longest length there's space for. (Hint: it's almost always beneficial to choose length 4). ## Anchoring: If the block you placed causes some blocks to be connected to one of the corners, you will be credited a point for every tile covered by a block in your color that's connected to a corner by an unbroken line (via cardinal directions only — diagonals are not enough). ## Embracing: There are two types of embraces: * complete embrace, when your blocks either completely enclose a part of the board or wall it in into a border * anchored embraces, which trade the requirement of enclosing only parts of the board that contain no free tiles for allowing braces that are connected only diagonally Whichever player gets the most points, wins. el-ixir-3.0/el-ixir.6000066400000000000000000000034261323472720600144000ustar00rootroot00000000000000.TH el-ixir 6 .SH NAME el-ixir \- a two-player board game .SH DESCRIPTION .B El-Ixir is a board game with an element of randomness. It is played by two players at the same terminal, although it is possible to use a shared tmux for remote play. The game should be playable on any vt100ish terminal whose character set includes a certain subset of glyphs of IBM ROM BIOS, encoded as Unicode. Terminals not meeting this requirement should be long extinct. .SH RULES The object of the game is to connect as many blocks in your colour to the corners. The players take turns, being presented with four random tiles each turn. .P The game is controlled by pressing any key (not \fIShift\fR or \fICtrl\fR...); \fIq\fR quits. .TP .B Moving: To make a move, choose one of the four tiles that were rolled for you. Next, choose a direction (up, left, right, down) and length (1-4). If a block of that length won't fit, it's silently cut to the longest length there's space for. (Hint: it's almost always beneficial to choose length 4). .TP .B Anchoring: If the block you placed causes some blocks to be connected to one of the corners, you will be credited a point for every tile covered by a block in your color that's connected to a corner by an unbroken line (via cardinal directions only — diagonals are not enough). .TP .B Embracing: There are two types of embraces: .IP \(bu complete embrace, when your blocks either completely enclose a part of the board or wall it in into a border .IP \(bu anchored embrace, which trades the requirement of enclosing only parts of the board that contain no free tiles for allowing braces that are connected only diagonally. It is possible that a move makes both players eligible for an embrace \(em your opponent has priority. .PP Whichever player gets the most points, wins. el-ixir-3.0/el-ixir.pas000066400000000000000000000504061323472720600150160ustar00rootroot00000000000000uses mycrt,Mouse,unix; type tsquare=array[0..5] of string; tscreen=array of array of array[0..1] of string; var SX,SY,SX2:integer; const delay1=550; { delay when cycling between options } delay2=250; { score increment delay } delay3=400; { embrace delay } delay4=100; { delay when placing parts of a stone } fanim=5; { # of animation phases } b0=#$70; arrows:array[0..3] of tsquare= ((' ',b0,'←',b0,' ',b0), (' ',b0,'↑',b0,' ',b0), (' ',b0,'→',b0,' ',b0), (' ',b0,'↓',b0,' ',b0)); digits:array[0..3] of tsquare= ((' ',b0,'1',b0,' ',b0), (' ',b0,'2',b0,' ',b0), (' ',b0,'3',b0,' ',b0), (' ',b0,'4',b0,' ',b0)); empty:tsquare=(' ',#7,' ',#7,' ',#7); timem:tsquare=(' ',#7,'•',#7,' ',#7); dirx:array[0..3] of integer=(-1,0,1,0); diry:array[0..3] of integer=(0,-1,0,1); wtl=3; { width of time indicator } tlmx=14; tlmy=3; { pos of time limit indicator, per move } tlgx1=3; tlgy=10; { pos of time limit indicator, per game } py=4; cb1=#$0f; cb2=#$07; ct0=#$70; c1= #$1a; c1s=#$12; c2= #$5d; c2s=#$5c; sqb1:tsquare=('▒',cb1,'▒',cb1,'▒',cb1); sqb2:tsquare=('▓',cb2,'▓',cb2,'▓',cb2); sqc:tsquare=(' ',ct0,'Θ',ct0,' ',ct0); sqs:array[1..2] of tsquare= ((' ',c1s,'•',c1s,' ',c1s), (' ',c2s,'•',c2s,' ',c2s)); sqf:array[1..2] of tsquare= ((' ',c1 ,'•',c1 ,' ',c1 ), (' ',c2 ,'•',c2 ,' ',c2 )); sqcf:array[1..2] of tsquare= ((' ',c1 ,'Ω',c1 ,' ',c1 ), (' ',c2 ,'Ω',c2 ,' ',c2 )); var quitting:boolean; fast:boolean; tl_kind:(TL_NONE,TL_MOVE,TL_GAME); tlimit:array[1..2] of integer; sco:array[1..2] of integer; screen:tscreen; board,board1:array[0..15,0..15] of integer; queue:array[1..196] of record x,y:byte end; qp1,qp2:integer; { queue indices: producer, consumer } em:boolean; { just embraced? } freesq:integer; an:array[1..2] of integer; vx,vy:integer; { virtual cursor's position } procedure delay(ms:integer); begin if fast then exit; mycrt.delay(ms); end; procedure gotoxy(x,y:integer); begin vx:=x; vy:=y; end; procedure outtext(txt:string); var i:integer; begin for i:=1 to length(txt) do begin if txt[i]<' ' then txt[i]:='?'; screen[vy,vx+i-1,0]:=txt[i]; screen[vy,vx+i-1,1]:=char(TextAttr); end; mycrt.gotoxy(vx,vy); crtwrite(txt); end; procedure draw(x,y:integer;p:tsquare); procedure c(s:string); begin if s='' then TextAttr:=7 else TextAttr:=ord(s[1]); end; var i:integer; begin for i:=0 to 5 do screen[y,x+(i div 2),i mod 2]:=p[i]; mycrt.gotoxy(x,y); c(p[1]); crtwrite(p[0]); c(p[3]); crtwrite(p[2]); c(p[5]); crtwrite(p[4]); end; procedure clearqueue; begin qp1:=0; qp2:=0 end; procedure pushqueue(x,y:integer); begin inc(qp1); queue[qp1].x:=x; queue[qp1].y:=y end; procedure showtime(pl:integer); var m,n:integer; txt:string[20]; begin case tl_kind of TL_MOVE:begin textattr:=$70; if pl=1 then m:=tlmx else m:=SX-tlmx-wtl*14; for n:=1 to 14 do draw(m-wtl+n*wtl,tlmy,timem) end; TL_GAME:begin textattr:=7; if pl=1 then gotoxy(tlgx1+1,tlgy) else gotoxy(SX-tlgx1-5+1,tlgy); outtext('Time:'); if pl=1 then gotoxy(tlgx1+2, tlgy+2) else gotoxy(SX-tlgx1-5+2,tlgy+2); str(tlimit[pl]:3, txt); outtext(txt) end; end; end; procedure showdectime(pl:integer); var txt:string[20]; begin case tl_kind of TL_MOVE:begin textattr:=$70; if pl=1 then draw(tlmx+tlimit[pl]*wtl,tlmy,empty) else draw(SX-tlmx-wtl-tlimit[pl]*wtl,tlmy,empty) end; TL_GAME:begin textattr:=7; if pl=1 then gotoxy(tlgx1+2, tlgy+2) else gotoxy(SX-tlgx1-5+2,tlgy+2); str(tlimit[pl]:3, txt); outtext(txt) end; end; end; procedure cleartime(pl:integer); var m,n:integer; begin case tl_kind of TL_MOVE:begin textattr:=$70; if pl=1 then m:=tlmx else m:=SX-tlmx-wtl*14; for n:=1 to 14 do draw(m-wtl+n*wtl,tlmy,empty) end; end; end; function waskey(timed:boolean;pl:integer):boolean; var ch:char; begin if not (quitting or timed) then waitkey; if keypressed or quitting then begin while keypressed do ch:=readkey; if ch='q' then begin quitting:=true; fast:=true end; waskey:=true end else if (GetMouseButtons and 1)<>0 then waskey:=true else if timed and (tl_kind<>TL_NONE) then begin dec(tlimit[pl]); if tlimit[pl]<0 then begin tlimit[pl]:=0; waskey:=true end else begin showdectime(pl); waskey:=false end end else waskey:=false end; procedure drawsquare(x,y:integer;w:tsquare); begin draw(SX2-23+3*x,4+y,w); end; procedure clearsquare(x,y:integer); begin if ((x=1) or (x=14)) and ((y=1) or (y=14)) then drawsquare(x,y,sqc) else if odd(x+y) then drawsquare(x,y,sqb1) else drawsquare(x,y,sqb2) end; procedure fillsquare(x,y,pl:integer); begin if ((x=1) or (x=14)) and ((y=1) or (y=14)) then drawsquare(x,y,sqcf[pl]) else drawsquare(x,y,sqf[pl]) end; procedure anim(x,y,pl:integer); var x0,y0,x1,y1:integer; xc,yc:integer; n,i:integer; tmp:tsquare; numc:integer; const corners:array[1..4,1..2] of integer=((1,1),(14,1),(14,14),(1,14)); begin numc:=0; for n:=1 to 4 do if board[corners[n,1],corners[n,2]]=pl*2 then inc(numc); if numc=0 then begin fillsquare(x,y,pl); delay(delay3); exit end; an[pl]:=an[pl] mod numc+1; numc:=0; for n:=1 to 4 do if board[corners[n,1],corners[n,2]]=pl*2 then begin inc(numc); if numc=an[pl] then begin x0:=corners[n,1]; y0:=corners[n,2] end end; y1:=py+y; x1:=SX2-23+3*x; y0:=py+y0; x0:=SX2-23+3*x0; for n:=0 to fanim do begin xc:=x0+longint((x1-x0))*n div fanim; yc:=y0+longint((y1-y0))*n div fanim; for i:=0 to 5 do tmp[i]:=screen[yc,xc+(i div 2),i mod 2]; draw(xc,yc,sqf[pl]); delay(delay3 div (fanim+1)); draw(xc,yc,tmp); end; fillsquare(x,y,pl) end; function boardsame:boolean; var x,y:integer; begin for x:=1 to 14 do for y:=1 to 14 do if board[x,y]<>board1[x,y] then begin boardsame:=false; exit end; boardsame:=true end; procedure message(pl:integer;str:string); begin gotoxy(SX2-1-length(str) div 2,SY-4); if pl=1 then textattr:=byte(c1) else if pl=2 then textattr:=byte(c2) else textattr:=byte(b0); outtext(' '+str+' ') end; procedure clearmessage; begin textattr:=7; gotoxy(SX2-10,SY-4); outtext(' ') end; procedure showwinner; begin if sco[1]>sco[2] then message(1,'EL-IXIR') else if sco[1]99 then n:=0 else if sco[pl]>9 then n:=1 else n:=2; if sco[pl]>99 then begin gotoxy(x,4); outtext('1') end; if sco[pl]>9 then begin gotoxy(x,5-n); outtext(char(ord('0')+sco[pl] div 10 mod 10)) end; gotoxy(x,6-n); outtext(char(ord('0')+sco[pl] mod 10)) end; procedure sweepandmark(pl:integer;msg:string); procedure check(x,y:integer); begin if board1[x,y]=pl*2-1 then begin pushqueue(x,y); board1[x,y]:=pl*2 end end; var x,y:integer; begin board1:=board; for x:=1 to 14 do for y:=1 to 14 do if board1[x,y]=pl*2 then board1[x,y]:=pl*2-1; clearqueue; check(1,1); check(1,14); check(14,1); check(14,14); while qp1>qp2 do begin inc(qp2); x:=queue[qp2].x; y:=queue[qp2].y; check(x+1,y); check(x-1,y); check(x,y+1); check(x,y-1) end; if not boardsame then begin message(pl,msg); for x:=1 to 14 do for y:=1 to 14 do if board1[x,y]<>board[x,y] then begin inc(sco[pl]); score(pl); delay(delay2) end; board:=board1; clearmessage end; end; procedure completeembrace(pl:integer); var b:boolean; procedure check(x,y:integer); begin if board1[x,y]=0 then begin pushqueue(x,y); board1[x,y]:=-1 end end; procedure check1(x,y:integer); begin if board1[x,y]=0 then begin pushqueue(x,y); board1[x,y]:=-2; if (board[x-1,y]=pl*2) or (board[x+1,y]=pl*2) or (board[x,y-1]=pl*2) or (board[x,y+1]=pl*2) then b:=true end end; var x,y,x1,y1:integer; begin board1:=board; for x:=1 to 14 do for y:=1 to 14 do if board1[x,y]=pl*2 then board1[x,y]:=pl*2-1; for x:=1 to 14 do for y:=1 to 14 do if board1[x,y]<>pl*2-1 then board1[x,y]:=0; clearqueue; check(1,1); check(1,14); check(14,1); check(14,14); while qp1>qp2 do begin inc(qp2); x:=queue[qp2].x; y:=queue[qp2].y; check(x+1,y); check(x-1,y); check(x,y+1); check(x,y-1); check(x+1,y+1); check(x-1,y-1); check(x-1,y+1); check(x+1,y-1) end; b:=false; for x:=1 to 14 do for y:=1 to 14 do if board1[x,y]=0 then begin x1:=x; y1:=y; b:=true end; if not b then exit; b:=false; clearqueue; check1(x1,y1); while qp1>qp2 do begin inc(qp2); x:=queue[qp2].x; y:=queue[qp2].y; check1(x+1,y); check1(x-1,y); check1(x,y+1); check1(x,y-1) end; message(pl,'Complete Embrace'); em:=true; for y:=1 to 14 do for x:=1 to 14 do if board1[x,y]=-2 then begin if board[x,y]=0 then dec(freesq); if b then begin inc(sco[pl]); score(pl); board[x,y]:=pl*2 end else board[x,y]:=pl*2-1; anim(x,y,pl) end; sweepandmark(pl,'Complete Embrace'); clearmessage end; procedure anchorembrace(pl:integer); procedure check(x,y:integer); begin if board1[x,y]=-3 then begin pushqueue(x,y); board1[x,y]:=-1 end end; procedure check1(x,y:integer); begin if board[x,y]=(3-pl)*2 then begin pushqueue(x,y); board1[x,y]:=-1 end end; procedure check2(x,y:integer); begin if board1[x,y]=-3 then begin pushqueue(x,y); board1[x,y]:=-2 end end; var b:boolean; x,y,x1,y1:integer; begin board1:=board; for x:=1 to 14 do for y:=1 to 14 do if (board1[x,y]<>pl*2) and (board1[x,y]<>0) then board1[x,y]:=-3; clearqueue; for y:=1 to 14 do for x:=1 to 14 do if board[x,y]=0 then begin pushqueue(x,y); board1[x,y]:=-1 end; check1(1,1); check1(1,14); check1(14,1); check1(14,14); while qp1>qp2 do begin inc(qp2); x:=queue[qp2].x; y:=queue[qp2].y; check(x+1,y); check(x-1,y); check(x,y+1); check(x,y-1) end; b:=false; for y:=1 to 14 do for x:=1 to 14 do if board1[x,y]=-3 then begin x1:=x; y1:=y; b:=true end; if not b then exit; clearqueue; check2(x1,y1); while qp1>qp2 do begin inc(qp2); x:=queue[qp2].x; y:=queue[qp2].y; check2(x+1,y); check2(x-1,y); check2(x,y+1); check2(x,y-1) end; message(pl,'Anchoring Embrace'); em:=true; for y:=1 to 14 do for x:=1 to 14 do if board1[x,y]=-2 then begin if board[x,y]=0 then dec(freesq); inc(sco[pl]); score(pl); board[x,y]:=pl*2; anim(x,y,pl) end; sweepandmark(pl,'Anchoring Embrace'); clearmessage end; procedure playermove(pl:integer); var selsq:array[1..4] of record x,y:integer end; numsel,len:integer; x,y,n,m:integer; begin if freesq<4 then numsel:=freesq else numsel:=4; if tl_kind=TL_MOVE then tlimit[pl]:=14; showtime(pl); for n:=1 to numsel do begin repeat x:=random(14)+1; y:=random(14)+1; until board[x,y]=0; board[x,y]:=-1; selsq[n].x:=x; selsq[n].y:=y end; n:=1; if numsel>1 then repeat with selsq[n] do clearsquare(x,y); inc(n); if n>numsel then n:=1; with selsq[n] do drawsquare(x,y,sqs[pl]); delay(delay1); until waskey(true,pl); for m:=1 to numsel do with selsq[m] do board[x,y]:=0; x:=selsq[n].x; y:=selsq[n].y; if (board[x+1,y]=0) or (board[x-1,y]=0) or (board[x,y+1]=0) or (board[x,y-1]=0) then begin if tl_kind=TL_MOVE then begin tlimit[pl]:=14; showtime(pl) end; n:=random(4); repeat n:=succ(n) mod 4; drawsquare(x,y,arrows[n]); delay(delay1); until waskey(true,pl); m:=n; n:=1; if tl_kind=TL_MOVE then begin tlimit[pl]:=14; showtime(pl) end; repeat n:=(n+2) mod 4+1; drawsquare(x,y,digits[n-1]); delay(delay1); until waskey(true,pl) end else m:=0; cleartime(pl); len:=n; n:=0; repeat board[x+n*dirx[m],y+n*diry[m]]:=pl*2-1; fillsquare(x+n*dirx[m],y+n*diry[m],pl); delay(delay4); dec(freesq); inc(n); until (n=len) or (board[x+n*dirx[m],y+n*diry[m]]>0); sweepandmark(pl,'Anchoring Chain'); repeat em:=false; completeembrace(pl); anchorembrace(3-pl); anchorembrace(pl); until not em end; procedure setsize; var i:integer; begin SX:=ScreenWidth; SY:=ScreenHeight; SX2:=SX div 2; SetLength(screen, SY+1); for i:=1 to SY do SetLength(screen[i], SX+1); end; procedure quit; begin write(#27'[0m'#27'[2J'#27'[0;0f'); cursorin; DoneMouse; halt end; procedure instructions; var f:text; manpath:string; begin DoneCrt; DoneMouse; cursorin; write(#27'[0m'#27'[2J'#27'[0;0f'); {$I-} assign(f, 'el-ixir.6'); reset(f); {$I+} if IOResult=0 then begin close(f); manpath:='./el-ixir.6' end else manpath:='el-ixir'; if fpSystem(ansistring('man '+manpath))<>0 then begin writeln('== Press any key =='); readln end; InitCrt; InitMouse; setsize end; procedure menu; var m,n:integer; ch:char; const min=11; choices:array[min..24] of string[15]=( ' EL-IXIR ', '', '', '', '', 'TIME:', 'For one move', 'For all game', 'No limit', '', 'Instructions', '', 'Play game', 'Exit to DOS'); options:set of byte=[17,18,19,21,23,24]; begin n:=23; repeat textattr:=7; clrscr; cursorout; for m:=min to 24 do begin if m=min then textattr:=$5e else textattr:=7; gotoxy(SX2+2-length(choices[m]) div 2,m); outtext(choices[m]) end; if tl_kind=TL_NONE then gotoxy(SX2+11,19) else gotoxy(SX2+11,integer(tl_kind)+16); outtext('√'); repeat gotoxy(SX2-5,n); textattr:=$70; outtext(' '); gotoxy(SX2+2-length(choices[n]) div 2,n); outtext(choices[n]); ch:=readkey; gotoxy(SX2-5,n); textattr:=$07; outtext(' '); gotoxy(SX2+2-length(choices[n]) div 2,n); outtext(choices[n]); case ch of #0:begin ch:=readkey; case ch of #72:repeat if n>min then dec(n) else n:=24; until n in options; #80:repeat if n<24 then inc(n) else n:=min until n in options; end; end; #27:begin ch:=readkey; case ch of '[':case readkey of 'A':repeat if n>min then dec(n) else n:=24; until n in options; 'B':repeat if n<24 then inc(n) else n:=min until n in options; end; #27:quit; end; end; 'q':quit; end; until (ch=#13) or (ch=' '); textattr:=7; clrscr; case n of 24:quit; 23:break; 19:tl_kind:=TL_NONE; 18:tl_kind:=TL_GAME; 17:tl_kind:=TL_MOVE; 21:instructions; end; until false end; var x,y:integer; pl:integer; begin tl_kind:=TL_NONE; InitMouse; setsize; repeat menu; tlimit[1]:=400; tlimit[2]:=400; quitting:=false; sco[1]:=0; sco[2]:=0; cursorout; randomize; textattr:=7; clrscr; for x:=1 to 14 do for y:=1 to 14 do clearsquare(x,y); if tl_kind=TL_GAME then begin showtime(1); showtime(2) end; for x:=0 to 15 do begin board[x,0]:=127; board[x,15]:=127 end; for y:=1 to 14 do begin board[0,y]:=127; board[15,y]:=127 end; for x:=1 to 14 do for y:=1 to 14 do board[x,y]:=0; freesq:=196; fast:=false; pl:=1; repeat message(pl,'Press any key'); markplayer(pl); waskey(false,0); clearmessage; playermove(pl); pl:=3-pl; until quitting or (freesq=0) or (sco[1]>98) or (sco[2]>98); showwinner; until false end. el-ixir-3.0/mycrt.pas000066400000000000000000000041521323472720600146000ustar00rootroot00000000000000unit mycrt; interface procedure gotoxy(x,y:integer); procedure cursorin; procedure cursorout; procedure delay(ms:integer); procedure crtwrite(txt:string); function keypressed:boolean; function readkey:char; procedure waitkey; procedure clrscr; procedure InitCrt; procedure DoneCrt; var TextAttr:byte; ScreenWidth,ScreenHeight:integer; implementation uses termio, unix, baseunix; var RealAttr:byte; procedure gotoxy(x,y:integer); begin write(#27'[',y-1,';',x-1,'f'); end; procedure cursorout; begin write(#27'[?25l') end; procedure cursorin; begin write(#27'[?25h') end; procedure delay(ms:integer); var tv:timeval; begin tv.tv_sec:=ms div 1000; tv.tv_usec:=(ms mod 1000)*1000; fpSelect(input, @tv); end; procedure SetAttr; const cols:array[0..7] of integer=(0,4,2,6,1,5,3,7); begin if RealAttr<>TextAttr then begin RealAttr:=TextAttr; write(#27'[0;',(TextAttr shr 3) and 1, ';3',cols[TextAttr and 7], ';4',cols[(TextAttr shr 4) and 7], 'm'); end; end; procedure crtwrite(txt:string); begin SetAttr; write(txt); end; function keypressed:boolean; begin keypressed:=fpSelect(input, 0)<>0; end; function readkey:char; var r:char; begin FpRead(0, r, 1); readkey:=r; end; procedure waitkey; begin fpSelect(input, $7fffffff); { ~24 days, workaround a bug in fpc } end; procedure clrscr; begin SetAttr; write(#27'[2J'#27'[0;0f'); end; var oldta, curta: TermIOS; WinInfo : TWinSize; procedure InitCrt; begin TextAttr:=7; RealAttr:=255; TCGetAttr(0, oldta); curta:=oldta; CFMakeRaw(curta); TCSetAttr(0, TCSANOW, curta); if fpIOCtl(1,TIOCGWINSZ,@Wininfo)>=0 then begin ScreenWidth:=WinInfo.ws_col; ScreenHeight:=WinInfo.ws_row; if ScreenWidth<=0 then ScreenWidth:=80; if ScreenHeight<=0 then ScreenHeight:=25; end else begin ScreenWidth:=80; ScreenHeight:=25; end; end; procedure DoneCrt; begin TCSetAttr(0, TCSANOW, oldta); end; initialization InitCrt finalization DoneCrt end.