PROGRAM tny_boot ; TYPE str255 = string[ 255 ]; fn_range = 1..14 ; fname = PACKED ARRAY [ fn_range ] OF char ; frec = PACKED RECORD reserved : PACKED ARRAY [ 0..19 ] OF byte ; resvd2 : byte ; attrib : byte ; time_stamp : integer ; date_stamp : integer ; size : long_integer ; name : fname ; END ; path_name = PACKED ARRAY [ 1..80 ] OF char ; file_array = array[ 1..250 ] of str255; InbufType = packed array[1..32044] of byte; Pallete = packed array[0..15] of integer; Screen = packed array[1..32000] of byte; Ptr_screen = ^screen; { pointer to the screen array } var rec_num,i,the_rez : integer; pics : file_array; tiny_path_str : str255; tny_path : path_name; inbuf : InbufType; Pal : Pallete; TinyPic : Screen; l : long_integer; show_title : boolean; CONST Read_Only = 0; null_char = #0; {SCREEN ROUTINES} PROCEDURE GotoXY( x, y : Short_Integer ); EXTERNAL; FUNCTION Physbase : Ptr_screen; XBIOS( 2 ); FUNCTION Get_rez : Integer; XBIOS( 4 ); PROCEDURE Set_screen(Logical_Screen,Physical_Screen:Long_integer; Rez:integer); XBIOS( 5 ); PROCEDURE Setpallete(VAR Pal:Pallete ); XBIOS( 6 ); FUNCTION Setcolor(ColorNumber,Tint:integer):integer; XBIOS( 7 ); PROCEDURE vsync; XBIOS( 37 ); {------------ FILE ROUTINES ---------------} FUNCTION f_open(VAR name :Path_Name; mode :Integer ) :Integer; GemDos($3d); FUNCTION f_close(handle :Integer) :Integer; GemDos($3e); FUNCTION f_read(handle :Integer; count :Long_Integer; VAR buffer :InBufType) :Long_Integer; GemDos($3f); function inkey : char; var char_val : integer; val_return : long_integer; key : char; function bconstat( device : integer ) : boolean; bios( 1 ); function bconin( device : integer ) : long_integer; bios( 2 ); begin if bconstat( 2 ) then { keypressed } val_return := bconin( 2 ) else val_return := 0; char_val := int( val_return ); key := chr( char_val ); inkey := key; end; { inkey } procedure make_path( path_string : str255; var ipath : path_name ); var i : integer; begin FOR i := 1 TO length( path_string ) DO ipath[i] := path_string[i] ; ipath[ length(path_string)+1 ] := chr(0) ; end; { make_path } function good_pic( pic : str255 ) : boolean; var pic_name : path_name; name : str255; res, f : integer; begin name := copy( tiny_path_str, 1, length( tiny_path_str) - 5 ); name := concat( name, pic ); make_path( name, pic_name ); F := f_open(Pic_Name,Read_Only); L := f_read(f, 32044, inbuf); f := f_close(f); res := inbuf[ 1 ]; if res > 2 then res := res - 3; if ( ( the_rez = 2 ) and ( res < 2 ) ) or ( (the_rez < 2 ) and ( res = 2 ) ) then good_pic := false else good_pic := true; end; { good_pic } {$P-} { turn pointer checking off.. } Procedure Show_Tiny_Screen( picname : str255 ); CONST Read_Only = 0; VAR i,j, res, {Screen Resolution} DelayTime, {Number of seconds to display pic on screen} RotStart, {Start color number to rotate} RotEnd, {End color number to rotate} RotSpeed, {Speed and direction to rotate} RotRevolutions, {Number of revolutions to make} RotationsMade, TimeToKill, f :Integer; S_ptr : Ptr_screen; { a pointer to a packed array of bytes... } RotInfo:Boolean; {Is there rotation info for the pic?} {-----------------------------------------------------------------------} PROCEDURE DecodePic; VAR i, j :INTEGER; curplane, curln, curcol :Integer; ctrlptr, dataptr :Integer; ctrlcnt, datacnt :Integer; {..........................................} PROCEDURE PutWord; VAR pos :Integer; BEGIN {PUT WORD} pos := ShL(curplane,1) + curln * 160 + ShL(curcol,3); TinyPic[pos+1] := inbuf[dataptr]; TinyPic[pos+2] := inbuf[dataptr+1]; curln := curln+1; IF curln >= 200 then Begin curln := 0; curcol := curcol + 1; If curcol >= 20 then Begin curcol := 0; curplane := curplane + 1; End End End; {PUT WORD} {..........................................} BEGIN {DECODE PIC} res := inbuf[1]; rotInfo := True; IF res > 2 THEN res := res-3 ELSE rotInfo := False; ctrlptr := 2; IF rotInfo THEN Begin ctrlptr := ctrlptr + 4; RotEnd := (inbuf[2] & 15); RotStart := ShR(inbuf[2],4); RotSpeed := inbuf[3]; RotRevolutions := (inbuf[4] * 256) + inbuf[5]; End; FOR i:=1 TO 16 DO Pal[i-1] := (inbuf[((i-1)*2)+ctrlptr]*256) + inbuf[((i-1)*2)+ctrlptr+1]; ctrlptr:=ctrlptr+32; ctrlcnt:=ShL(inbuf[ctrlptr],8)+inbuf[ctrlptr+1]; datacnt:=ShL(inbuf[ctrlptr+2],8)+inbuf[ctrlptr+3]; ctrlptr:=ctrlptr+4; dataptr:=ctrlptr+ctrlcnt; curplane:=0; curln:=0; curcol:=0; REPEAT IF inbuf[ctrlptr]>=128 THEN BEGIN FOR j:=1 TO (256-inbuf[ctrlptr]) DO BEGIN PutWord; dataptr:=dataptr+2; END; ctrlptr:=ctrlptr+1; END else IF inbuf[ctrlptr]=0 THEN BEGIN FOR j:=1 TO (inbuf[ctrlptr+1]*256+inbuf[ctrlptr+2]) DO PutWord; ctrlptr:=ctrlptr+3; dataptr:=dataptr+2; END else IF inbuf[ctrlptr]=1 THEN BEGIN FOR j:=1 TO (inbuf[ctrlptr+1]*256+inbuf[ctrlptr+2]) DO BEGIN PutWord; dataptr:=dataptr+2; END; ctrlptr:=ctrlptr+3; END else BEGIN FOR j:=1 TO inbuf[ctrlptr] DO {inbuf[ctrlptr]>1} PutWord; ctrlptr:=ctrlptr+1; dataptr:=dataptr+2; END; UNTIL (curplane>=4); END; {DECODE_PIC} procedure title; var i, x1,x2, long, y : integer; begin if show_title then begin if res = 0 then begin x1 := 1; x2 := 40; end else begin x1 := 2; x2 := 79; end;; long := length( picname ) - 4; y := ( 25 - long ) div 2; for i := 1 to long do begin gotoxy( i + y - 1, x1 ); write( picname[ i ] ); end; picname := 'Tiny Boot by dwb'; long := 16; y := 5; for i := 1 to long do begin gotoxy( i + y -1, x2 ); write( picname[ i ] ); end; end; end; { title } {---------------------------------------------------------------------} Begin {SHOW_WELCOME} DecodePic; for i := 0 to 15 do f := Setcolor(i,Pal[i]); {Set Pallete colors} Set_Screen(-1,-1,res); { set correct resolution } S_ptr := Physbase; { grab location of screen... } S_ptr^ := TinyPic; { stuff picture into screen } title; End; {Show_Welcome} {$P=} {Turn pointer checking back on} { ------------------------------------------------------ } Function Random( Low, Hi : Integer ) : Integer; Function XB_Rnd : Long_Integer; Xbios( 17 ); Function Rnd : Real; Begin Rnd := XB_Rnd / 16777216.0; End; Begin Random := Low + Trunc( Rnd * ( Hi - Low +1 ) ); End; { RANDOM.PAS } FUNCTION IO_Result : Short_Integer ; EXTERNAL ; PROCEDURE IO_Check( YesNo : Boolean ) ; EXTERNAL ; FUNCTION get_current_drive : integer ; GEMDOS( 25 ); procedure directory( path : path_name ; var fs : file_array; var total : integer); VAR r : frec ; i : fn_range ; kar : char; PROCEDURE set_dta( VAR buf : frec ) ; GEMDOS( $1a ) ; FUNCTION get_first( VAR path : path_name ; search_attrib :integer ):integer ; GEMDOS( $4e ) ; FUNCTION get_next : integer ; GEMDOS( $4f ) ; PROCEDURE store_file( VAR r : frec ) ; var i : fn_range ; temp : str255; BEGIN temp := ''; WITH r DO BEGIN i := 1 ; WHILE (i <= 14) AND (name[i] <> chr(0)) DO BEGIN temp := concat( temp, name[ i ] ); i := i + 1 END ; total := total + 1; fs[ total ] := temp END ; END ; { store_file } BEGIN set_dta( r ) ; IF get_first( path, 0 ) >= 0 THEN REPEAT store_file( r ) ; kar := inkey; if kar <> null_char then if ( kar = 'Q' ) or ( kar = 'q' ) then halt; UNTIL get_next < 0 ; end; { directory } function exist( name : str255 ) : boolean; var error : integer; which : file of text; begin io_check( false ); reset( which, name ); error := io_result; if error = 0 then exist := true else exist := false; close( which ); io_check( true ); end; { exist } procedure check_alt_path( var tiny_pth : str255 ); var which : file of text; title_show, file_name : str255; begin file_name := concat( tiny_pth, 'TNY_BOOT.INF' ); if exist( file_name ) then begin reset( which, file_name ); readln( which, tiny_pth ); readln( which, title_show ); if tiny_pth[ length( tiny_pth) ] <> '\' then tiny_pth := concat( tiny_pth, '\' ); if ( title_show[ 1 ] = 'n' ) or ( title_show[ 1 ] = 'N' ) then show_title := false; end; end; { check_alt_path } procedure get_pic_names; var drnum : integer; drive : char; BEGIN rec_num := 0; drnum := get_current_drive; drive := chr( drnum + 65 ); tiny_path_str := concat( drive, ':\AUTO\'); check_alt_path( tiny_path_str ); tiny_path_str := concat( tiny_path_str, '*.TNY' ); make_path( tiny_path_str, tny_path ); directory( tny_path, pics, rec_num ); END; { get_pic_names } procedure select_pic( pic : file_array; total : integer; VAR select : integer ) ; var rot : integer; ok : boolean; begin rot := 0; repeat select := random( 1, total ); ok := good_pic( pic[ select ] ); rot := rot + 1; until ( ok ) or ( rot > 50 ); if not ok then select := 0; end; { select_pic } begin { ------------- main routine ----------- } show_title := true; the_rez := get_rez; get_pic_names; select_pic( pics, rec_num, i); if i > 0 then show_tiny_screen( pics[ i ] ); end.