Homebrew:Scrolling Mountains

From veswiki
Jump to: navigation, search

Scrolling mountains in action.

Curtdawg figured out a nice way to make scrolling mountains like in the game Scramble. A lot of bios calls are used which saves a lot of programming space. The variations can be set as data to control the various peaks and valleys, example code below. Could be used as a graphics engine for various types of games, none that has been made yet. Add a ship or helicopter and a few enemies and it's a game!


; Scrolling Mountains
;
; written by Curtdawg

	processor f8

;------------;
; BIOS Calls ;
;------------;

delay           =       $008f
prompt		=       $0099
clrscrn		=	$00D0
pushk           =       $0107
popk            =       $011e
RedVert12Line   =       $01F6
RedHoriz104Line =       $020E
prompts         =       $0224
IncP1Score	=       $02AC
IncP2Score	=       $02B5
UpdateBall      =       $03D3
Clock		=	$0467
DetectCollision =	$049C
unknown		=	$05FC
ResetFrameCounter =	$065B
drawchar        =       $0679
drawcustomchar  =       $067C
eraseimageoldpos =      $06EC
drawsquareimage =       $0718

; Data Counter def
bitmaps		=	$767


;-------------------;
; Color Definitions ;
;-------------------;
red             =       $40
blue            =       $80
green           =       $00
bkg             =       $C0
clear		=	$FF

;--------------------;
; Register Reference ;
;--------------------;

; Reg8: Left edge where drawing begins: Initialized to SCREEN_WIDTH and decremented until 0
; Reg9: Flat pane index for column pointed to by Reg8
; RegB: Current height of Reg8 Column
; Reg4: Current Column
; Reg5: Current Flat pane index
; Reg7: Current Column Height
; Reg32: Op code byte for column pointed to by Reg8
; Reg1: Current Op code byte

;------------------;
; Object Variables ;
;------------------;

SCREEN_WIDTH		=	101	; 95

;===================;
; Main Program Code ;
;===================;

;---------------;
; Program Entry ;
;---------------;

	org	$800


	LR   $5,A                ;
	LR   $A,A                ;
cartridgeStart:
	li	$D0;
	lr	3, A
	pi	clrscrn;
	dci opcodes;
	lr  q,dc;
	li  SCREEN_WIDTH;
	lr  $8,A;	; actual left edge for drawing
	clr;
	lr  $9,A;	; Flat plane index for column specified by $8
	li  $37
	lr  $B,A	; current height at column specified by $8
	lisu 4;
	lisl 0;		; reg 32 has current op code byte
	lm;
	oi  $40
	lr  (IS), A;
	
	
DrawNextFrame:
	bf $0,DrawScreen;
DrawScreenReturn:
	ds	$8;
	bp DrawNextFrame;
	clr;
	lr  $8,A;				// Start column
	bf $0,DrawNextFrame ;
	
DrawScreen:
	lr  dc,q;
	lr  A,$8    ; start column
	lr	$4,A	; reg4 stores current column
	lr  A,$B	; current column height
	lr  $7,A	; reg7 stores current column height
	lr  A,(IS)		; S has current op code
	lr  $1,A	; reg1 has current op code
	lr  A,$9    ; flat plane index
	lr	$5,A	; reg5 stores current flat plane index
DrawScreen.Loop:
	oi	$0;		; If we are drawing a flat plane, no need to update this column
	bz  SkipFlat;
	ds	$5;
	bz NextColumn.NextOpcode ;
	br  NextColumn ;
SkipFlat:
    lis $3  ; Get op code in low bits and transform to column height offset (0=-2,1=-1,2=1,3=2)
	ns	$1;
	lr  $0,A
	ds  $0
    bz  DecOffset; 
    bp  skipDec;
DecOffset:
	ds  $0
skipDec:
	pi UpdateColumnPixels ;
	lr A,$0;
	as $7	; update currentColumn height
	lr	$7,A;
    lr  A,$1 ; advance to next 2-bit opcode in byte
    sr  1
    sr  1
    lr  $1,A
    sr  1
	bnz  NextColumn;
	
NextColumn.NextOpcode:
	lm	; Get next opcode
	oi $0;	// Is flat?
	bp NotFlat;
	ci $80
	bnz Flat;
	dci opcodes_repeat;
	bf	$0,NextColumn.NextOpcode;

Flat:
	ni $3F;
	lr $5,A;
	bf $0,NextColumn ;
NotFlat:
    oi $40
	lr $1,A;
NextColumn:
	lr	 A,$4
	oi   $0;
	bnz IncColumn;
	
	lr  A,$7	; 
	lr  $B,A	; 
	lr  A,$1		; 
	lr  (IS),A	; 
	lr  A,$5    ; 
	lr	$9,A	; 
	lr  q,dc;
IncColumn:
	lis $1;
	as  $4;
	lr  $4,A;
	ci	SCREEN_WIDTH + 1;
	bz  DrawScreenReturn;
	lr  A,$5    ; flat plane index
	bf $0,DrawScreen.Loop ;
	
; Draws or erases 1 or 2 pixels in the current column
; Reg0: Code:	$FE = Draw two pixels (Column, Row-1 and Column, Row-2)
;				$FF = Draw one pixel (Column, Row-1)
;				$01 = Erase one pixel (Column, Row)
;				$02 = Erase two pixels (Column, Row and Column, Row + 1)
; Reg4: Column - We add 4 to this
; Reg7: Row - We add 4 to this
UpdateColumnPixels:	
	
	LI   $40                 ; Load Immediate $40
	OUTS 0                   ; Store in Port $0 (Why?)
	lis $1
	ns  $7
	li	blue
	bz	SkipRed
	li	green
SkipRed:
	outs 1;	// Set color
	lr  A,$0;
	ci  $01;
	bz EraseOnePixel;
	bm EraseTwoPixels;
	ci $FE;
	bz DrawTwoPixels;
	lis $4;
	as $4;
	com ;
	outs 4;
	lis $3;
	as $7;
	com;
	ni $3F;
	outs 5;	
	li	$60
	outs	0
	li	$50
	outs	0
	pop	; Don't delay - there will be a fair amount of processing before the next pixel is drawn
DrawTwoPixels:
	li $4;
	as $4;
	com ;
	outs 4;
	lis $3;
	as $7;
	com;
	ni $3F;
	outs 5;	
	li	$60
	outs	0
	li	$50
	outs	0
D2PDelay:
	sr 1;
	bnz D2PDelay; Delay for 31 cycles. Hopefully this is enough
	lis $1
	ns  $7
	li	green
	bz	SkipRed2
	li	blue
SkipRed2:
	outs 1;	// Set color
	lis $2;
	as $7;
	com;
	ni $3F;
	outs 5;	
	li	$60
	outs	0
	li	$50
	outs	0
	pop	; Don't delay - there will be a fair amount of processing before the next pixel is drawn
EraseOnePixel:
	li $C0;	// background
	outs 1;	// Set color
	li $4;
	as $4;
	com ;
	outs 4;
	lis $4;
	as $7;
	com;
	ni $3F;
	outs 5;	
	li	$60
	outs	0
	li	$50
	outs	0
	pop	; Don't delay - there will be a fair amount of processing before the next pixel is drawn
EraseTwoPixels:
	li $C0;	// background
	outs 1;	// Set color
	li $4;
	as $4;
	com ;
	outs 4;
	lis $4;
	as $7;
	com;
	ni $3F;
	outs 5;	
	li	$60
	outs	0
	li	$50
	outs	0
E2PDelay:
	sr 1;
	bnz E2PDelay	; Delay for 31 cycles. Hopefully this is enough
	lis $5;
	as $7;
	com;
	ni $3F;
	outs 5;	
	li	$60
	outs	0
	li	$50
	outs	0
	pop				; Don't delay - there will be a fair amount of processing before the next pixel is drawn
	

; high bit set means run of flat ground - count is in the lower bits if %1000000 then reset game data
; otherwise the three lower sets of two bots each encode an 
; instruction: (00:up two), (01:up one), (10:down one), (11:down two), 
; Warning comments for these opcodes are generally invalid as I've modified the opcodes without
; updating the comments. Sorry!
opcodes:
	.byte	%00000101	; up 3 : 3
	.byte	%00010101   ; up 3 : 6
	.byte	%00010101   ; up 3 : 6
	.byte	%00010101   ; up 3 : 6
	.byte	%00010101   ; up 3 : 6
opcodes_repeat
	.byte	%00000000   ; up 3: 15
	.byte	%00010101   ; up 3: 15
	.byte   %00101010   ; down 3 : 12
	.byte   %00111111   ; down 3 : 12
	.byte	%10010000   ; flat 16
	.byte	%00000000   ; up 3: 15
	.byte   %00101010   ; down 3 : 12
	.byte   %00101010   ; down 3 : 12
	.byte	%10000011   ; flat 3
	.byte	%00000000   ; up 3: 15
	.byte	%00010101   ; up 3: 15
	.byte   %00101010   ; down 3 : 12
	.byte   %00111111   ; down 3 : 12
	.byte   %00101010   ; down 3 : 12
	.byte	%10010000   ; flat 12
	.byte	%00000000   ; up 3: 15
	.byte	%00010101   ; up 3: 15
	.byte   %00101010   ; down 3 : 12
	.byte   %00111111   ; down 3 : 12
	.byte	%00010101   ; up 3: 15
	
	.byte   %00101010   ; down 3 : 12
	.byte   %00101010   ; down 3 : 12
	.byte   %00101010   ; down 3 : 12
	.byte   %00101010   ; down 3 : 12
	.byte   %00101010   ; down 3 : 12
	.byte	%00000000   ; up 6: 15
	.byte	%00000000   ; up 6: 15
	.byte	%10000100  ; flat 16
	.byte	%00000000   ; up 6: 15
	.byte	%00000000   ; up 6: 15
	.byte   %00111111   ; down 3 : 12
	
	
	
	.byte	%00000000   ; up 3: 15
	.byte	%00010101   ; up 3: 15
	.byte   %00101010   ; down 3 : 12
	.byte   %00111111   ; down 3 : 12
	.byte	%10010000   ; flat 16
	.byte	%00000000   ; up 3: 15
	.byte   %00101010   ; down 3 : 12
	.byte   %00101010   ; down 3 : 12
	.byte	%10000011   ; flat 3
	.byte	%00000000   ; up 3: 15
	.byte	%00010101   ; up 3: 15
	.byte   %00101010   ; down 3 : 12
	.byte   %00111111   ; down 3 : 12
	.byte   %00101010   ; down 3 : 12
	.byte	%10010000   ; flat 12
	.byte	%00000000   ; up 3: 15
	.byte	%00010101   ; up 3: 15
	.byte   %00101010   ; down 3 : 12
	.byte   %00111111   ; down 3 : 12
	.byte	%00010101   ; up 3: 15
	
	.byte   %00101010   ; down 3 : 12
	.byte   %00101010   ; down 3 : 12
	.byte   %00101010   ; down 3 : 12
	.byte   %00101010   ; down 3 : 12
	.byte   %00101010   ; down 3 : 12
	.byte	%00000000   ; up 6: 15
	.byte	%00000000   ; up 6: 15
	.byte	%10000100  ; flat 4
	.byte	%00000001  ; flat 16
	.byte	%00100110  ; flat 16
	.byte	%00011001  ; flat 16
	.byte	%00101111   ; up 6: 15
	.byte	%10000100  ; flat 4
	.byte	%00000000   ; up 6: 15
	.byte	%00000000   ; up 6: 15
	.byte   %00111111   ; down 3 : 12
	
	.byte   %00101010   ; down 3 : 12
	.byte   %00101010   ; down 3 : 12
	.byte   %10000000	; restart

	org	$fff
	.byte	$ff