Charger un background en assembleur

Discussions techniques et Pixel Art en 9 bits.

Modérateurs : SirG, Redfield1, shubibiman, Laucops

Répondre
vct-kun
Please Insert Disc!
Messages : 2
Inscription : mar. 30 avr. 2013 16:16

Charger un background en assembleur

Message par vct-kun »

Bonjour,

Débutant dans la programmation pc engine, j'ai une petite question pour les personnes expérimentées en la matière.
Je cherche à savoir comment charger une image en background en assembleur.
L'équivalent de la fonction load_background dans Huc mais en assembleur. Je n'ai pas trouvé une macro équivalente dans pceas.

Quelqu'un aurait il une idée ?

Charles.
Avatar de l’utilisateur
touko
NECromancer
Messages : 2297
Inscription : lun. 31 mars 2008 14:32

Re: Charger un background en assembleur

Message par touko »

Salut tu peux te baser sur la demo bomberman de chris covell, que j'ai adaptée pour pceas 3.21

Code : Tout sélectionner

;
; "Bomberman Title screen effect"
;

_xres	.equ 320	; set this before including 'startup.asm'
			; that will set up a 320x240 screen in place
			; of the default 256x240 screen

	.include "startup.asm"
	.nomlist
	.list

; ----
; defines

NB_PICS	.equ 1		; the number of pictures in the slideshow

; ----
; variables

	.zp
pic:			.ds 1		; the current picture number
scanline:		.ds 2	; the line number for the scanline interrupt
curr_scanline 	.ds 1	;The scanline of the pic
sinevalue: 		.ds 1	;Some temporary val for the sine wave.
sinevalueA: 	.ds 1
delayA: 		.ds 1		;A delay for scrolling...
WaveIndex16:	.ds 2	
WaveBase16:		.ds 2	;A 16-bit index for linearity, etc...

	; wavy scroll

wave_base:		.ds 1	; base index for the wave table
wave_idx:		.ds 1	; index in the wave table
wave_base2:		.ds 1
wave_idx2:		.ds 1


;±±±[ MAIN CODE ]±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±

	.code
	.bank MAIN_BANK
	.org  $C000
main:	
	
	vec_off #VSYNC
	vec_off #HSYNC
	; disable display
	
	vsync
	st0  #5	
	st1   #$0C	
	st2	  #$00	
	
	; load the picture in VRAM

	jsr	load_pic	
	
	; enable display
	vsync	
	vreg  #5
	lda   #$CC
	sta   $0002
	stz	  $0003

	vsync
	setvec #VSYNC,vsync_proc
	setvec #HSYNC,hsync_proc
	vec_on #VSYNC
	vec_on #HSYNC
	
	
.waitstate:
	;vsync
	
	jmp   .waitstate

;**************************************************
;------ Interrupt code --------------------------

; ----
; vsync_proc
; ----
; called every VSYNC
; ----

vsync_proc:	
	
	st0   	#6						; restart the scanline counter on the first
	
	lda		#$40
	sta		video_data_l
	stz		video_data_l + 1
	sta		<scanline
	sta		<scanline + 1

	inc		<delayA
	lda		<delayA
	cmp		#$01
	bne		.pas_inc_h	
	stz		<delayA
	
	;Increase the index (0-1023)
	ldx		<WaveBase16
	lda		<WaveBase16 + 1				;Get its high value
	inx
	stx		<WaveBase16
	stx		<WaveIndex16
	bne		.pas_inc_h
	ldx		#$C0						;This adds a hold at the effect's peak
	stx		<delayA
	inc		A
	and		#$03						;Only 0000-03FF
	sta		<WaveBase16 + 1
	sta		<WaveIndex16 + 1
	
  .pas_inc_h:	
  
;--------------------------- Now we do the complicated stuff.
	lda		<WaveIndex16				;Get index
	lsr		A
	ldx		<WaveIndex16 + 1				;Get high byte
	bne		.Not1stQuarter				;Is it 0?
;----------------	
	add		#$81
	bra		.SaveSineVal
	
.Not1stQuarter:
	dex								;Is it 1?
	bne		.Not2ndQuarter
	eor		#$FF
	add		#$81						;#$80 plus #$1
	bra		.SaveSineVal
;--------------------
.Not2ndQuarter:
	dex								;Is it 2?
	bne		.Not3rdQuarter
	add		#$01
	bra		.SaveSineVal
;--------------------------
.Not3rdQuarter:						;Okay, so it's 3 (I hope).
	eor		#$FF
	add		#$01
	
.SaveSineVal:
	sta		<sinevalue

	eor		#$FF
	add		#$01
	sta		<sinevalueA

.vb_end:	
	rts

; ----
; hsync_proc
; ----
; called every HSYNC
; ----
hsync_proc:
	; update the scrolling	

	st0		#8		; This means Y-scroll!
;-----------------------
	lda		<scanline
	sec
	sbc		#$40
	sta		<curr_scanline	;Current scanline of the image, not the screen!
	
	lda		<sinevalueA		;A = above
	cmp		<sinevalue		;(B) = below
	bcs		.NoAbove1

	lda		<curr_scanline
	cmp		<sinevalue		;Is the scanline below?
	bcc		.NoBelow1
	lda		<sinevalue		;If so, then smear
	bra		.NoAbove2
	
.NoBelow1:
	cmp		<sinevalueA		;Is the scanline above?
	bcs		.NoAbove2
	lda		<sinevalueA		;If so, then smear
	bra		.NoAbove2
	
.NoAbove1:
;------------------------------
	lda		<curr_scanline		;Are the lines switched?
	cmp		<sinevalue
	bcc		.NoAbove2
	cmp		<sinevalueA
	bcs		.NoAbove2		;At this point we're in the middle.
	lda		<curr_scanline
	and		#$01
	beq		.Smear_Even
	lda		<sinevalueA
	bra		.NoAbove2
	
.Smear_Even:
	lda		<sinevalue
	
.NoAbove2:
;-----------------------	
	sta   	video_data_l
	stz   	video_data_l + 1

	; // reprogram the scanline counter for the next line
	st0		#6	
	lda		<scanline
	ldx		<scanline + 1
	inc		A
	sta		<scanline
	sta		video_data_l
	bne		.pas_inc_h
	inx	
	stx		<scanline + 1
	stx		video_data_l + 1
	
  .pas_inc_h:
	rts

	; the wave table

.wave:	.db   5,6,7,8,8,9,9,10,10,10,9,9,8,8,7,6
		.db   5,4,3,2,2,1,1,0,0,0,1,1,2,2,3,4
		.db   5,6,7,7,8,8,9,9,9,9,9,8,8,7,7,6
		.db   5,4,3,3,2,2,1,1,1,1,1,2,2,3,3,4


;±±±[ SUB CODE ]±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±

; ----
; load_pic
; ----
; upload a whole pic in VRAM
; ----

load_pic:
	lda   <pic		; get the current pic number

	asl   A			; mul it by 6 (each picture takes six banks,
	sta   <_al		; five for the graphics and one for the BAT
	asl   A			; and the palette)
	add   <_al

	add   #2		; add 2 - our pictures are stored starting
				; from bank 2

	sta   <_ah		; store the bank index

	; load the graphic in VRAM, one bank at a time
	
	lda   <_ah		; first bank
	tam   #4
	vload $1000,$8000,#$1000
	inc   <_ah		; second bank
	lda   <_ah
	tam   #4
	vload $2000,$8000,#$1000
	inc   <_ah		; third bank
	lda   <_ah
	tam   #4
	vload $3000,$8000,#$1000
	inc   <_ah		; fourth bank
	lda   <_ah
	tam   #4
	vload $4000,$8000,#$1000
	inc   <_ah		; fifth bank
	lda   <_ah
	tam   #4
	vload $5000,$8000,#$1000

	; vsync before setting the palette, to avoid snow

	vsync

	; now set the palette

	inc   <_ah
	lda   <_ah
	tam   #4
	set_bgpal #0,$8000,#16
	set_sprpal #0,$8000,#16

	; and finaly copy the BAT

	batcpy $0001,\	       
	       $8200,\
	       #40,\
	       #32

	; ok, done

	rts	

;±±±[ PICTURE DATA ]±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±

	.data

	; pictures can contain up to 256 colors, but as you know the
	; PC-Engine can display only 16 colors per 8x8 tile, so be careful
	; when making pictures. And also take care of the color alignment,
	; a tile can use, for example, color 0 to 15, but not color 4 plus
	; color 26 plus color 125, all the colors used in a tile must
	; belong to the same sub-palette (colors 0 - 15, 16 - 31, etc...)
        ;
	; if you have problems making such pictures, use only 16 colors
	; PCX files, you will have less problems

PIC_BANK .func (((\1)*6)+MAIN_BANK+1)	; a little function to help
					; referencing banks

PIC	.macro			; hmm a macro could be handy too...
	 .bank PIC_BANK(\1)
	 .org  $8000
	 .incchr \2,40,32
	 .bank PIC_BANK(\1)+5
	 .org  $8000
	 .incpal \2
	 .org  $8200
	 .incbat \2,$1000,40,32
	.endm

	PIC 0,"pcx/strider0.pcx"	; what would we do without macros? :)

	; etc... up to 21 pictures.
	;
	; at your turn now, make us some cool slideshow!
Répondre