home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!noc.near.net!hri.com!enterpoop.mit.edu!eru.mt.luth.se!lunic!sunic!aun.uninett.no!nuug!ifi.uio.no!larshaug
- From: larshaug@ifi.uio.no (Lars Haugseth)
- Newsgroups: alt.sys.amiga.demos
- Subject: Source : Horizontal scroller
- Message-ID: <1992Dec12.193243.14082@ifi.uio.no>
- Date: 12 Dec 92 19:32:43 GMT
- Sender: larshaug@ifi.uio.no (Lars Haugseth)
- Organization: Dept. of Informatics, University of Oslo, Norway
- Lines: 403
- Nntp-Posting-Host: yrsa.ifi.uio.no
- Originator: larshaug@yrsa.ifi.uio.no
-
-
-
-
- It's time to hit the hardware again, and maybe earn
- some more flames. 8)
-
- Ok, here is small program I made that simply scrolls
- a 5 bitplane 320x256 pixels picture leftwards, and inserts
- new graphics at the right edge of the screen. The graphics are
- built up by 16x16 pixel blocks. I have included some example
- block-data as a uuencoded LhA-archive. (Separate posting)
-
- The scrolling works as follows:
-
- After smooth-scrolling the picture 16 pixel with the BLTCON1 register,
- I add 2 bytes to the bitplane-pointers, and blit new blocks into the
- memory which lies off the right edge of the screen. It's as simple as
- that. It's very simple to extend the program to scroll in both directions,
- but that part you must figure out yourselves.
-
- The memory usage for the graphics are [ SW * (SH + MX) ] bytes,
- where SW is the screenwidth in bytes, SH is the screenheight in
- pixels, and MX is the maximum number of screenwidths you can scroll.
- I have set MX=32, which means you can scroll 352x32 pixels, which
- should be more than enough for most vertical scrolling games.
-
- Time usage is about 4 rasterlines pr.frame when scrolling 1 pixel at a time.
- If you'd like to scroll more pixel pr.frame, the time increases, but
- it's still pretty fast.
-
- +-----------------------------------------------------------+
- | Lars Haugseth +-+
- | Dept. of Informatics, <larshaug@ifi.uio.no> | |
- | University of Oslo, Norway | |
- | | |
- | If idiots could fly, this would be an airport... | |
- +-+---------------------------------------------------------+ |
- +-----------------------------------------------------------+
-
-
-
-
-
- ;-------------------------------------------------------------------------
- ; BLOCK-SCROLLER
- ;-------------------------------------------------------------------------
- ; Programmed by Lars Haugseth 9/12-92
- ;-------------------------------------------------------------------------
- ; CONSTANTS
- ;-------------------------------------------------------------------------
-
- EXECBASE = 4
-
- CUSTOMBASE = $DFF000 ; Custom-chips register offset
-
- OpenLibrary = -408 ; Library function offsets
- CloseLibrary = -414
- VBeamPos = -384
-
- SW = 44 ; Width of screen in bytes
- SH = 256 ; Height of screen in pixels
- MX = 32 ; Maximum pages of scrolling
-
- ;-------------------------------------------------------------------------
- ; MACROS
- ;-------------------------------------------------------------------------
-
- WRAST: MACRO ; Wait for a specific rasterpos.
- movem.l d0-a6,-(SP)
- move.l GFXBASE,a6
- \@1 jsr VBeamPos(a6)
- cmp.w #\1,d0
- bne.s \@1
- movem.l (SP)+,d0-a6
- ENDM
-
- WBLIT: MACRO ; Wait for the blitter to finish
- btst #6,$02(a5)
- bne.s \@1
- bra.s \@2
- \@1 nop
- nop
- btst #6,$02(a5)
- bne.s \@1
- \@2
- ENDM
-
- ;-------------------------------------------------------------------------
- ; PROGRAM
- ;-------------------------------------------------------------------------
-
- SECTION "code",code_p
-
- STARTPROG:
-
- move.l EXECBASE,a6 ; Open graphics.library
- lea GFXNAME,a1
- moveq #0,d0
- jsr OpenLibrary(a6)
- move.l d0,GFXBASE
- beq EXIT
-
- lea CUSTOMBASE,a5
- move.l GFXBASE,a6
-
- move.l $26(a6),OLDCOPPERLIST ; Save copperlist
- move.w $1C(a5),OLDINTERRUPTS ; Save enabled interrupts
- move.w $02(a5),OLDDMACONTROL ; Save dmacontrol
-
- move.w #$87E0,$96(a5) ; Enable some DMAs
- move.w #$7FFF,$9A(a5) ; Disable all interrupts
-
- ;-------------------------------------------------------------------------
-
- INITMAP:
-
- lea SCROLLMAP,a0
- moveq #0,d7
- IMAP1: cmp.w #320,d7
- blt.s IMAP2
- bsr GETRANDOM
- bra.s IMAP3
- IMAP2: move.w d7,d0
- IMAP3: move.w d0,(a0)+
- addq #1,d7
- cmp.w #[SW*8]*MX,d7
- bne.s IMAP1
-
- ;-------------------------------------------------------------------------
-
- INITCOPPER: ; Initialize copperlist
-
- lea COLOURS,a0 ; Insert palette
- lea COP1PALETTE+2,a1
- move.w #31,d7
- ICOP1: move.w (a0)+,(a1)
- addq.w #4,a1
- dbf d7,ICOP1
-
- move.l #BLANKS,d0 ; Insert blank sprites
- move.w d0,COP1SPRITES+06
- move.w d0,COP1SPRITES+14
- move.w d0,COP1SPRITES+22
- move.w d0,COP1SPRITES+30
- move.w d0,COP1SPRITES+38
- move.w d0,COP1SPRITES+46
- move.w d0,COP1SPRITES+54
- move.w d0,COP1SPRITES+62
- swap d0
- move.w d0,COP1SPRITES+02
- move.w d0,COP1SPRITES+10
- move.w d0,COP1SPRITES+18
- move.w d0,COP1SPRITES+26
- move.w d0,COP1SPRITES+34
- move.w d0,COP1SPRITES+42
- move.w d0,COP1SPRITES+50
- move.w d0,COP1SPRITES+58
-
- move.l #SCROLLPLANES+[0*SW],d0 ; Insert Bitplane pointers
- move.l #SCROLLPLANES+[1*SW],d1
- move.l #SCROLLPLANES+[2*SW],d2
- move.l #SCROLLPLANES+[3*SW],d3
- move.l #SCROLLPLANES+[4*SW],d4
- add.l d5,d0
- add.l d5,d1
- add.l d5,d2
- add.l d5,d3
- add.l d5,d4
- move.w d0,COP1PLANE1+6
- move.w d1,COP1PLANE2+6
- move.w d2,COP1PLANE3+6
- move.w d3,COP1PLANE4+6
- move.w d4,COP1PLANE5+6
- swap d0
- swap d1
- swap d2
- swap d3
- swap d4
- move.w d0,COP1PLANE1+2
- move.w d1,COP1PLANE2+2
- move.w d2,COP1PLANE3+2
- move.w d3,COP1PLANE4+2
- move.w d4,COP1PLANE5+2
-
- move.l #COPPERLIST,$80(a5) ; Start copperlist
- clr.w $88(a5)
-
- ;-------------------------------------------------------------------------
-
- MAINLOOP:
-
- WRAST $110 ; Wait for rasterpos $111
- WRAST $111
-
- move.w #$722,$180(a5) ; Scroll screen, and set
- bsr SCROLLER ; a red background colour
- move.w #$000,$180(a5) ; to measure time
-
- btst #6,$BFE001 ; Loop until LMB is pressed
- bne.s MAINLOOP
-
- ;-------------------------------------------------------------------------
-
- EXITPROGRAM:
-
- move.l EXECBASE,a6 ; Close graphics.library
- move.l GFXBASE,a1
- jsr CloseLibrary(a6)
-
- EXIT: lea CUSTOMBASE,a5 ; Restore old values and exit
- or.w #$8000,OLDDMACONTROL
- or.w #$8000,OLDINTERRUPTS
- move.w OLDDMACONTROL,$96(a5)
- move.w OLDINTERRUPTS,$9A(a5)
- move.l OLDCOPPERLIST,$80(a5)
- clr.w $88(a5)
- moveq #0,d0
- rts
-
- ;-------------------------------------------------------------------------
-
- GETRANDOM:
-
- moveq #0,d0 ; Get a 'random' byte
- moveq #0,d1
- move.b $DFF007,d0
- move.b $BFD800,d1
- eor.b d1,d0
- rts
-
- ;-------------------------------------------------------------------------
-
- SCROLLER: ; Scrolling routine
-
- btst #2,$DFF016 ; Skip if RMB is pressed
- beq.w SCRLX
-
- move.w SCROLLPOS,d1 ; Lowest 4 bits into BPLCON1
- and.w #15,d1
- sub.w #15,d1
- neg d1
- mulu #$11,d1
- move.w d1,COP1SCROLL+2
-
- move.w SCROLLPOS,d5 ; Add words to Bitplane-pointers
- lsr.w #4,d5
- add.w d5,d5
- and.l #$FFFE,d5
-
- move.l #SCROLLPLANES+[0*SW],d0 ; Update pointers in
- move.l #SCROLLPLANES+[1*SW],d1 ; copperlist
- move.l #SCROLLPLANES+[2*SW],d2
- move.l #SCROLLPLANES+[3*SW],d3
- move.l #SCROLLPLANES+[4*SW],d4
- add.l d5,d0
- add.l d5,d1
- add.l d5,d2
- add.l d5,d3
- add.l d5,d4
- move.l d0,COPYADR ; Store address where new
- add.l #SW-2,COPYADR ; blocks are to copied
- move.w d0,COP1PLANE1+6
- move.w d1,COP1PLANE2+6
- move.w d2,COP1PLANE3+6
- move.w d3,COP1PLANE4+6
- move.w d4,COP1PLANE5+6
- swap d0
- swap d1
- swap d2
- swap d3
- swap d4
- move.w d0,COP1PLANE1+2
- move.w d1,COP1PLANE2+2
- move.w d2,COP1PLANE3+2
- move.w d3,COP1PLANE4+2
- move.w d4,COP1PLANE5+2
-
- bsr COPYBLOCK ; Copy a block at right edge
-
- cmp.w #8*SW*[MX-1],SCROLLPOS ; Scroll 1 pixel left
- bge.s SCRLX
- addq.w #1,SCROLLPOS
-
- SCRLX: rts
-
- ;-------------------------------------------------------------------------
-
- COPYBLOCK: ; Copy a block onto screen
-
- lea SCROLLMAP,a0 ; Get block number from
- add.w SCROLLPOS,a0 ; the map
- add.w SCROLLPOS,a0
- move.w (a0),d0
-
- lea BLOCKS,a0 ; Calculate address for
- mulu #160,d0 ; the block data
- add.l d0,a0
-
- move.w SCROLLPOS,d1 ; Calculate address that
- and.l #15,d1 ; the block is copied into
- mulu #5*16*SW,d1
- move.l COPYADR,a1
- add.l d1,a1
-
- lea CUSTOMBASE,a5 ; Blit block onto screen
- WBLIT
- move.l a0,$50(a5) ; BLTAPTR
- move.l a1,$54(a5) ; BLTDPTR
- move.l #$0000002A,$64(a5) ; BLTAMOD BLTDMOD
- move.l #$09F00000,$40(a5) ; BLTCON0 BLTCON1
- move.w #$1401,$58(a5) ; BLTSIZE
- WBLIT
- rts
-
- ;-------------------------------------------------------------------------
- ; PUBLICMEM STORAGE
- ;-------------------------------------------------------------------------
-
- SECTION "publicdata",data_p
-
- OLDCOPPERLIST: dc.l 0
- OLDINTERRUPTS: dc.l 0
- OLDDMACONTROL: dc.l 0
-
- SCROLLPOS: dc.w 0 ; Scrollposition in pixels
-
- COPYADR: dc.l 0 ; Where to copy new blocks on screen
-
- COLOURS: dc.w $000,$FFF,$EEE,$DDD,$CCC,$BBC,$AAB,$99A ; Palette
- dc.w $889,$777,$666,$555,$444,$333,$222,$111
- dc.w $F87,$E65,$C43,$911,$800,$600,$400,$300
- dc.w $500,$B98,$DB9,$FDC,$846,$956,$A67,$A79
-
- SCROLLMAP: blk.w [SW*8]*MX,0 ; Block map
-
- GFXBASE: dc.l 0
- GFXNAME: dc.b "graphics.library",0
-
- ;-------------------------------------------------------------------------
- ; COPPERLIST
- ;-------------------------------------------------------------------------
-
- SECTION "chipdata",data_c
-
- COPPERLIST: dc.w $008E,$2C81,$0090,$2CC1 ; DisplayWindow
- dc.w $0092,$0030,$0094,$00D0 ; DataFetch
- dc.w $0108,$00B2,$010A,$00B2 ; BitplaneModulo
- dc.w $0102,$0000,$0104,$0000 ; BPLCON1 & BPLCON2
-
- COP1SPRITES: dc.w $0120,$0000,$0122,$0000 ; Sprite pointers
- dc.w $0124,$0000,$0126,$0000
- dc.w $0128,$0000,$012A,$0000
- dc.w $012C,$0000,$012E,$0000
- dc.w $0130,$0000,$0132,$0000
- dc.w $0134,$0000,$0136,$0000
- dc.w $0138,$0000,$013A,$0000
- dc.w $013C,$0000,$013E,$0000
-
- COP1PALETTE: dc.w $0180,$0000,$0182,$0000 ; Palette
- dc.w $0184,$0000,$0186,$0000
- dc.w $0188,$0000,$018A,$0000
- dc.w $018C,$0000,$018E,$0000
- dc.w $0190,$0000,$0192,$0000
- dc.w $0194,$0000,$0196,$0000
- dc.w $0198,$0000,$019A,$0000
- dc.w $019C,$0000,$019E,$0000
- dc.w $01A0,$0000,$01A2,$0000
- dc.w $01A4,$0000,$01A6,$0000
- dc.w $01A8,$0000,$01AA,$0000
- dc.w $01AC,$0000,$01AE,$0000
- dc.w $01B0,$0000,$01B2,$0000
- dc.w $01B4,$0000,$01B6,$0000
- dc.w $01B8,$0000,$01BA,$0000
- dc.w $01BC,$0000,$01BE,$0000
-
- COP1PLANE1: dc.w $00E0,$0000,$00E2,$0000 ; Bitplane pointers
- COP1PLANE2: dc.w $00E4,$0000,$00E6,$0000
- COP1PLANE3: dc.w $00E8,$0000,$00EA,$0000
- COP1PLANE4: dc.w $00EC,$0000,$00EE,$0000
- COP1PLANE5: dc.w $00F0,$0000,$00F2,$0000
-
- COP1SCROLL: dc.w $0102,$0000 ; FineScrolling BPLCON1
-
- dc.w $2C07,$FFFE,$0100,$5200 ; Turn on bitplanes at line $2C
-
- dc.w $FFDF,$FFFE ; Wait below line $100
-
- dc.w $2C07,$FFFE,$0100,$0000 ; Turn off bitplanes at $12C
-
- dc.w $FFFF,$FFFE ; End copperlist
-
- ;-------------------------------------------------------------------------
- ; CHIPMEM STORAGE
- ;-------------------------------------------------------------------------
-
- SCROLLPLANES: blk.b 5*SW*[SH+MX],0 ; Scroll bitplanes
-
- incdir "df0:" ; Where to load includes
- BLOCKS: incbin "blocks.raw" ; Block image data
-
- BLANKS: dc.l 0,0 ; Blank sprite
-
- ;-------------------------------------------------------------------------
-