Log inRegister an accountBrowse CSDbHelp & documentationFacts & StatisticsThe forumsAvailable RSS-feeds on CSDbSupport CSDb Commodore 64 Scene Database
  You are not logged in - nap
Doppelgaenger Scroll Intro   [2023]

Doppelgaenger Scroll Intro Released by :
Excess

Release Date :
17 September 2023

Type :
C64 Crack Intro

User rating:**********  9.6/10 (21 votes)   See votestatistics
**********  9.9/10 (9 votes) - Public votes only.

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 :
Trip to Space(/MUSICIANS/B/Bayliss_Richard/Trip_to_Space.sid)

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
Advanced
Navigate
Prev - Random - Next
Detailed Info
· Summaries (2)
· User Comments (11)
· Production Notes (2)
Fun Stuff
· Goofs
· Hidden Parts
· Trivia
Forum
· Discuss this release
Support CSDb
Help keep CSDb running:



Funding status:




About this site:
CSDb (Commodore 64 Scene Database) is a website which goal is to gather as much information and material about the scene around the commodore 64 computer - the worlds most popular home computer throughout time. Here you can find almost anything which was ever made for the commodore 64, and more is being added every day. As this website is scene related, you can mostly find demos, music and graphics made by the people who made the scene (the sceners), but you can also find a lot of the old classic games here. Try out the search box in the top right corner, or check out the CSDb main page for the latest additions.
Home - Disclaimer
Copyright © No Name 2001-2024
Page generated in: 0.09 sec.