Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ; ===============================================================
- ; ---------------------------------------------------------------
- ; The Merry Christmas Screen-Saver
- ;
- ; - Written in Blast ASM
- ; - Uses LabEngine-compatible SCL-functions
- ;
- ; (c) 2014, Developed by Vladikcomper
- ; ---------------------------------------------------------------
- ; ---------------------------------------------------------------
- ; Compilation constants / variables
- ; ---------------------------------------------------------------
- ; SCL-table indecies
- .set _Dummy, $00
- .set _LoadTexture, $01
- .set _DisplaySprite, $02
- .set _Redraw, $03
- .set _GetMem16, $04
- .set _DisplayMsg, $05
- ; ---------------------------------------------------------------
- ; Start of RAM actual vector table
- ; ---------------------------------------------------------------
- bra Init ; PC = $0000
- bra MainLoop ; PC = $0003
- ; ===============================================================
- ; ---------------------------------------------------------------
- ; Initialization programme
- ; ---------------------------------------------------------------
- Init:
- ; Clear interal memory (registers)
- sub r0,r0 ; r0 = $0000
- move r0,r1 ; clear data registers
- move r1,r2 ;
- move r2,r3 ;
- move r3,r4 ;
- move r4,r5 ;
- move r5,r6 ;
- move r6,r7 ;
- move r7,sp ; reset stack
- move sp,cc ; reset conditional codes register
- ; Load global textures
- move #Textures,r0
- move (r0),r1 ; r1 = Number of textures
- add #2,r0 ; next 2 bytes
- Init_LoadTexture:
- scl _LoadTexture ; obtain texture struct
- sub #1,r1 ; subtract 1 from number of textures remaining
- bra nz,Init_LoadTexture ; if textures remain, branch
- ; Clear object RAM
- move #ObjectRAM,r0
- move #$400,r1
- sub r2,r2 ; r2 = $0000
- Init_ClearObjRAM:
- move r2,(r0)
- add #2,r0
- sub #1,r1
- bra nz,Init_ClearObjRAM
- rti
- ; ===============================================================
- ; ---------------------------------------------------------------
- ; Main loop programme (update logic)
- ; ---------------------------------------------------------------
- MainLoop:
- bsr ProcessBG
- bsr GenerateSnowflakes
- bsr ProcessSnowflakes
- ; Debug memory view
- ; move #ObjectRAM,r0
- ; scl _GetMem16
- ; add #$10,r0
- ; scl _GetMem16
- scl _Redraw
- rti
- ; ---------------------------------------------------------------
- ; Subroutine to process background
- ; ---------------------------------------------------------------
- ProcessBG:
- move #Spr_BG,r0
- sub r1,r1 ; r1 = 0
- sub r2,r2 ; r2 = 0
- scl _DisplaySprite
- rts
- ; ---------------------------------------------------------------
- ; Subroutine to generate snowflakes
- ; ---------------------------------------------------------------
- Message:
- .dc 'Snowflake was created at $%X'
- GenerateSnowflakes:
- sub #1,GenSnowfls_Timer ; subtract 1 from timer
- bra nz,GenSnowfls_Done ; if time remains, branch
- move #8,GenSnowfls_Timer ; reset timer
- ; Find free slot in Object RAM
- move #$80,r7 ; r7 = Objects counter
- move #ObjectRAM,r6 ; r6 = Object RAM
- GenSnowfls_FindLoop:
- move (r6),r0 ; r0 = Sprite pointer
- bra z,GenSnowfls_SlotFound ; if found, branch
- add #$10,r6 ; next snowflake struct
- sub #1,r7 ; subtract 1 from number of snowflakes processed
- bra nz,GenSnowfls_FindLoop ; if snowflakes remain, branch
- rts ; emergency!
- GenSnowfls_SlotFound:
- move r6,r5
- move #Message, r0
- move r6,r1
- scl _DisplayMsg
- ; Load pattern structure for the snowflake
- move #GenSnowfls_Patterns,r0 ; load patterns array
- move GenSnowfls_PatPtr,r1
- add #8,r1
- and #%111000,r1
- add r1,r0 ; load current pattern
- move r1,GenSnowfls_PatPtr
- ; Copy sprite pointer
- move (r0),(r5)
- add #2,r0
- add #2,r5
- ; Generate pseudo-random X-pos
- add #49,GenSnowfls_XPos
- move GenSnowfls_XPos,r1
- and #$3FF,r1 ; r1 = 0...1024
- sub #640,r1 ; r1 -= 640
- bra nc,GenSnowfls_SetXY
- add #640,r1
- GenSnowfls_SetXY:
- ; Sets XY- position
- move r1,(r5) ; set XPos
- add #2,r5
- move #$FFE0,(r5) ; set Ypos
- add #2,r5
- ; Copy YVel, Angle and gain
- move (r0),(r5)
- add #2,r0
- add #2,r5
- move (r0),(r5)
- add #2,r0
- add #2,r5
- move (r0),(r5)
- add #2,r0
- add #2,r5
- ; Set base XPos
- move r1,(r5)
- move r6,r0
- scl _GetMem16
- ;scl 0
- GenSnowfls_Done:
- rts
- ; ---------------------------------------------------------------
- GenSnowfls_Timer:
- .dc 30
- GenSnowfls_XPos:
- .dc $0000
- GenSnowfls_PatPtr:
- .dc $0000
- GenSnowfls_Patterns:
- ; 8 bytes x 8 entries
- ; sprite yvel angle gain
- .dc Spr_BigSnowflake, 4, $0000, $0180
- .dc Spr_SmallSnowflake, 1, $8000, $FF40
- .dc Spr_SmallSnowflake, 2, $8000, $FF40
- .dc Spr_BigSnowflake, 4, $8000, $FE80
- .dc Spr_SmallSnowflake, 2, $2000, $FF40
- .dc Spr_SmallSnowflake, 1, $2C00, $FF40
- .dc Spr_BigSnowflake, 2, $0000, $00C0
- .dc Spr_SmallSnowflake, 2, $2C00, $FF40
- ; ---------------------------------------------------------------
- ; Subroutine to process snowflakes
- ; ---------------------------------------------------------------
- Messsage2:
- .dc 'Snowflake was removed from $%X'
- ProcessSnowflakes:
- move #$80,r7 ; r7 = Objects counter
- move #ObjectRAM,r6 ; r6 = Object RAM
- ProcSnowfls_Loop:
- move (r6),r0 ; r0 = Sprite pointer
- bra z,ProcSnowfls_Next ; if Sprite pointer wasn't set, skip this snowflake
- ; Display the snowflake at it's old position
- move r6,r5
- add #2,r5
- move (r5),r1 ; r1 = XPos
- push r5 ; remember XPos pointer
- add #2,r5
- move (r5),r2 ; r2 = YPos
- push r5 ; remember YPos pointer
- add #2,r5
- scl _DisplaySprite ; display snowflake at current pos (fetches r0, r1, r2)
- ; Update Y-position
- add (r5),r2 ; r2 = YPos + YVel
- pop r0
- add #2,r5
- cmp #516,r2 ; is YPos > 512?
- bra mi,ProcSnowfls_NoWrap
- ; move #$FFE0,r2 ; reset Ypos
- sub (r6),(r6) ; free obj struct
- pop r0
- push r0
- push r1
- move #Messsage2,r0
- move r6,r1
- scl _DisplayMsg
- pop r1
- pop r0
- bra ProcSnowfls_Next
- ProcSnowfls_NoWrap:
- move r2,(r0) ; update YPos
- ; Update X-position
- move (r5),r0 ; r0 = Angle
- push r5 ; save angle pointer
- add #2,r5
- add (r5),r0 ; r0 = Angle + Angle Gain
- add #2,r5
- move (r5),r2 ; r2 = XPos (actual)
- bsr CalcSine ; r1 = Sine
- sra r1 ; r1 >>= 3
- sra r1
- add r2,r1 ; r1 = XPos (actual) + Sin(Angle)
- move r0,r2 ; r2 = Angle
- pop r0
- move r2,(r0) ; update angle
- pop r0
- move r1,(r0) ; update XPos
- ProcSnowfls_Next:
- add #$10,r6 ; next snowflake struct
- sub #1,r7 ; subtract 1 from number of snowflakes processed
- bra nz,ProcSnowfls_Loop ; if snowflakes remain, branch
- rts
- ; ===============================================================
- ; ---------------------------------------------------------------
- ; Subroutine to calculate sine and cosine
- ; ---------------------------------------------------------------
- ; Input:
- ; r0 - Angle ($00.00 -- $FF.FF)
- ;
- ; Output:
- ; r1 - Sine (8.8)
- ; ---------------------------------------------------------------
- CalcSine:
- push r0
- move r0,UInt16
- move UInt8,r0 ; convert r0 to a 8-bit number
- sl r0 ; doulbe it
- add #Sinewave,r0 ; add Sinewave base to it
- move (r0),r1 ; r1 = Sin value (8.8)
- pop r0
- rts
- ; ===============================================================
- ; ---------------------------------------------------------------
- ; Integer convertor (extender) struct
- ; ---------------------------------------------------------------
- ; 32-bit format: $1122.3344
- UInt32: .rs 1 ; $44 -- $00
- UInt16: .rs 1 ; $33 -- .
- UInt8: .dc $0000 ; $22 -- .
- ; $11 -- $00
- Int32: .rs 1 ; $44 -- $00
- Int16: .rs 1 ; $33 -- .
- Int8: .dc $FFFF ; $22 -- .
- ; $11 -- $FF
- ; ===============================================================
- ; ---------------------------------------------------------------
- ; Resources data block
- ; ---------------------------------------------------------------
- .align $100
- ; ---------------------------------------------------------------
- Sinewave:
- .include 'sinewave.bin'
- ; ---------------------------------------------------------------
- Textures:
- .dc 2 ; number of textures
- ; id path width height
- .dc 1, 'BG_1024x512.raw', 1024, 512
- .dc 2, 'Snowflakes_64x64.raw', 64, 64
- ; ---------------------------------------------------------------
- Spr_BG:
- .dc 1, 0, 0, 640, 480
- ; ---------------------------------------------------------------
- Spr_BigSnowflake:
- .dc 2, 0, 0, 32, 32
- ; ---------------------------------------------------------------
- Spr_SmallSnowflake:
- .dc 2, 32, 0, 32, 32
- ; ===============================================================
- ; ---------------------------------------------------------------
- ; Object RAM
- ; ---------------------------------------------------------------
- ; Format ($10 bytes):
- ;
- ; $00 - Sprite pointer
- ; $02 - XPos
- ; $04 - YPos
- ; $06 - YVel
- ; $08 - Angle
- ; $0A - Angle gain
- ; $0C - XPos (actual)
- ; $0E - <Free/Unused>
- ;
- ; ---------------------------------------------------------------
- .align $100
- ObjectRAM:
- ; NOTICE: Should be initialized
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement