1588 lines
44 KiB
Plaintext
1588 lines
44 KiB
Plaintext
/**
|
|
* 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
|
|
@define spriteBank 0
|
|
|
|
spriteCopyBlock : array[63] of byte = buildtable("i") 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("i") 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, " 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, "KANSANAANESTYSALOITE",
|
|
@cmoveto, 0, 5, " RAHANKERAYSLAIN ",
|
|
@cmoveto, 0, 6, " UUDISTUS ",
|
|
@cmoveto, 0, 7, " PERUSTULO ",
|
|
@cpage,
|
|
@cmoveto, 0, 2, " PERUSOIKEUDET ",
|
|
@cmoveto, 0, 3, " YKSITYISYYDENSUOJA ",
|
|
@cmoveto, 0, 4, " YHDENVERTAISUUS ",
|
|
@cmoveto, 0, 5, " KESTAVYYSSIIRTYMA ",
|
|
@cmoveto, 0, 6, " VETYTALOUDEN ",
|
|
@cmoveto, 0, 7, " TEKNOLOGIATUKI ",
|
|
@cpage,
|
|
@cmoveto, 0, 2, " HYVINVOINTIALUEIDEN",
|
|
@cmoveto, 0, 3, " VERONKANTO-OIKEUS ",
|
|
@cmoveto, 0, 4, "PAIKALLISDEMOKRATIAN",
|
|
@cmoveto, 0, 5, " VAHVISTAMINEN ",
|
|
@cmoveto, 0, 6, " LUONTO MAANKAYTTO ",
|
|
@cmoveto, 0, 7, " KESTAVYYS ",
|
|
@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;
|
|
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);
|
|
if (currentTime > 50) then 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;
|
|
|
|
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 > 400) 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();
|
|
CopyCharsetRomToRam($c0);
|
|
|
|
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(^$0568, KEY_SPACE, 200);
|
|
|
|
for i := 0 to 256 do fastPlasma[i] := textPlasmaLumi[textPlasmaX[i]];
|
|
|
|
PreProcessScrollText();
|
|
|
|
// Start demo
|
|
|
|
GoToMainRaster();
|
|
EnableRasterIRQ();
|
|
enableirq();
|
|
|
|
while (true) do
|
|
begin
|
|
// 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. |