| |
Doppelgaenger Scroll Intro [2023] |
Credits :
Code | .... | zscs of Excess, Lethargy, The Apace Software |
Music | .... | Richard of People of Liberty, Psytronik Software, Scene World Magazine, The New Dimension |
Graphics | .... | zscs of Excess, Lethargy, The Apace Software |
Design | .... | zscs of Excess, Lethargy, The Apace Software |
Idea | .... | zscs of Excess, Lethargy, The Apace Software |
Charset | .... | zscs of Excess, Lethargy, The Apace Software |
SIDs used in this release :
Download :
Look for downloads on external sites:
Pokefinder.org
Summary Submitted by zscs on 26 October 2023
Here is the .txt file that I used during planning the screens, effects and also making it easier to code the whole thing in S-MON $C000.
SCREEN:
ln# d012 badl*: scr: col: *$d011=$1b /badline
-----------------------------------------------------
!00 $31 $33 $0400 $d800
01 $39 $3b $0428 $d828 logo1
02 $41 $43 $0450 $d850 logo2
03 $49 $4b $0478 $d878 logo3
04 $51 $53 $04a0 $d8a0 logo4
05 $59 $5b $04c8 $d8c8 logo5
06 $61 $63 $04f0 $d8f0 logo6
07 $69 $6b $0518 $d918 logo7
08 $71 $73 $0540 $d940 logo8
09 $79 $7b $0568 $d968 logo9
10 $81 $83 $0590 $d990 logoa (only 1 pixel)
11 $89 $8b $05b8 $d9b8 <empty>
12 $91 $93 $05e0 $d9e0 name of the release
13 $99 $9b $0608 $da08 <empty>
*14 $a1 $a3 $0630 $da30 <empty>
15 $a9 $ab $0658 $da58 32-bit heigh sprite scroll starts here
16 $b1 $b3 $0680 $da80 3x3-char scroller - upper part
17 $b9 $bb $06a8 $daa8 ...2nd line
18 $c1 $c3 $06d0 $dad0 ...3rd line
19 $c9 $cb $06f8 $daf8 -- empty - (blue bg. set here)
20 $d1 $d3 $0720 $db20 3x3-char scroller - mirror + mirrored bg. sprites
21 $d9 $db $0748 $db48 ..2nd line
22 $e1 $e3 $0770 $db70 ..3rd line
23 $e9 $eb $0798 $db98 last 8-pixel part of mirrored scroll sprites
24 $f1 $f3 $07c0 $dbc0
Sprites: screen top-left X: #24/$18 (#32/$20 w/ 38-char wide), Y: #50/$32
right-most: $159/#351
* - stable raster init point
----------------------
DATA: C: code, G: graphics, D: data, S: sprites, V/P: value/pointer, M:music, T:text
F: font
************************************************************************************
---------------------------------------------------------------------
f $0800 - 0c40: 3x3 charset bitmap data (0-127 chars, 128-135 'error' overlays)
d $0c80 - 0cc0: offset to char map / char (e.g. 'a'->charpos $03->bitmap from $0808)
d $0cc0 - 0d00: width of char (in nr. of characters). Important: length>=2 is supported!
d $0d00 - 0d8a: charset map, row #1
d $0d90 - 0e1a: charset map, row #2
d $0e20 - 0eaa: charset map, row #3
m $1000 - 188c: init: 1000, play: 1003 - /MUSICIANS/B/Bayliss_Richard/Trip_to_Space.sid
d $1900 - 1ab0: $0428 screen colour data
d $1b00 - 1cb0: $d828 screen colour data
d $1cc0 - 1d00: sinus data
g $2000 - 2dc0: MC bitmap gfx (Excess logo). Note: effectively, gfx data from $2140
t $2dc0 - 2de8: 'name of the crack' - (40-char wide)
f $2e00 - 3000: 1x1 font
g $3000 - 3780: 2x3x40-char bitmap scroll data (240 chars used)
s $3800 - 3c00: 2x8 sprites: upper scroll ($e0 - e7) + shadow ($e8 - ef)
t $3c00 - 3c30: fade-out text (must be empty / spaces only!)
d $3fa0 - 3fb8: sprite position data
$3fa0 - 3fa7: X position for sprites 0-7
$3fa8 - 3faf: $D010 bit for sprites 0-7
d $3fc0 - 3fd8: 3x8 byte bitmap data buffer (3x3 scroll right-most column data)
--> sprites will get 3fc0-3fcf in the upper part
d $3fd8 - 3fe8: mirrored temporary char data for sprite mirrored scroller
--> sprites will get 3fd8-3fe7 in the lower part
d $42c0 - 42f0: 42c0: upper color scroll offset ($3f0a -> e.g. $40->$3e40)
42c4: upper scroll sprites' color ($401b)
42c8: upper 3x3-char scroll color ($1893)
42cc: lower background color ($4727)
42d0: lower scroll sprites' color ($419b)
42d4: lower 3x3-char scroll color ($189e)
d $46a0 - 46b0: memory pointers to sprite row 1 - low byte
d $46b0 - 46c0: memory pointers to sprite row 1 - high byte
d $46c0 - 46d0: memory pointers to sprite row 2 - low byte
d $46d0 - 46e0: memory pointers to sprite row 2 - high byte
d $46e0 - 46f0: 07fx sprite pointer table - row 1 ($e0-e7, twice)
d $46f0 - 4700: 07fx sprite pointer table - row 2 ($e8-ef, twice)
t $4800 - 4b00: scrolltext (3x3 scroll)
--
Code/Routines:
c $1d00: START <-- !!!
c $1f00: main routine
.
c $0ec0 - 0f43: fade-in logo colour draw routine, 1 column/frame (init: $0fff=$00)
c $0f48: fade-out logo, 1 column/frame (init: $0ffe=$27)
c $0fa1: reset / JMP $3c40 after pressing space + fade-out logics
c $1000: music init
c $1003: music play
c $1890: 3x3 scroll upper-lower part: set color ($1893: upper, $189e: lower)
c $3c40: reset registers and move game code to $0801 after space press <-- !!!
c $3f00: color change logic (scroll)
c $3f30: upper sprite row's color cycling logic
c $3f50: change scroll color scheme
c $4000: upper sprite scroll init
v $4001: common Y coordinates
v $401b: sprites' colours
c $40c0: name of the game/crack line's fade-in
c $4100: 3x3 scroll main logic
JSR 4200: move the matrix left by 1 char
INC 3ffa: add 1 to current column pos of the current char
LDA+CMP: width of char reached?
BEQ .b: get next scrolltext char
JMP 435B: simply draw the next column of the char
.b
JSR 4300: get the next char
JSR 4420: draw next char's left-most column with 'ORA' on
c $4180: lower sprite scroll init
v $4181: common Y coordinates
v $419b: sprites' colours (default: $00 - black)
c $4200: a. move 6x40-char matrix to left by 1 char
b. inc last sprite's column counter $3FF6
c $4276: calculate 3x3 left column default 16-bit pointer ($34-35)
c $4300: go and read the next char in the scrolltext
c $435b: fill right-most chars in the 3x3 scroll - with 'STA' !
TODO: $06a7 is not enough. use zero-page and 3 x ROL the index! (done.)
c $4440: right-most column: copy upper part to mirrored part
c $4500: 'ORA' on the last char of the previous scrolltext char's right-most chars
c $4600: sprite scroller graphics: main routine
IMPORTANT: $4100 code should always run before this routine!
1. based on 3x3 scroller speed, determine whether new sprite column should be
drawn (Note: here, pause is NOT handled yet!)
2. if yes, do the magic:
INC $3ff6.
a) if $3FF6 = $00 then sprite (pointer) movement needed ($07f8-07ff data)
b) left-most sprite to the right: INC $38 AND $07. If Carry is set, zero out
c) if new sprite should come at right (see at b)) then
cycle $1cb0-1cb7 and 1cb8-1cbf (these are the data for $07f8-07ff)
d) right-most sprite's actual column's draw routine:
x = $1cc0,$38 points to sprite data pointers' small tables
upper scroll: $1cc8,x : low 8-bit. $1cd0,x : high 8-bit (e.g. $3840)
lower scroll: $1cd8,x : low 8-bit. $1ce0,x : high 8-bit (e.g. $3a40)
e) set values (determined at d)) to $36-$37, $39-3a and
LDA $3fc0-3fcf data
STA ($36),y
set values for lower data pointers
LDA $3fd8-3fe7 data
STA (39),y
c $4700: sprite scroller: sprite movement calculation
c $4720: set d020-21 to dark color (e.g. $06),
...also JMP $4180 to set 2nd sprite row and re-enable sprites
--
VARIABLES (ZERO PAGE, memory addr):
z $2d 3x3 scroll: pause (default is $03 because of scroll - sprite sync)
z $2e 3x3 scroll: D016 value (0-7)
z $2f 3x3 scroll: bitmap's draw position: $00-$27 (-->3x3's 1st row/last col val:
$06a7 )
z $30-31: scrolltext vector
z $32-33: temporary vector which points to 3x3 charset's char data
z $34-35: 3x3 right column default 16-bit pointer
z $36-37: 3x3 right column 16-bit pointer - corrected to 2nd and 3rd row
z $38 : sprite scroller position (0-7)
z $39-3a: temporary pointers for mirrored sprite scroll gfx draw part
z $3b : sprite scroller temporary counter
v 0ffd : crack name line fade-out (default/init: $27, run: $00)
v 0ffe : logo fade-out after press space (default: $00, run: $27)
v 0fff : fade-in logo colour draw routine: position
v 18ae : crack name fader init (on: $25, after pressing space it's $00)
v 1cff : left-most sprite # (0-7)
v 1e28 : init & calculate sprite X coordinates: 8th bit value
v 3ff0 - 3ff5: temporary buffer for 2x40-char matrix's left-oriented cycling
v 3ff6 : right-most sprite's char data paste column (0-2)
v 3ff8 : 3x3 scroll: offset where char starts (e.g. $03: char 'a')
v 3ff9 : 3x3 scroll: length of char (e.g. 3 for char 'a')
v 3ffa : 3x3 scroll: current position within the current char
$3f: %00111111
v 3ffd : 1st row current char
v 3ffe : 2nd row current char
v 3fff : 3rd row current char
v 40c1 : name of game/crack fade-in's pointer
v 410e : 3x3 scroll SPEED
v 460b : sprite scroll SPEED ($410e * 2)
v 47ff : sprite 0 position addix ($00-$2f)
RUNTIME Plan:
-------------
$4200 - all main code sections, separated by raster interrupts.
Nr#: $D012: $1e00,X: $D018: $D016: $D011: ($D0xx value only, if change is made)
03 87 a4 $1a $c8 $1b
.0 init 1x1 charset ($2800, effectively starts at $2e00)
.1 init sprites for upper scroll, set coords and colours
.2
00 a1 00 $1c $c8+x $1b
.0 init 3x3 charset ($3000), set D016, D011
.1 play music here, if rastertime fits (??)
.2 init 1st sprite row
01 c7 30
.0 set D020 and D021 to e.g. $06 (for mirrored text)
.1 wait until $D012=$c8 and start to set mirrored sprite colours and also
set Y-coordinates (set D015 to $00 might be required, temporarily!)
.2 logo fade-in routine (JSR $0ec0)
02 e9 52
.0 set D020 and D021 to $00
.1 init bitmap logo:
$18 $d8 $3b
.2 fade-in name of game/crack ($40c0)
-----------------------
colours:
0 - @ - black
1 - a - white
2 - b - red
3 - c - cyan
4 - d - purple
5 - e - green
6 - f - blue
7 - g - yellow
8 - h - orange
9 - i - brown
a - j - light red
b - k - dark grey
c - l - grey
d - m - light green
e - n - light blue
f - o - light grey
scheme | #1: #2: #3: #4:
42c0+: upper color scroll offset 40 60 80 a0
42c4+: upper scroll sprites' color n b n f
42c8+: upper 3x3-char scroll color a j c m
42cc+: lower background color f k f k
42d0+: lower scroll sprites' color @ @ d @
42d4+: lower 3x3-char scroll color k e j e
Sprite parameters - : ( note: screen top-left X: #24/$18, Y: #50/$32 )
- row #02 (3rd): $07fx X-coord.: X-max: Y-coordinate: d00x d010 bits
- HI sprite #0: 8-$e0 $f0+x $1f $aa (left-upper) 0 1.0
- HI sprite #1: 9-$e1 $20+x $4f $aa 2 0
- HI sprite #2: a-$e2 $50+x $7f $aa 4 0
- HI sprite #3: b-$e3 $80+x $af $aa 6 0
- HI sprite #4: c-$e4 $b0+x $df $aa 8 0
- HI sprite #5: d-$e5 $e0+x $0f $aa a 0.1
- HI sprite #6: e-$e6 $10+x $3f $aa c 1
- HI sprite #7: f-$e7 $40+x $6f $aa e 1
...where 'x' increases from $00 to $2f
$d010 sets and as soon as X reaches the following values:
when x=$2f: %10000011, $83
when x=$19: %00000111, $07
when x=$09: %00000011, $03
- $d010: $ (X coordinate offset/ 256)
- $d015: $ff (%11111111 - 1: sprite enabled)
- $d027-d02e: $0e ( sprites' colours: e.g. blue )
Common:
-------
- $d017/d01d: $ (x/y double)
- $d01b: $ff (sprite priority register, 1 = Sprite #x is behind screen contents)
- $d01c: $00 (%00011111: MC or hires, 0 = Sprite #x is hires; 1 = Sprite #x is MC)
Music 3rd channel instrument values> @ $17c7:
code: colours:
- $12ce: drums, 1f, 24, 18, 14, 34
-
Ideas:
------
- phase-out:
1) logo: $0400 and d800 values cleared from right to left?
2) scroll: the extra 8 'dirty' chars 'clears' the scroll more and more? [not implemented]
3) time to time, scroll colours and bg. colors switch to an another variation
4) after every 256-frame: colour cycling on 'name of the crack' line (fade-in only) [different version used]
- HIDDEN part ideas:
1) overlaps between chars could do 'OR' and - if e.g. F1 is pressed, changes to EOR [not implemented]
2) pressing F1: changing colours of the scroller [not implemented]
space press: LDA DC01, AND #10, BEQ -code-
F1 press: [not implemented]
- 3x3 scroll tricks:
1) when new char is drawn, set a 'flag' to $01 and fill out the mirrored right-most
column only during the next raster interrupt. A LOT of runtime could be saved.
Note: not necessary, logic is fast enough!
2) right-most sprite's next column should be also filled in the next raster
interrupt (maybe together with nr. 1), if there's enough rastertime - otherwise,
if scroll speed is $03 then a 'blank'/wrong column will be used...
[update: this was not necessary, the routine much faster than I thought]
- music sync:
1) sprite bg scrolls bounces a little, if e.g. snare happens 4 times
a. ...also upper sprite colours could fade back from e.g. 07, 03, 0f, 0e
Note: 4-5 pixel high bouncing would be enough
b. name of crack could also have a colour fade scroll
-----
Temporary data:
---------------
3x3 Charset: #, offset, length
00 _ 0 3
01 A 3 3
02 b 6 3
03 c 9 3
04 d 12 3
05 e 15 3
06 f 18 3
07 g 21 3
08 h 24 3
09 i 27 2
10 j 29 2
11 k 31 3
12 l 34 3
13 m 37 5
14 n 42 3
15 o 45 3
16 p 48 3
17 q 51 3
18 r 54 3
19 s 57 3
20 t 60 3
21 u 63 3
22 v 66 3
23 w 69 5
24 x 74 3
25 y 77 3
26 z 80 3
46 . 83 2
44 , 85 2
33 ! 86 3
63 ? 89 3
58 : 92 2
59 ; 93 2
47 / 95 3
61 = 98 3
39 ' 101 2
34 " 103 3
40 ( 106 3
41 ) 108 3
48 0 112 3
49 1 115 2
50 2 117 3
51 3 120 3
52 4 123 3
53 5 126 3
54 6 129 3
55 7 132 3
56 8 135 3
57 9 138 3
Char: 3ffa 3ffa
A 1 2
draw 2nd col
draw 3rd col + ORA next char's 1st col
| Summary Submitted by zscs on 19 September 2023
Multi-speed scroller routine a tricky one. The charset part could handle speeds from 1-8 pixels/frame, however, because of the sprite background / scrolling I decided to restrict it to 1-3 pixels/frame (theoretically, 4 pixels/frame should work, not checked though). The draw routine is quite fast, writes only 1 column when a new char should be displayed. I used some kind of buffering to make the sprite's draw routine fast and keep the code less complex. But it's a really tricky one. It's a complete chaos actually. :) |
|
|
|
| Search CSDb |
| Navigate | |
|
| Detailed Info | |
|
| Fun Stuff | |
· Goofs · Hidden Parts · Trivia
|
|
| Forum | |
|
| Support CSDb | |
|
| |
|