/** * Single file C64 intro * * Finnish Pirate Party election campaign 2023 */ program PiraattiIntro; var /* Demo part flags */ @define partNone 0 @define partWriter 1 @define partOpenBar 2 @define partSpriteBounce 3 @define partFadeOutOpeningScreen 4 @define partLogoBarWobble 5 @define partBounceBarUp 6 @define partMain 7 currentPart : byte = @partNone; currentTime : integer = 0; currentPartDone : boolean = true; /* Main screen state flags */ @define mainShowText 0 @define mainFadeToPicture 1 @define mainPicture 2 @define mainFadeToText 3 mainState : byte = @mainPicture; mainTime : integer = 0; /* Opening writer main variables */ bTime, curWait, curCol, i : byte = 0; tp, sp: pointer; onPause, bigSprite : boolean; textColFade : array[] of byte = ($01, $03, $0c, $0d, $01, $01, $01, $01); @define cpause 220 @define cmoveto 221 @define cstop 223 @define cpage 224 @define cloop 225 /* Writer sprite flying */ charOnSprite0 : byte = 0; spriteX : integer = 0; spriteY : byte = 0; textX, textY : byte = 0; @define spriteLoc $3c80 @define charSetCopyLoc $c000 charsetCopyBlock : array[1024] of byte = buildtable("0") at @charSetCopyLoc; @define spriteBank 0 spriteCopyBlock : array[63] of byte = buildtable("0") at @spriteLoc; lookup3Dx : array[40] of integer = buildtable("300 * (i - 20) / 200"); lookup3Dy : array[25] of integer = buildtable("300 * (i - 11) / 30"); flightColFade : array[] of byte = ($01, $0c, $01, $0b, $01, $00, $0f, $00, $01); @define betweencharpause 8 /* Writer text. @cmoveto moves the cursor to the x/y position @ccolor sets color @cpause initializes a pause */ text : string = (@cmoveto, 6,10, "TIETOYHTEISKUNTA TARVITSEE ", @cpause,12, @cmoveto, 10,12, "TEKNOLOGIAPUOLUEEN ", @cpause,32, @cstop); /* Opening color plasma variables */ textPlasmaX : array[256] of integer = buildtable("5 * (Math.sin(3 * i * 6.28 / 256) * 0.5 + 0.5) + 12 * (Math.sin(2 * i * 6.28 / 256) * 0.5 + 0.5)"); fastPlasma : array[256] of byte; textPlasmaLumi : array[] of byte = ($06, $0b, $0c, $0e, $0f, $03, $0d, $07, $01, $01, $01, $01, $01, $01, $01); textLumi2 : array[] of byte = ($01, $07, $0d, $03, $0f, $0e, $0c, $0b, $06, $0b, $0c, $0e, $0f, $03, $0d, $07, $01); fastPlasmaSweep : array[256] of byte = buildtable("10 * (-Math.cos(2 * i * 6.28 / 256) * 0.5 + 0.5)"); textPlStartX : byte = 0; textPlStartY : byte = 0; textPlEndX : byte = 40; textPlEndY : byte = 7; textPlOfsX, textPlOfsY : byte = 0; textPlAdd : byte = 0; textBlinkOfs : byte = 0; /* Purple bar variables */ @define purpleBarBounceSize 128 @define purpleBarDefaultCenter 180 @define purpleBarCenterOffset 17 purpleBarBounce : array[@purpleBarBounceSize] of byte = buildtable("17 * Math.abs( (i <= 64) ? Math.exp(5*((i/64)-1)) : 1 - ( Math.abs(Math.cos( ((i/64)+0.5) * 3.1415 )) / Math.pow((i/64),2) ) )") at $5a00; purpleBarBounce2 : array[@purpleBarBounceSize] of byte = buildtable("60 + 120 * (Math.pow(2, -8 * (i/128)))") at $5a80; purpleBounceOfs : byte = 0; purpleBarCenter : byte = @purpleBarDefaultCenter; bgColBefore, fgColBefore : byte = 0; purpleBarStartRasterLine : byte = @purpleBarDefaultCenter - 17; purpleBarEndRasterLine : byte = @purpleBarDefaultCenter + 17; /* Sprite bounce variables */ @define spriteBounceSpriteWidth 24 @define spriteBounceSize 128 @define spriteBarCenterOffset 10 spriteBounce : array[@spriteBounceSize] of integer = buildtable("300 - 300 * Math.abs( (i <= 64) ? Math.exp(5*((i/64)-1)) : (1 - ( Math.abs(Math.cos( ((i/64)+0.5) * 3.1415 )) / Math.pow((i/64),2) ) ) - ( (i/64) / 12 ) )") at $5b00; spriteBounceOfs : byte = 0; spriteBounceStartY : byte = 170; spriteBounceStartX : byte = 24; spriteBounceXCurrent : integer = 0; // Export all sprites automatically on each build @define spriteLocBounce0 $3d00 @define spriteLocBounce $0000 @export "resources/sprites/piraattilogo-hires.flf" "resources/sprites/piraattilogo-hires.bin" 0 bounceSpritesBank0:incbin("resources/sprites/piraattilogo-hires.bin", @spriteLocBounce0); bounceSpritesBank1:incbin("resources/sprites/piraattilogo-hires.bin", @spriteLocBounce + $4000); @define spriteLocCEquals0 $3f00 @define spriteLocCEquals $0200 @export "resources/sprites/c-equals-2x1-hires.flf" "resources/sprites/c-equals-2x1-hires.bin" 0 cEqualsSpritesBank0:incbin("resources/sprites/c-equals-2x1-hires.bin", @spriteLocCEquals0); cEqualsSpritesBank1:incbin("resources/sprites/c-equals-2x1-hires.bin", @spriteLocCEquals + $4000); @define spriteWobbleSize 256 spriteWobble : array[@spriteWobbleSize] of byte = buildtable("78 + 10 * ( ( (i <= 127) ? (i/128) : ((256-i)/128) ) * Math.sin(i/4) )"); spriteWobbleEasy : array[@spriteWobbleSize] of byte = buildtable("78 + 10 * ( ( (i <= 127) ? (i/128) : ((256-i)/128) ) * Math.sin(i/10) )"); spriteWobblePtr : pointer; spriteWobbleOfs : byte = 0; flagOrCequals : boolean = false; /* Screen fade variables */ @define textFadeLumiLast 21 textFadeLumi : array[] of byte = ($01, $01,$01, $01, $07, $07, $0d, $0d, $03, $03, $03, $03, $03, $0e, $0e, $0e, $0e, $0e, $0b, $0b, $00, $00); textFadeReverse : array[] of byte = ($0, $0, $0, $0, $0b, $0b, $0b, $0e, $0e, $0e, $03, $03, $03, $0d, $0d, $0d, $07, $07, $07, $01, $01, $01); @define fadeStateBorder 0 @define fadeStateText 1 @define fadeStateAll 2 fadeStateCurrent : byte = @fadeStateBorder; fadeOfsCurrent : byte = 0; fadeTemp : byte = 0; /* Main part */ @define mainpart_bitmapArea $6000 // <-- VIDEO BUFFER IS HERE!! @define piraattinaamat1_color $5200 @define piraattinaamat1_data $8000 @export "resources/images/piraattinaamat-1.flf" "resources/images/piraattinaamat-1.bin" 0 naamat1Color:incbin("resources/images/piraattinaamat-1_color.bin", @piraattinaamat1_color); naamat1Data:incbin("resources/images/piraattinaamat-1_data.bin", @piraattinaamat1_data); @define piraattinaamat2_color $f800 @define piraattinaamat2_data $a000 @export "resources/images/piraattinaamat-2.flf" "resources/images/piraattinaamat-2.bin" 0 naamat2Color:incbin("resources/images/piraattinaamat-2_color.bin", @piraattinaamat2_color); naamat2Data:incbin("resources/images/piraattinaamat-2_data.bin", @piraattinaamat2_data); @define naamaCoordEhdokas 0 @define naamaCoordStartX 1 @define naamaCoordStartY 2 @define naamaCoordWidth 3 @define naamaCoordHeight 4 naamatAddresses : array[] of integer = ( @piraattinaamat1_data, @piraattinaamat1_color, @piraattinaamat1_data, @piraattinaamat1_color, @piraattinaamat1_data, @piraattinaamat1_color, @piraattinaamat1_data, @piraattinaamat1_color, @piraattinaamat1_data, @piraattinaamat1_color, @piraattinaamat1_data, @piraattinaamat1_color, @piraattinaamat2_data, @piraattinaamat2_color, @piraattinaamat2_data, @piraattinaamat2_color, @piraattinaamat2_data, @piraattinaamat2_color, @piraattinaamat2_data, @piraattinaamat2_color, @piraattinaamat2_data, @piraattinaamat2_color, @piraattinaamat2_data, @piraattinaamat2_color); naamatCoordinates : array[] of byte = ( 0, 0, 13, 12, 13, 0, 13, 12, 26, 0, 13, 12, 0, 12, 13, 12, 13, 12, 13, 12, 26, 12, 13, 12, 0, 0, 13, 12, 13, 0, 13, 12, 26, 0, 13, 12, 0, 12, 13, 12, 13, 12, 13, 12, 26, 12, 13, 12); naamatNames : string = ( "TONI AITTONIEMI - UUSIMAA", @cpause, "JUHO KARVINEN - PIRKANMAA", @cpause, "RIIKKA NIEMINEN - UUSIMAA", @cpause, "JARI NIKKINEN - SAVO-KARJALA", @cpause, "SATU IMMONEN - HELSINKI", @cpause, "PEKKA MUSTONEN - HELSINKI", @cpause, "REETTA OJALA - HELSINKI", @cpause, "MAREK NETSHADA - HELSINKI", @cpause, "OLAVI KAUKAMIELI - HELSINKI", @cpause, "JONI MAHLAMAKI - UUSIMAA", @cpause, "KAUSTI RANTALAINEN - HELSINKI", @cpause, "ARI-PEKKA PULKKIS - VAASA", @cpause, @cstop ); naamatNumbers : string = ( "123", "456", "789", " 10", "20 ", " 30", " 40", "50 ", " 60", " 70", " 80", " 90", @cstop); tab320 : array[25] of integer = buildtable("i*320"); tab40 : array[25] of integer = buildtable("i*40"); @define numberSpriteCopies $5e00 numberSprite0loc : byte = @numberSpriteCopies / 64 + 0; numberSprite1loc : byte = @numberSpriteCopies / 64 + 1; numberSprite2loc : byte = @numberSpriteCopies / 64 + 2; numberSpriteCopyBlock : array[192] of byte = buildtable("0") at @numberSpriteCopies; numberSpriteFloatX : array[256] of byte = buildtable("Math.sin(i * (2 * 6.28 / 256)) * 7 + Math.cos(i * 6.28 / 256) * 20") at $5c00; numberSpriteFloatY : array[256] of byte = buildtable("Math.cos(i * (3 * 6.28 / 256)) * 5") at $5d00; numberSprite0FloatOfs : byte = 15; numberSprite1FloatOfs : byte = 30; numberSprite2FloatOfs : byte = 45; numberSprite3FloatOfs : byte = 0; numberSprite4FloatOfs : byte = 15; numberSprite5FloatOfs : byte = 30; @define mainPartBigFontLoc $4800 mainPartBigFont:incbin("resources/charsets/broadway_xy.bin", @mainPartBigFontLoc); @define numMainTextPages 6 mainText : string = ( @cmoveto, 0, 3, " COMMODORELLA", @cmoveto, 0, 4, " EDUSKUNTAAN", @cmoveto, 0, 5, " ---------", @cmoveto, 0, 6, " 2023", @cpage, @cmoveto, 0, 2, " RADIKAALISTI", @cmoveto, 0, 3, " AVOINTA", @cmoveto, 0, 4, " DEMOKRATIAA", @cmoveto, 0, 5, " VALTIONHALLINNON", @cmoveto, 0, 6, " LIVESTREAMAUS", @cmoveto, 0, 7, " LAHTOKOHTAISESTI", @cpage, @cmoveto, 0, 2, " LOBBAUS NAKYVAKSI", @cmoveto, 0, 3, "LAAJA JULKISUUSLAKI", @cmoveto, 0, 4, " KANSANAANESTYS", @cmoveto, 0, 5, " PERUSOIKEUDET", @cmoveto, 0, 6, "YKSITYISYYDENSUOJA", @cmoveto, 0, 7, " YHDENVERTAISUUS", @cpage, @cmoveto, 0, 2, " KESTAVYYSSIIRTYMA", @cmoveto, 0, 3, " VETYTALOUDEN", @cmoveto, 0, 4, " TEKNOLOGIATUKI", @cmoveto, 0, 5, "PAIKALLISDEMOKRATIA", @cmoveto, 0, 6, " LUONTO MAANKAYTTO", @cmoveto, 0, 7, " KESTAVYYS", @cpage, @cmoveto, 0, 3, "HYVINVOINTIALUEIDEN", @cmoveto, 0, 4, " VERONKANTO-OIKEUS", @cmoveto, 0, 5, " RAHANKERAYSLAIN", @cmoveto, 0, 6, " UUDISTUS", @cmoveto, 0, 7, " PERUSTULO", @cpage, @cmoveto, 0, 2, " TAVOITTEELLINEN", @cmoveto, 0, 3, " TUTKIMUS- JA", @cmoveto, 0, 4, " INNOVAATIO-", @cmoveto, 0, 5, " POLITIIKKA", @cmoveto, 0, 6, " TYOPERAINEN", @cmoveto, 0, 7, " MAAHANMUUTTO", @cpage, @cmoveto, 0, 2, " LAPINAKYVAT JA", @cmoveto, 0, 3, " TURVALLISET", @cmoveto, 0, 4, " JULKISET", @cmoveto, 0, 5, "TIETOJARJESTELMAT", @cmoveto, 0, 6, " OSTO-OSAAMISTA", @cmoveto, 0, 7, " YKSITYISTAMISEEN", @cpage, @cmoveto, 0, 3, " TIETOPOLITIIKAN", @cmoveto, 0, 4, " VAKIINNUTTAMINEN", @cmoveto, 0, 5, " OSAKSI HALLINTO-", @cmoveto, 0, 6, " RAKENNETTA", @cpage, @cstop); mainPartAddressTable : array[25] of integer; colorAddressTable : array[25] of integer; @define mainPartSmallFontLoc $5000 mainPartSmallFont:incbin("resources/charsets/cavelon.bin", @mainPartSmallFontLoc); naamatDataPtr, naamatColorPtr : pointer; numbersPtr, namesPtr : pointer; pictureFade, textFade, numbersFade, nameFade : integer = 0; currentNaama : byte = 0; rasterLineMainCandidateText : byte = 180; rasterLineMainScroller : byte = 240; // TODO optimize spaces scrollText : string = " YARRRR SAILORS WELCOME TO THE FINNISH PIRATE PARTY PARLIAMENTARY ELECTION 2023 INTRO --- VOTE FOR US --- WE ROCK THE WORLD IN 8 BITS AND BEYOND --- WRITTEN BY GIMLE IN TRSE --- MUSIC BY GIMLE WITH SIDFACTORY II --- MUCH LOVE AND GREETINGS TO THE C64 DEMOSCENE --- WE SALUTE SOME GROUNDBREAKING TECHNOLOGICAL PIRATES --- FINNISH GOLD - EXTEND - VIRTUAL DREAMS - FAIRLIGHT - BYTERAPERS - BLOODSUCKERS - ARTLINE DESIGNS - DEKADENCE - BOOZE DESIGN - ACCESSION - NOICE - PROXIMA - ORANGE - CNCD - KEWLERS - MFX - TPOLM - MATUREFURK - KATASTRO FI - SCOOPEX - TAAT - HEDELMAE - JUMALAUTA - KAITA FILMITUOTANTO - BRAINLEZ CODERS - SYMPTOM - GOTO 10 - DAMONES - DA JORMAS - WIDE LOAD - HIRMU - LEUAT "; scrollTextOffset : integer = 0; scrollTextLength : integer = 0; scrollCurrent : byte = 0; scrollFlashTimer : integer = 0; /* Music */ sidfile:incsid("resources/sid/piraattimusa.sid", 2); /* General flags */ @define useKernal 0 /* Spare pointers */ tempPtr1, tempPtr2 : pointer; tempInt : integer; /* Workloads for main loop */ @define notWorking 0 @define mainText 1 @define mainPicture 2 mainWorkState : byte = 0; //=========================================================================================================== // Raster interrupt forward declarations //=========================================================================================================== interrupt MainRaster(); interrupt RasterText(); interrupt RasterTextPlasma(); interrupt RasterPurpleBarStart(); interrupt RasterPurpleBarEnd(); interrupt RasterPurpleBarStartWithSprites(); interrupt RasterMainPartCandidateTexts(); interrupt RasterMainPartScroller(); procedure GoToMainRaster(); begin RasterIrq(MainRaster(), 250, @useKernal); end; procedure GoToPurpleBarRasterStart(); begin if (currentPart < @partLogoBarWobble) then RasterIrq(RasterPurpleBarStart(), purpleBarStartRasterLine, @useKernal) else RasterIrq(RasterPurpleBarStartWithSprites(), purpleBarStartRasterLine, @useKernal); end; procedure GoToPurpleBarRasterEnd() inline; begin RasterIrq(RasterPurpleBarEnd(), purpleBarEndRasterLine, @useKernal); end; procedure GoToMainPartCandidateTextRaster(); begin RasterIrq(RasterMainPartCandidateTexts(), rasterLineMainCandidateText, @useKernal); end; procedure GoToMainPartScrollerRaster(); begin RasterIrq(RasterMainPartScroller(), rasterLineMainScroller, @useKernal); end; //=========================================================================================================== // Main Work state functions //=========================================================================================================== function isMainWorking() : boolean; var result : boolean; begin if (mainWorkState = @notWorking) then result := false else result := true; isMainWorking := result; end; procedure startMainWork(s : byte); begin mainWorkState := s; end; /** * Assembly setup for a character set copy in RAM */ procedure CopyCharsetRomToRam(targetHi : byte); begin asm(" ldx #$08 ; we loop 8 times (8x255 = 2Kb) lda #$33 ; make the CPU see the Character Generator ROM... sta $01 ; ...at $D000 by storing %00110011 into location $01 lda #$d0 ; load high byte of $D000 sta $fc ; store it in a free location we use as vector ldy #$00 ; init counter with 0 sty $fb ; store it as low byte in the $FB/$FC vector lda $fd ; second pair in $FD/$FE lda targetHi ; point to target sta $fe loopc lda ($fb),y ; read byte from vector stored in $fb/$fc sta ($fd),y ; write to the RAM iny ; do this 255 times... bne loopc ; ..for low byte $00 to $FF inc $fc ; when we passed $FF increase high byte... inc $fe dex ; ... and decrease X by one before restart bne loopc ; We repeat this until X becomes Zero lda #$37 ; switch in I/O mapped registers again... sta $01 ; ... with %00110111 so CPU can see them "); end; /** * Print character set char to sprite data (hires) * Triple each bit in char both vertical and horizontal */ procedure PrintCharToSprite(char:byte, charsetptr, sPtr:pointer); var chrBitMask : array[] of byte = ($01, $02, $04, $08, $10, $20, $40, $80); sprBitMask : array[] of byte = ($07, $38, $c0, $01, $0e, $70, $80, $03, $1c, $e0); sprOffset : array[] of byte = ($02, $02, $02, $01, $01, $01, $01, $00, $00, $00); sprChrBit : array[] of byte = ($00, $01, $02, $02, $03, $04, $05, $05, $06, $07); numLines : array[] of byte = (3, 3, 3, 3, 3, 3, 3, 3); numLines2 : array[] of byte = (2, 3, 3, 2, 3, 3, 3, 2); numLinesPtr : pointer; temp : array[] of byte = (0,0,0); charTemp, sprOfsTemp : byte; k : byte; begin while (char > 64) do char -= 64; tempPtr1 := charsetptr + char * 8; for k:=0 to 8 do begin temp[0] := 0; temp[1] := 0; temp[2] := 0; for i:=0 to 10 do begin charTemp := tempPtr1[0] & chrBitMask[sprChrBit[i]]; sprOfsTemp := sprOffset[i]; if charTemp then temp[sprOfsTemp] := temp[sprOfsTemp] | sprBitMask[i]; end; for i:=0 to numLinesPtr[k] do begin sPtr[0] := temp[0]; sPtr[1] := temp[1]; sPtr[2] := temp[2]; sPtr += 3; end; tempPtr1 += 1; end; end; procedure PrintDebug(cx, cy, n : byte); begin tempPtr1 := screenmemory; moveto(cx,cy,hi(screen_char_loc)); printnumber(n); screenmemory := tempPtr1; end; procedure UpdateText(); procedure UpdateTextColor() inline; begin for i:=0 to 5 do begin tempPtr1:=sp-i; tempPtr1[0]:=textPlasmaLumi[4+i]; end; end; procedure UpdateTextPlasma(); var iy, ix : byte; begin for iy := textPlStartY to textPlEndY do begin tempPtr1 := #screen_col_loc + tab40[iy]; tempPtr2 := #fastPlasma + textPlOfsX + iy; memcpyfast(tempPtr2, 0, tempPtr1, 40); end; inc(textPlOfsX); if (textPlOfsX > 230) then textPlOfsX := 0; // don't go over end; procedure TransformCharToSpriteLoc(x, y:byte); begin spriteX := (x * 8) + 24; spriteY := (y * 8) + 50; spriteX += lookup3Dx[x] * curWait; spriteY += lookup3Dy[y] * curWait; if (bigSprite) then begin spriteX -= 24; spriteY -= 21; end else begin spriteX -= 12; spriteY -= 9; end; end; /* Updates and prints text on screen */ procedure UpdateText(); var j : byte; begin if (curWait) then begin if (onPause) then begin sp:=sp+1; UpdateTextColor(); end else if (tp[0] < @cpause) then begin if (curWait > (@betweencharpause / 2)) then bigSprite := true else bigSprite := false; TransformCharToSpriteLoc(textX, textY); SpritePos(spriteX, spriteY, 0); sprite_color[0] := flightColFade[curWait]; if (bigSprite) then begin togglebit(sprite_stretch_x, 0, 1); togglebit(sprite_stretch_y, 0, 1); end else begin togglebit(sprite_stretch_x, 0, 0); togglebit(sprite_stretch_y, 0, 0); end; end; dec(curWait); return(); end; // Moveto if (tp[0]=@cmoveto) then begin textX:=tp[1]; textY:=tp[2]; moveto(tp[1], tp[2], hi(screen_col_loc)); sp:=screenmemory; moveto(tp[1], tp[2], hi(screen_char_loc)); tp:=tp+3; onPause:=false; return(); end; // Pause if (tp[0]=@cpause) then begin curWait:=tp[1]; tp:=tp+2; onPause:=true; return(); end; // Stop - jump to next IRQ if (tp[0]=@cstop) then begin // jump to next part here currentPartDone := true; return(); end; // Render text j:=tp[0]; // Subtract 64 if (j>64) then j:=j-64; screenmemory[0]:=j; UpdateTextColor(); if (j <> KEY_SPACE) then begin PlaySound(sid_channel1, 10, // Volume Random()/128 + 5, // Hi byte frequency 0*16+0, // Attack voice 1 15*16 + 3, // Sustain = 16*15 + release=6 1 +sid_noise, // Waveform sid_noise); // waveform PlaySound(sid_channel2, 13, // Volume 6, // Hi byte frequency 0*16+0, // Attack voice 1 4*16 + 3, // Sustain = 16*15 + release=6 1 + sid_tri, // Waveform sid_tri); // waveform end; // Increase tex,color and screen pointers tp:=tp+1; sp:=sp+1; screenmemory:=screenmemory+1; curWait:=@betweencharpause; textX:=textX+1; // print next char on sprite if (j <> charOnSprite0) then PrintCharToSprite(j, @charSetCopyLoc, @spriteLoc); // PrintDebug(0, 24, textX); // PrintDebug(3, 24, textY); end; /** * Write 2x2 text on screen (vic bank 1) * * input: * tp : pointer - text * */ procedure WriteMainText(); // TODO write in parts to fit in frame begin sp := #screen_char_loc2; while (tp[0] <> @cpage) do begin if (tp[0] = @cmoveto) then begin x := tp[1] * 2 + 1; y := tp[2] * 3 - 1; sp := AddressTable(#mainPartAddressTable, x, y); tp += 3; end else begin j := tp[0]; if (j = KEY_SPACE) then j := 0; if (j > 64) then j := j - 64; k := j * 4; // k contains character start sp[0] := k; sp[1] := k+1; sp[40] := k+2; sp[41] := k+3; tp += 1; sp += 2; end; end; tp += 1; end; /** * Write 1x1 text in bottom of main screen * input: * namesPtr : pointer - text */ procedure WriteMainName(); begin sp := AddressTable(#mainPartAddressTable, 8, 21); while (namesPtr[0] <> @cpause) do begin j := namesPtr[0]; if (j = KEY_SPACE) then j := 0; if (j > 64) then j := j - 64; sp[0] := j; namesPtr += 1; x += 1; sp += 1; end; namesPtr += 1; end; /** * Write scroll text at offset */ procedure WriteScrollText() inline; begin tempPtr1 := #scrollText + scrollTextOffset; memcpyunroll(tempPtr1,0,^$47c0,40); end; /** * Subtract 64 from the ASCII text */ procedure PreProcessScrollText(); var temps : integer; begin tempPtr1 := #scrollText; while (tempPtr1[0] <> 0) do begin j := tempPtr1[0]; if (j > 64) then j -= 64; tempPtr1[0] := j; tempPtr1 += 1; end; end; /** * Copies a rectangle of one bitmap + color data to another, assumes width of both to be 320/160 pixels / 40 chars * * input: * naamatDataPtr : pointer - bitmap data * naamatColorPtr : pointer - color data */ procedure CopyNaamatBitmapData(fromX, fromY, toX, toY, width, height : byte, colordatasize : integer); begin // copy bitmap data tempPtr1 := naamatDataPtr; tempPtr2 := @mainpart_bitmapArea; tempPtr1 += tab320[fromY]; // 40 * 8 bytes on a single row of characters tempPtr2 += tab320[toY]; tempPtr1 += fromX * 8; tempPtr2 += toX * 8; j := width * 8; // never call this with width >= 32 !! for i := 0 to height do begin memcpy(tempPtr1, 0, tempPtr2, j); tempPtr1 += 320; tempPtr2 += 320; end; // copy color data #1 tempPtr1 := naamatColorPtr + 2; // skip bg & fg colors and go directly to color data tempPtr2 := #screen_char_loc2; tempPtr1 += fromY * 40 + fromX; tempPtr2 += toY * 40 + toX; for i := 0 to height do begin memcpyfast(tempPtr1, 0, tempPtr2, width); tempPtr1 += 40; tempPtr2 += 40; end; // copy color data #2 tempPtr1 := naamatColorPtr + 2 + colordatasize; // skip bg & fg colors and go directly to second color data tempPtr2 := #screen_col_loc; tempPtr1 += fromY * 40 + fromX; tempPtr2 += toY * 40 + toX; for i := 0 to height do begin memcpyfast(tempPtr1, 0, tempPtr2, width); tempPtr1 += 40; tempPtr2 += 40; end; end; /** * Fill rectangle in bitmap mode with black */ procedure BlankNaamatBitmapData(fromX2, fromY2, toX2, toY2, width2, height2 : byte); begin // bitmap data tempPtr2 := @mainpart_bitmapArea; tempPtr2 += tab320[toY]; tempPtr2 += toX2 * 8; j := width2 * 8; // never call this with width >= 32 !! for i := 0 to height2 do begin fill(tempPtr2, 0, j); tempPtr2 += 320; end; // color data #1 tempPtr2 := #screen_char_loc2; tempPtr2 += toY2 * 40 + toX2; for i := 0 to height2 do begin fillfast(tempPtr2, 0, width2); tempPtr2 += 40; end; // color data #2 tempPtr2 := #screen_col_loc; tempPtr2 += toY2 * 40 + toX2; for i := 0 to height2 do begin fillfast(tempPtr2, 0, width2); tempPtr2 += 40; end; end; //=========================================================================================================== // Sprite initializers //=========================================================================================================== procedure UpdateSpriteBouncePositions(); // TODO get rid of this method begin SpritePos(spriteBounceXCurrent + 0, spriteBounceStartY, 0); SpritePos(spriteBounceXCurrent + @spriteBounceSpriteWidth, spriteBounceStartY, 1); SpritePos(spriteBounceXCurrent + @spriteBounceSpriteWidth * 2, spriteBounceStartY, 2); SpritePos(spriteBounceXCurrent + @spriteBounceSpriteWidth * 3, spriteBounceStartY, 3); SpritePos(spriteBounceXCurrent + @spriteBounceSpriteWidth * 4, spriteBounceStartY, 4); SpritePos(spriteBounceXCurrent + @spriteBounceSpriteWidth * 5, spriteBounceStartY, 5); SpritePos(spriteBounceXCurrent + @spriteBounceSpriteWidth * 6, spriteBounceStartY, 6); SpritePos(spriteBounceXCurrent + @spriteBounceSpriteWidth * 7, spriteBounceStartY, 7); end; procedure UpdateSpriteXLSBPositions(posx:byte); begin poke(SPRITE_POS, 0, posx); poke(SPRITE_POS, 2, posx + 24); poke(SPRITE_POS, 4, posx + 48); poke(SPRITE_POS, 6, posx + 72); poke(SPRITE_POS, 8, posx + 96); poke(SPRITE_POS, 10, posx + 120); poke(SPRITE_POS, 12, posx + 144); poke(SPRITE_POS, 14, posx + 168); end; procedure UpdateSpriteYPositions(posy:byte); begin poke(SPRITE_POS, 1, posy); poke(SPRITE_POS, 3, posy); poke(SPRITE_POS, 5, posy); poke(SPRITE_POS, 7, posy); poke(SPRITE_POS, 9, posy); poke(SPRITE_POS, 11, posy); poke(SPRITE_POS, 13, posy); poke(SPRITE_POS, 15, posy); end; procedure InitSpriteWriter(); begin sprite_multicolor:=$00; sprite_color[0]:=$00; sprite_stretch_x:=$ff; sprite_stretch_y:=$ff; togglebit(sprite_bitmask,0,1); SetSpriteLoc(0, @spriteLoc/64, @spriteBank); end; procedure InitLogoBounceSprites(); begin sprite_multicolor:=$00; sprite_color[0]:=$01; sprite_color[1]:=$01; sprite_color[2]:=$01; sprite_color[3]:=$01; sprite_color[4]:=$01; sprite_color[5]:=$01; sprite_color[6]:=$01; sprite_color[7]:=$01; sprite_stretch_x:=$0; sprite_stretch_y:=$0; sprite_bitmask := $ff; //sprite_multicolor_reg1:=$0c; //sprite_multicolor_reg2:=$01; //SetSpriteLoc(0, @spriteLocCEquals/64, @spriteBank); SetSpriteLoc(0, (@spriteLocBounce0)/64, @spriteBank); SetSpriteLoc(1, (@spriteLocBounce0)/64 + 1, @spriteBank); SetSpriteLoc(2, (@spriteLocBounce0)/64 + 2, @spriteBank); SetSpriteLoc(3, (@spriteLocBounce0)/64 + 3, @spriteBank); SetSpriteLoc(4, (@spriteLocBounce0)/64 + 4, @spriteBank); SetSpriteLoc(5, (@spriteLocBounce0)/64 + 5, @spriteBank); SetSpriteLoc(6, (@spriteLocBounce0)/64 + 6, @spriteBank); SetSpriteLoc(7, (@spriteLocBounce0)/64 + 7, @spriteBank); end; procedure InitLogoBounceSprites1(); begin sprite_multicolor:=$00; sprite_color[0]:=$01; sprite_color[1]:=$01; sprite_color[2]:=$01; sprite_color[3]:=$01; sprite_color[4]:=$01; sprite_color[5]:=$01; sprite_color[6]:=$01; sprite_color[7]:=$01; sprite_stretch_x:=$0; sprite_stretch_y:=$0; sprite_bitmask := $ff; //sprite_multicolor_reg1:=$00; //sprite_multicolor_reg2:=$00; if (flagOrCequals) then SetSpriteLoc(0, @spriteLocCEquals/64 + $4000, 1) else SetSpriteLoc(0, (@spriteLocBounce + $4000)/64, 1); SetSpriteLoc(1, (@spriteLocBounce + $4000)/64 + 1, 1); SetSpriteLoc(2, (@spriteLocBounce + $4000)/64 + 2, 1); SetSpriteLoc(3, (@spriteLocBounce + $4000)/64 + 3, 1); SetSpriteLoc(4, (@spriteLocBounce + $4000)/64 + 4, 1); SetSpriteLoc(5, (@spriteLocBounce + $4000)/64 + 5, 1); SetSpriteLoc(6, (@spriteLocBounce + $4000)/64 + 6, 1); SetSpriteLoc(7, (@spriteLocBounce + $4000)/64 + 7, 1); end; procedure InitVoteNumberSprites1(); begin sprite_multicolor:=$00; sprite_stretch_x:=$7f; sprite_stretch_y:=0; sprite_bitmask:=$7f; SetSpriteLoc(0, numberSprite0loc, 1); SetSpriteLoc(1, numberSprite1loc, 1); SetSpriteLoc(2, numberSprite2loc, 1); SetSpriteLoc(3, numberSprite0loc, 1); SetSpriteLoc(4, numberSprite1loc, 1); SetSpriteLoc(5, numberSprite2loc, 1); SpritePos(110 + numberSpriteFloatX[numberSprite0FloatOfs], 188 + numberSpriteFloatY[numberSprite0FloatOfs], 0); SpritePos(160 + numberSpriteFloatX[numberSprite1FloatOfs], 188 + numberSpriteFloatY[numberSprite1FloatOfs], 1); SpritePos(210 + numberSpriteFloatX[numberSprite2FloatOfs], 188 + numberSpriteFloatY[numberSprite2FloatOfs], 2); SpritePos(110 + numberSpriteFloatX[numberSprite3FloatOfs], 188 + numberSpriteFloatY[numberSprite3FloatOfs], 3); SpritePos(160 + numberSpriteFloatX[numberSprite4FloatOfs], 188 + numberSpriteFloatY[numberSprite4FloatOfs], 4); SpritePos(210 + numberSpriteFloatX[numberSprite5FloatOfs], 188 + numberSpriteFloatY[numberSprite5FloatOfs], 5); end; procedure ChangeFlagToCEquals(); begin if (flagOrCequals) then SetSpriteLoc(0, @spriteLocBounce0/64, @spriteBank) else SetSpriteLoc(0, @spriteLocCEquals0/64, @spriteBank); flagOrCequals := not(flagOrCequals); end; procedure ChangeFlagToCEquals1(); begin if (flagOrCequals) then SetSpriteLoc(0, @spriteLocBounce/64, 1) else SetSpriteLoc(0, @spriteLocCEquals/64, 1); flagOrCequals := not(flagOrCequals); end; //=========================================================================================================== // Raster interrupts //=========================================================================================================== procedure UpdateMainPart(); interrupt RasterTextPlasma(); begin startirq(@useKernal); //screen_bg_col := red; UpdateTextPlasma(); //screen_bg_col := bgColBefore; GoToPurpleBarRasterStart(); closeirq(); end; interrupt RasterText(); begin startIRQ(@useKernal); UpdateText(); closeIRQ(); GoToMainRaster(); end; interrupt RasterPurpleBarStart(); begin StartIRQ(@useKernal); nop(14); screen_bg_col := purple; screen_fg_col := purple; GoToPurpleBarRasterEnd(); CloseIRQ(); end; interrupt RasterPurpleBarStartWithSprites(); begin StartIRQ(@useKernal); poke(^$39, 0, lo(spriteWobblePtr)); poke(^$3a, 0, hi(spriteWobblePtr)); nop(13); screen_bg_col := purple; screen_fg_col := purple; asm(" ldy spriteWobbleOfs ldx #21 sprLoop lda ($39),y sta $d000 adc #24 sta $d002 adc #24 sta $d004 adc #24 sta $d006 adc #24 sta $d008 adc #24 sta $d00a adc #24 sta $d00c adc #24 sta $d00e iny dex bne sprLoop "); GoToPurpleBarRasterEnd(); CloseIRQ(); end; interrupt RasterPurpleBarEnd(); begin StartIRQ(@useKernal); nop(13); screen_bg_col := bgColBefore; screen_fg_col := fgColBefore; if (currentPart >= @partMain) then begin if (mainState = @mainPicture or mainState = @mainFadeToText) then begin GoToMainPartCandidateTextRaster(); setmulticolormode(); setbitmapmode(); setcharsetlocation(@mainpart_bitmapArea); InitVoteNumberSprites1(); end else begin settextmode(); setregularcolormode(); setcharsetlocation(@mainPartBigFontLoc); GoToMainPartScrollerRaster(); end; UpdateMainPart(); end else GoToMainRaster(); CloseIRQ(); end; interrupt RasterMainPartCandidateTexts(); begin StartIRQ(@useKernal); setregularcolormode(); settextmode(); setcharsetlocation(@mainPartSmallFontLoc); GoToMainPartScrollerRaster(); CloseIRQ(); end; interrupt RasterMainPartScroller(); begin StartIRQ(@useKernal); scrollx(scrollCurrent); setcharsetlocation(@mainPartSmallFontLoc); GoToMainRaster(); CloseIRQ(); end; //=========================================================================================================== // Demo part handlers //=========================================================================================================== procedure InitMainPart(); procedure InitPart(part : byte); begin if (part = @partWriter) then begin tp:=#text; InitSpriteWriter(); numLinesPtr := #numLines; end; if (part = @partOpenBar) then begin bgColBefore := screen_bg_col; fgColBefore := screen_fg_col; InitSID(SIDFILE_1_INIT); end; if (part = @partSpriteBounce) then InitLogoBounceSprites(); if (part = @partLogoBarWobble) then begin spriteWobblePtr := #spriteWobble; spriteWobbleOfs := 245; end; if (part = @partBounceBarUp) then begin purpleBounceOfs := 0; spriteBounceOfs := 0; spriteWobbleOfs := 245; end; if (part = @partMain) then begin screen_bg_col := 0; screen_fg_col := 0; bgColBefore := 0; fgColBefore := 0; spriteBounceOfs := 0; purpleBarStartRasterLine := 60 - 17; purpleBarEndRasterLine := 60 + 17; spriteWobblePtr := #spriteWobbleEasy; spriteBounceStartY := 60 - @spriteBarCenterOffset; InitLogoBounceSprites1(); UpdateSpriteYPositions(spriteBounceStartY); UpdateSpriteXLSBPositions(spriteWobble[0]); clearscreen(0, screen_col_loc); setmulticolormode(); setbitmapmode(); setcharsetlocation(@mainpart_bitmapArea); setbank(vic_bank1); tp := #mainText; naamatDataPtr := naamatAddresses[0]; naamatColorPtr := naamatAddresses[1]; namesPtr := #naamatNames; numbersPtr := #naamatNumbers; currentNaama := 0; mainState := @mainPicture; mainTime := 0; scrollTextLength := length(scrollText); numLinesPtr := #numLines2; hideborderx(1); // avoid choppy scroll InitMainPart(); end; end; procedure InitMainPart(); var currentNaamaX, currentNaamaY, currentNaamaWidth, currentNaamaHeight : byte; plasmaHeight : byte; begin // Always reset pictureFade := 0; textFade := 0; numbersFade := 0; nameFade := 0; if (mainState = @mainShowText) then begin startMainWork(@mainText); end; if (mainState = @mainPicture) then begin startMainWork(@mainPicture); end; end; procedure UpdateMainPart(); begin if (mainState = @mainShowText and not isMainWorking()) then begin textPlStartX := 0; i := lo(textFade); j := fastPlasmaSweep[i]; textPlStartY := 4 + j; textPlEndX := 40; textPlEndY := textPlStartY + plasmaHeight; UpdateTextPlasma(); inc(textFade); if (mod(textFade, 10) = 0) then inc(plasmaHeight); if (plasmaHeight > 9) then plasmaHeight := 9; end; if (mainState = @mainFadeToPicture and textFade < 210) then begin i := lo(textFade); j := fastPlasmaSweep[i]; textPlStartY := 4 + textFade / 10; if (textPlStartY > 21) then textPlStartY := 21; textPlEndY := textPlStartY + plasmaHeight; if (textPlEndY > 22) then textPlEndY := 22; if (textPlStartY > textPlEndY) then textPlStartY := textPlEndY; if (mainTime < 180) then UpdateTextPlasma(); tempPtr1 := #screen_col_loc + textFade * 4 + 100; memcpyfast(#textFadeReverse, 0, tempPtr1, 20); tempPtr1 := #screen_char_loc2 + textFade * 4 + 96; fillfast(tempPtr1, 0, 4); // clear character memory inc(textFade); end; if (mainState = @mainPicture) then if (isMainWorking()) then begin sprite_color[0]:=0; sprite_color[1]:=0; sprite_color[2]:=0; sprite_color[3]:=0; sprite_color[4]:=0; sprite_color[5]:=0; end else begin // copy picture one row at a time if (pictureFade < currentNaamaHeight) then begin CopyNaamatBitmapData(currentNaamaX, currentNaamaY + pictureFade, 13, 4 + pictureFade, currentNaamaWidth, 1, 1000); inc(pictureFade); end; // fade in the sprite colors if (mainTime > 100) then begin if (numbersFade < @textFadeLumiLast) then begin j := textFadeReverse[numbersFade]; sprite_color[0]:=j; sprite_color[1]:=j; sprite_color[2]:=j; inc(numbersFade); end else begin sprite_color[0]:=1; sprite_color[1]:=1; sprite_color[2]:=1; sprite_color[3]:=$0b; sprite_color[4]:=$0b; sprite_color[5]:=$0b; end end else fillfast(#sprite_color, 0, 6); if (nameFade < 85) then begin tempPtr1 := #screen_col_loc + 800 + nameFade; // starts at row 20 memcpyfast(#textFadeLumi, 0, tempPtr1, 20); inc(nameFade); end; if (mainTime > 350 and mainTime < 425) then begin i := mainTime - 350; tempPtr1 := #screen_col_loc + 800 + i; // starts at row 20 memcpyfast(#textFadeLumi, 0, tempPtr1, 20); end; end; if (mainState = @mainFadeToText) then begin // blank out picture one row at a time if (pictureFade < currentNaamaHeight) then begin BlankNaamatBitmapData(currentNaamaX, currentNaamaY + pictureFade, 13, 4 + pictureFade, currentNaamaWidth, 1); inc(pictureFade); end; // fade out the sprite colors if (numbersFade < @textFadeLumiLast) then begin j := textFadeLumi[numbersFade]; sprite_color[0]:=j; sprite_color[1]:=j; sprite_color[2]:=j; sprite_color[3]:=$0; sprite_color[4]:=$0; sprite_color[5]:=$0; inc(numbersFade); end else begin sprite_color[0]:=0; sprite_color[1]:=0; sprite_color[2]:=0; sprite_color[3]:=0; sprite_color[4]:=0; sprite_color[5]:=0; end; if (mainTime > 50 and nameFade < 150) then begin tempPtr1 := #screen_col_loc + 840 + nameFade; // starts at row 21 memcpyfast(#textFadeReverse, 0, tempPtr1, 20); inc(nameFade); end; end; if (currentTime > 512 and mod(mainTime, 2) = 0)then begin if (scrollCurrent = 0) then begin inc(scrollTextOffset); if (scrollTextOffset > scrollTextLength - 39) then scrollTextOffset := 0; WriteScrollText(); scrollCurrent := 7; end; dec(scrollCurrent); end; end; procedure GoToNextMainPart(); begin mainTime := 0; mainState := mod(mainState + 1, 4); if (mainState = @mainPicture) then begin currentNaama := mod(currentNaama + 1, 12); naamatDataPtr := naamatAddresses[currentNaama * 2]; naamatColorPtr := naamatAddresses[currentNaama * 2 + 1]; end; InitMainPart(); end; procedure UpdateCurrentRaster(); var lastSpriteWoblOfs : byte; wobblePause : boolean = false; wobblePauseTimer : integer = 0; cEqualsChangeFlag : boolean = false; fillPart : byte = 0; begin if (part >= @partOpenBar) then Call(SIDFILE_1_PLAY); if (part = @partWriter) then RasterIRQ(RasterText(),0, @useKernal); if (part = @partOpenBar) then begin purpleBarStartRasterLine := purpleBarCenter - purpleBarBounce[purpleBounceOfs]; purpleBarEndRasterLine := purpleBarCenter + purpleBarBounce[purpleBounceOfs] + 1; RasterIRQ(RasterTextPlasma(), 0, @useKernal); inc(purpleBounceOfs); if (purpleBounceOfs = 10) then FillFast(screen_char_loc + 640, KEY_SPACE, 40); if (purpleBounceOfs = 50) then FillFast(screen_char_loc + 600, KEY_SPACE, 40); if (purpleBounceOfs = 50) then FillFast(screen_char_loc + 680, KEY_SPACE, 40); if (purpleBounceOfs = 120) then FillFast(screen_char_loc + 560, KEY_SPACE, 40); if (purpleBounceOfs = 120) then FillFast(screen_char_loc + 720, KEY_SPACE, 40); if (purpleBounceOfs >= @purpleBarBounceSize) then currentPartDone := true; end; if (part = @partSpriteBounce) then begin spriteBounceXCurrent := spriteBounceStartX + spriteBounce[spriteBounceOfs]; UpdateSpriteBouncePositions(); RasterIRQ(RasterTextPlasma(), 0, @useKernal); if (spriteBounceOfs < @spriteBounceSize - 1) then spriteBounceOfs += 1; if (currentTime > 240) then currentPartDone := true; end; if (part = @partFadeOutOpeningScreen) then begin if (fadeStateCurrent = @fadeStateBorder) then begin bgColBefore := textFadeLumi[fadeOfsCurrent]; screen_bg_col := bgColBefore; RasterIRQ(RasterTextPlasma(), 0, @useKernal); if (fadeOfsCurrent >= @textFadeLumiLast) then begin fadeStateCurrent := @fadeStateText; fadeOfsCurrent := 0; end; end; if (fadeStateCurrent = @fadeStateText) then begin fadeTemp := textFadeLumi[fadeOfsCurrent]; if (fillPart = 0) then begin Fill(screen_col_loc, fadeTemp, 255); FillFast(screen_col_loc + 256, fadeTemp, 127); fadeOfsCurrent -= 1; end; if (fillPart = 1) then begin Fill(screen_col_loc + 511, fadeTemp, 255); Fill(screen_col_loc + 766, fadeTemp, 234); end; GoToPurpleBarRasterStart(); if (fadeOfsCurrent >= @textFadeLumiLast) then begin fadeStateCurrent := @fadeStateAll; fadeOfsCurrent := 0; end; inc(fillPart); if (fillPart = 2) then fillPart := 0; end; if (fadeStateCurrent = @fadeStateAll) then begin fgColBefore := 0; Fill(screen_char_loc, KEY_SPACE, 255); FillFast(screen_char_loc + 256, KEY_SPACE, 127); GoToPurpleBarRasterStart(); currentPartDone := true; screen_fg_col := 0; end; fadeOfsCurrent += 1; end; if (part = @partLogoBarWobble) then begin fadeTemp := textLumi2[textBlinkOfs]; FillFast(screen_col_loc + 406 , fadeTemp, 30); FillFast(screen_col_loc + 486 , fadeTemp, 30); inc(textBlinkOfs); if (textBlinkOfs > 16) then textBlinkOfs := 0; if (currentTime > 150) then begin if (lastSpriteWoblOfs = 127 and spriteWobbleOfs = 128) then ChangeFlagToCEquals(); lastSpriteWoblOfs := spriteWobbleOfs; if (currentTime > 645) then currentPartDone := true; inc(spriteWobbleOfs); end; GoToPurpleBarRasterStart(); end; if (part = @partBounceBarUp) then begin purpleBarCenter := purpleBarBounce2[purpleBounceOfs]; purpleBarStartRasterLine := purpleBarCenter - @purpleBarCenterOffset; purpleBarEndRasterLine := purpleBarCenter + @purpleBarCenterOffset; spriteBounceStartY := purpleBarCenter - @spriteBarCenterOffset; UpdateSpriteYPositions(spriteBounceStartY); if (currentTime = 5) then FillFast(^$05e0, KEY_SPACE, 40); if (currentTime = 8) then FillFast(^$0590, KEY_SPACE, 40); inc(purpleBounceOfs); if (purpleBounceOfs > 127) then currentPartDone := true; GoToPurpleBarRasterStart(); end; if (part = @partMain) then begin setbank(vic_bank1); if (not(wobblePause)) then begin inc(spriteWobbleOfs); if (lastSpriteWoblOfs = 127 and spriteWobbleOfs = 128) then begin if (cEqualsChangeFlag) then ChangeFlagToCEquals1(); cEqualsChangeFlag := not(cEqualsChangeFlag); end; end; lastSpriteWoblOfs := spriteWobbleOfs; inc(wobblePauseTimer); if (wobblePauseTimer > 512) then begin wobblePause := not(wobblePause); wobblePauseTimer := 0; spriteWobbleOfs := 245; end; InitLogoBounceSprites1(); UpdateSpriteYPositions(spriteBounceStartY); UpdateSpriteXLSBPositions(spriteWobble[0]); inc(numberSprite0FloatOfs); inc(numberSprite1FloatOfs); inc(numberSprite2FloatOfs); inc(numberSprite3FloatOfs); inc(numberSprite4FloatOfs); inc(numberSprite5FloatOfs); inc(mainTime); if (mainState = @mainFadeToPicture and mainTime > 200) then GoToNextMainPart(); if (mainState = @mainFadeToText and mainTime > 100) then GoToNextMainPart(); if (mainState = @mainPicture and mainTime > 650) then GoToNextMainPart(); if (mainState = @mainShowText and mainTime > 500) then GoToNextMainPart(); GoToPurpleBarRasterStart(); end; end; procedure GoToNextPart(); begin inc(currentPart); currentPartDone := false; currentTime := 0; InitPart(currentPart); // poke(^$3fff, 0, currentPart); // debug end; interrupt MainRaster(); begin StartIRQ(@useKernal); // bgColBefore := screen_bg_col; // screen_bg_col := white; if (currentPartDone) then GoToNextPart(); scrollx(0); UpdateCurrentRaster(); inc(currentTime); // screen_bg_col := bgColBefore; CloseIRQ(); end; begin bgColBefore := screen_bg_col; fgColBefore := screen_fg_col; DisableCIAInterrupts(); CopyCharSetFromRom(^$c000); setmemoryconfig(1,@useKernal,0); // Some heavy part init here to spare work later ClearScreen(0, screen_char_loc2); ClearScreen(0, ^@mainpart_bitmapArea); ClearScreen(0, ^@mainpart_bitmapArea + 1000); ClearScreen(0, ^@mainpart_bitmapArea + 2000); ClearScreen(0, ^@mainpart_bitmapArea + 3000); ClearScreen(0, ^@mainpart_bitmapArea + 4000); ClearScreen(0, ^@mainpart_bitmapArea + 5000); ClearScreen(0, ^@mainpart_bitmapArea + 6000); ClearScreen(0, ^@mainpart_bitmapArea + 7000); CreateAddressTable(#mainPartAddressTable, $4400, 40, 25); CreateAddressTable(#colorAddressTable, $d800, 40, 25); Fill(^$0528, KEY_SPACE, 240); for i := 0 to 256 do fastPlasma[i] := textPlasmaLumi[textPlasmaX[i]]; PreProcessScrollText(); // Start demo GoToMainRaster(); EnableRasterIRQ(); enableirq(); while (true) do begin // Heavy main loop work tasks here if (mainWorkState = @mainText) then begin //tempPtr1 := #screen_char_loc2 + 840; Fill(^$4740, 0, 80); //tempPtr1 := #screen_col_loc + 800; FillFast(^$DB20, 0, 80); WriteMainText(); if (tp[0] = @cstop) then tp := #mainText; // back to first page when done //tempPtr2 := #screen_col_loc + 960; // keep color for scroll text fillfast(^$DBC0, $a, 40); mainWorkState := @notWorking; end; if (mainWorkState = @mainPicture) then begin //tempPtr1 := AddressTable(#colorAddressTable, 0, 21); FillFast(^$4748, 0, 120); //tempPtr2 := #screen_col_loc + 960; // keep color for scroll text fillfast(^$DBC0, $a, 40); // set current picture currentNaamaX := naamatCoordinates[currentNaama * 4]; currentNaamaY := naamatCoordinates[currentNaama * 4 + 1]; currentNaamaWidth := naamatCoordinates[currentNaama * 4 + 2]; currentNaamaHeight := naamatCoordinates[currentNaama * 4 + 3]; PrintCharToSprite(numbersPtr[0], @mainPartSmallFontLoc, @numberSpriteCopies); PrintCharToSprite(numbersPtr[1], @mainPartSmallFontLoc, @numberSpriteCopies + 64); PrintCharToSprite(numbersPtr[2], @mainPartSmallFontLoc, @numberSpriteCopies + 128); numbersPtr += 3; if (numbersPtr[0] = @cstop) then numbersPtr := #naamatNumbers; // print the name WriteMainName(); if (namesPtr[0] = @cstop) then namesPtr := #naamatNames; plasmaHeight := 2; mainWorkState := @notWorking; end; end; end.