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 of byte; time: byte; colorIndex:byte; fade : array  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.