millfork/examples/c64/galencia.mfk

169 lines
3.7 KiB
Plaintext

// Parallax starfield effect from Galencia
// originally written in assembly by Jason Aldred:
// https://github.com/JasonAldred/C64-Starfield
// http://www.galencia.games/
// compile with -O3 -finline -t c64
const word starScreenChar = $0400 // Screen address
const word StarScreenCols = $d800 // Character attribute address
const word charBase = $3000 // Address of our character set
const word star1Init = charBase+$1d0 // Init address for each star
const word star2Init = charBase+$298
const word star3Init = charBase+$240
const word star4Init = charBase+$2e0
const word star1Limit = charBase+$298 // Limit for each star
const word star2Limit = charBase+$360 // Once limit is reached, they are reset
const word star3Limit = charBase+$298
const word star4Limit = charBase+$360
const word star1Reset = charBase+$1d0 // Reset address for each star
const word star2Reset = charBase+$298
const word star3Reset = charBase+$1d0
const word star4Reset = charBase+$298
byte staticStar1 @charBase+$250 // 2 Locations for blinking static stars
byte staticStar2 @charBase+$1e0
const byte starColourLimit = 20 // use values 1 to 20
// Galencia uses these values
// 1 = mono
// 2 = duo
// 20 = full colour
byte rasterCount
pointer starfieldPtr1
pointer starfieldPtr2
pointer starfieldPtr3
pointer starfieldPtr4
void main() {
pointer p
disable_irq()
p = charBase
byte page
byte b
for page,0,paralleluntil,8 {
for b,255,downto,0 {
p[b] = 0
}
p.hi += 1
}
vic_bg_color0 = black
vic_border = black
vic_mem = 28
initStarfield()
createStarScreen()
while true {
while vic_raster != $FF {}
rasterCount += 1
vic_border -= 1
doStarfield()
vic_border += 1
}
}
void doStarfield() {
starfieldPtr1[0] = 0
starfieldPtr2[0] = 0
starfieldPtr3[0] = 0
starfieldPtr4[0] = 0
if rasterCount & 1 != 0 {
starfieldPtr1 += 1
if starfieldPtr1 == star1Limit {
starfieldPtr1 = star1Reset
}
}
starfieldPtr2 += 1
if starfieldPtr2 == star2Limit {
starfieldPtr2 = star2Reset
}
if rasterCount & 1 != 0 {
starfieldPtr3 += 1
if starfieldPtr3 == star3Limit {
starfieldPtr3 = star3Reset
}
}
starfieldPtr4 += 2
if starfieldPtr4 == star4Limit {
starfieldPtr4 = star4Reset
}
if rasterCount >= 230 {
staticStar1 = 0
} else {
staticStar1 = 192
}
if rasterCount ^ $80 >= 230 {
staticStar2 = 0
} else {
staticStar2 = 192
}
starfieldPtr1[0] |= 3
starfieldPtr2[0] |= 3
starfieldPtr3[0] |= 12
starfieldPtr4[0] |= 48
}
void initStarfield() {
starfieldPtr1 = star1Init
starfieldPtr2 = star2Init
starfieldPtr3 = star3Init
starfieldPtr4 = star4Init
}
void createStarScreen() {
byte y
byte x
pointer p
p = starScreenChar
byte char
byte start
byte limit
for x,0,paralleluntil,40 {
char = starfieldRow[x]
if char >= (58+25) {
limit = 58+50
} else {
limit = 58+25
}
start = limit - 25
p = starScreenChar
for y,0,paralleluntil,25 {
p[x] = char
p += 40
char += 1
if char == limit {
char = start
}
}
}
p = c64_color_ram
byte ci
ci = 0
for y,0,until,25 {
for x,0,paralleluntil,40 {
p[x] = starfieldCols[ci]
ci += 1
if ci == starColourLimit {
ci = 0
}
}
p += 40
}
}
const array starfieldCols = [
14,10,12,15,14,13,12,11,10,14,
14,10,14,15,14,13,12,11,10,12
]
const array starfieldRow = [
058,092,073,064,091,062,093,081,066,094,
086,059,079,087,080,071,076,067,082,095,
100,078,099,060,075,063,084,065,083,096,
068,088,074,061,090,098,085,101,097,077
]