In this tutorial, we’ll be doing some neat stuff that will impress even your corpulent aunt.
Here’s what we’ll be aiming for:
The interesting stuff we’re doing here is displaying text as well as a multi color image in bitmap mode. The trick is as follows
- Wait for the raster to hit line 0
- Make sure you are in bitmap multi color mode
- Let the image display, but for each raster line apply a smooth sine scrolling
- When hitting a specific rasterline at the bottom of the screen, switch graphics mode to standard text
- scroll the text between 0-7 pixels
- when hitting the bottom, revert to multi color mode.
As the multi color image is stored in bank 1 while the text character map is stored in bank 0, we also will be performing a bank switch when jumping between modes. Details details!
program Tutorial7;
var
xscroll, x,y, val, i: byte;
textshift, wobbleShift: byte;
text: array[255] of byte;
time: byte;
colorIndex:byte;
fade : array [16] of byte = (11,6,6,12,4,14,15,1,1,15,14,4,12,6,6,11);
mainChar: IncBin("test.bin","$27FF");
image_color: IncBin("images/octopus_color.bin", "$5000");
image_data: IncBin("images/octopus_data.bin", "$6000");
Nothing too surprising here. As in Tutorial 6, we include a multicolor image in memory bank 1, and have also added a color fade array.
procedure PrintText();
begin
// move to screen position
moveto(2,23, $04);
// print text
PrintString(text, textshift, 36);
// move cursor to color
moveto(2,23, $D8);
colorIndex:=colorIndex+1;
for x:=0 to 36 do begin
val:=fade[((x+colorIndex)/2)&15];
screenmemory[x]:=val;
end;
end;
/pre>
This method just prints the scrolling text, with a shift given by the “textshift” parameter. In addition, we poke the color values shiftet by a sine function. Nice!
interrupt UpdateRaster();
begin
// increase global time
time:=time+1;
// increase text shift only every 8th step due to scrolling
x:=time&7;
if time&7=0 then begin
textshift:=textshift+ 1;
end;
// increase scrolling
xscroll:=(xscroll+1)&7;
y:=0;
// Optional wobble effect on the main image
wobbleShift:=sine[time*2];
while y<210 do begin
// Keep until rasterline hits text line
y:=peek(RASTERLINE_POS, 0);
val:=sine[y*8 + wobbleShift]/32;
scrollx(val);
waitnoraster(1);
end;
// Wait for text line raster
waitForRaster(23*10);
// switch bank to 0
setbank(VIC_BANK0);
// switch graphics mode
setregularcolormode();
settextmode();
// set the vic's data to point to the custom character set
poke(VIC_DATA_LOC, 0, $1A);
// scroll this area
Scrollx(8-xscroll);
// wait for rasterline to hit near bottom
waitForRaster(25*10);
// switch back to bank 1 and set multi color mode again
setbank(VIC_BANK1);
Scrollx(0);
setmulticolormode();
setbitmapmode();
// Make sure we point the vic to the bitmap data
poke(VIC_DATA_LOC, 0, $18);
// finally, update the text
PrintText();
// call system kernel
kernalinterrupt();
end;
This is the main bulk. Breakdown:
- Update timer, text scrolling index (0-7 pixels) and text shift index (i.e. the current position in the text, which should be updated for every scrolling index=0)
- Add a wobble effect to the main image that is currently displayed: while the current rasterline is *above* the line with the text, set the x scroll register to some arbitrary sine value and wait yet another raster line.
- When hitting the desired rasterline (here 230), perform the magic:
- Switch VIC bank to bank 1, where the character map is stored
- Change to regular text mode, non-multicolor
- Set the character map's position
- Set the text scroll x register
- Wait until the rasterline leaves the desired area for text ( here, around 250)
- Now revert back to multicolor bitmap mode, scrolling to zero etc
- Print the updated text
The rest of the code (Setup and Main) should be quite self-explanatory. The important part is copying the image_color data to the Bank 1 of the VIC chip, which is performed with the "copyImageColorData" method.
procedure Setup();
procedure Setup();
begin
ClearScreen($20, SCREEN_CHAR_LOC);
Poke(SCREEN_BG_COL, 0, BLACK);
Poke(SCREEN_FG_COL, 0, BLACK);
setbank(VIC_BANK1);
copyimagecolordata(image_color,1);
text:=" WHY AM I DOING THIS WHEN I SHOULD BE SLEEPING I WANT SMOOTH HARDWARE SCROLLING IRL THIS SCOLLING DOESN'T END PROPERLY";
end;
begin
Setup();
DisableInterrupts();
RasterIRQ(UpdateRaster(), 0);
EnableInterrupts();
Loop();
end.