program fading_text;
var  
   	time1, waitTime,x,y,i,j,val : byte = 0; 

// @max defines how many texts can be written on the screen at the same time
@define max 6
@define useKernal 1

	// Colors to fade between, one per frame
	colors:  array[] of byte = (0,$3e,$3e,$39,$41,$42,$44,$48,$51,$5e,$52,$5f,$61,$63,$77,$7f,$71,$71,$71,$71,$71,$71,$71,$71,$71,$71,$71,$71,$7f,$77,$63,$61,$5f,$52,$5e,$51,$48,$44,$42,$41,$39,$3e,$3e,$3e,$3e);


	// Current texts, supports @max 
	text_x, text_y, text_time, text_len:array[@max] of byte = (0,0,0,0,0,0);

	// Pointer to text and color ram
	textPtr, colorPtr:pointer;


	// the text itself: format
	// x,y, "string", 0, pause time
	// terminates with 255, restarts

	demotext: string = (5,10, "TURBO RASCAL", 0,8,
						8,12, "PRESENTS",0,8,
						3,12, "ALPHA", 0,1,
						10,12, "BETA", 0,1,
						18,12, "GAMMA", 0,1,
						10,14, "DELTA", 0,4,

						3,5, "VARIABLE",0,8
						3,7, "FADING",0,4
						10,15, "TEXT",0,6
						20,4, "WITH",0,6
						8,12, "PAUSES",0,12,
						255);


/*
	Finds an available slot out of @max, checks for time =0

*/

procedure FindAvailableSlot(); // returns j
begin
	j:=0;
	for i:=0 to @max do begin
		if text_time[i]=0 then begin 
			j:=i; 
			return(); 
		end;
	end;
end;
	
/*
	Advances the text counter, searches through data and assigns a new slot (out of total @max)
*/
procedure Advance();
begin
	// Finds one out of @max available slots (with time zero)
	FindAvailableSlot(); // Sets j
	// keep x/y position
	x:=textPtr[0];
	y:=textPtr[1];
	text_x[j]:=x;
	text_y[j]:=y;

	// Set time to size of color list
	text_time[j]:=40; // set time
	// Advance to text
	textPtr:=textPtr+2;
	// Move screenmemory pointer to $d800 color ram
	moveto(x,y,hi(screen_col_loc));
	colorPtr:=screenmemory;
	// Also, move to screen position
	moveto(x,y,hi(screen_char_loc));
	i:=0;
	// Write chars as long as char isn't zero 
	while (textPtr[0]<>0) do begin
		colorPtr[i]:=0; // Should be black!
		val:=textPtr[0];
		if (val>64) then val:=val-64; // Petscii/c64 codes conversion
		screenmemory[i]:=val;
		inc(i);
		textPtr:=textPtr+1;
	end;
	text_len[j]:=i; // Set length
	waitTime:=textPtr[1];
	// Pointing to the next
	textPtr:=textPtr+2;
	// If value is 255, then reset text pointer
	if (textPtr[0]=255) then textPtr:=#demotext;
end;

/*
	Called per frame (or second, or whatever)
	Loops through all slots with time>0 and updates color ram. 
	Color should be terminated same as background color, here black

*/
procedure UpdateTextColors();
begin
	for i:=0 to @max do begin
		if (text_time[i]<>0) then begin // is active: update color 
			text_time[i]:=text_time[i]-1; // damn dec doesn't work
			val:=colors[text_time[i]];
			moveto(text_x[i],text_y[i],hi(screen_col_loc));
			j:=text_len[i];
			fill(screenmemory,val,j);
//			for j:=0 to text_len[i] do screenmemory[j]:=val;

		end;
	end; 

end;


/*
	Main update loop. Replace with a raster.
*/
procedure Update();
begin
	inc(time1);
	// Update colors
	UpdateTextColors();
	// Every 7th frame, advance timer
	if (time1&7=0) then begin	
		dec(waitTime);
		// if wait time is over, advance text pointer and create a new slot
		if (waitTime>127) then 
			Advance();
	end;

end;

// Main raster, enables Update to be called once per raster cycle
interrupt RasterMain();
begin
	StartIRQ(@useKernal);
	Update();

	CloseIRQ();
end;

// Main block
begin
	screen_bg_col:=black;
	screen_fg_col:=black;
	textPtr:=#demotext;
	ClearScreen(key_space,screen_char_loc);
	ClearScreen(black,screen_col_loc);

	StartRasterChain(RasterMain(),$fe,@useKernal);
	Loop();
end.
