In my game,player have 4 different size,and 6 kinds of fish,every kind of fish is different size.
I want to make a table like:
spr_data: ;w ;h ;t
lev.1L db $1, $1, $02
lev.1R db $1, $1, $03
lev.2L db $2, $1, $0e,$0f
lev.2R db $2, $1, $1E,$1F
LEV.3L DB $2, $2, $04,$05, $14,$15
LEV.3R DB $2, $2, $06,$07, $16,$17
LEV.4l DB $3, $2, $08,$09, $0A,$18,$19,$1A
LEV.4R DB $3, $2, $0B,$0C,$0D,$1B,$1C,$1D
Fish_data: ;w ;h ;y ;t ;x
fish_1 db $1, $1, $3f, $42, $08
fish_2 db $2, $1, $4F, $24,$25,$34,$35, $f0
fish_3 db $2, $1, $5f, $44,$45,$54,$55, $78
...........
But then how to do?
I don't how to do next.
PLS make an example,Write some source.
I'm very bad at English.THX.
Many games works like this to show sprites :
At VBLank : Just write #$00 to $2003 and #$02 (or something else) to $4014, then let's use the precious VBlank time for others PPU Writes.
Once the VBlank finished, you can start to clear the whole sprite RAM buffer to be sure to have it clean :
Code:
ldx #$3f
lda #$ff ;If the whole sprite data is $ff, everything will be hidden
loop:
sta $200,X
sta $240,X
sta $280,X
sta $2c0,X
dex
bpl loop
The above example is in the middle of good speed and not oversized routines. Doing only one write to $200,X and increment X for the whole 256 bytes is slower. Of course, you can store it anywhere else, but the $200 ram page is usally used.
Then you can start to upload your sprite data. You can call various routines like this :
Code:
ldx #$00
jsr WriteSpritePart1
jsr WriteSpritePart2
jsr WriteSpritePart3
....
Inside your routines, you'll have to load all the sprite data that you want, the better mode is to write it at $200,X and increase X correctly between each routine, so you can easily change the sprite's priority by changing routine's order.
But you first have to organize your data to be easily readable/usable by your programm.[/code]
One minor detail is that to actually get the sprite data to be displayed on screen... you need to do a $4014 write every frame during vblank. After all your sprite drawing code... do a quick:
Code:
LDA #$00
STA $2003
LDA #$02
STA $4014
That will copy the whole $02xx page to sprite memory. Also note that this eats a very good chunk of CPU time (the code above will take a whole 525 cycles to complete!)... But it's necessary.
Disch wrote:
One minor detail is that to actually get the sprite data to be displayed on screen... you need to do a $4014 write every frame during vblank. After all your sprite drawing code...
Nope. BEFORE all your sprite drawing code. If all calculations are done between an NMI trigger and a sprite updating, I'm afraid it would often fill the whole VBLank time and the thing won't work at all. I think the delay of one frame before moving stuff isn't too much, heh.
But in my code,if I use
Code:
LDA #$00
STA $2003
LDA #$02
STA $4014
before or after load sprites, sprites will be displayed which shouldn't .
If I use [code]
ldx #$3f
lda #$ff
loop:
sta $200,X
sta $240,X
bne loop
[code]
before or after sprites loaded,sprtes will be displayed well,but my whole screen will shake seriously.
I think it's my nmi too long.Yes?
But I must add other function,and my code will more than more in the nmi.
What can I do?[/code]
It's me.I haven'But in my code,if I use
Code:
LDA #$00
STA $2003
LDA #$02
STA $4014
before or after load sprites, sprites will be displayed which shouldn't .
If I use
Code:
ldx #$3f
lda #$ff
loop:
sta $200,X
sta $240,X
bne loop
before or after sprites loaded,sprtes will be displayed well,but my whole screen will shake seriously.
I think it's my nmi too long.Yes?
But I must add other function,and my code will more than more in the nmi.
What can I do?[/code]t logo in.
Bregalad wrote:
Nope. BEFORE all your sprite drawing code.
Meh... before/after is all relative to which frame you're talking about. I said after because you have to draw sprite data to RAM at least once before using DMA or you'll draw garbage sprites. And after makes more sense because it displays what you draw to the screen (doesn't make sense to display sprite data
before you have any sprite data to display, does it)
Although yes... in the scope of a frame, the $4014 write will probably happen earlier in the frame than your sprite drawing code (assuming you place VBlank at the top of the frame and not at the bottom)
</semantics>
xian106 wrote:
Code:
ldx #$3f
lda #$ff
loop:
sta $200,X
sta $240,X
bne loop
That code will lock up your program -- it will never escape that loop. You never change the status of the Z flag, so BNE will always branch (infinite loop). Only way to break out would be through an IRQ or NMI -- but an RTI would throw you right back inside.
Anyway, yeah... screen shaking is a symptom of your NMI taking too long All you really should be doing in NMI is drawing related stuff. Anything that involves drawing to the screen ($4014/$2006/$2007/$2005) should be done in VBlank (2006/2005 might be used outside of vblank for split screen and other raster effects... but you know what I mean).
everything else should wait until outside VBlank... there just simply isn't enough time to do all sorts of work in VBlank -- do your drawing and that's
it -- everything else can be done during frame rendering.
So your sprite writes to the $02xx page should
not be done in your NMI (or at least you shouldn't reserve VBlank time for it). You can write to $02xx anytime in the frame. However the $2003/$4014 writes must be done in vblank.
xian106 wrote:
If I use
Code:
ldx #$3f
lda #$ff
loop:
sta $200,X
sta $240,X
bne loop
You just forget the dex before the bne loop, so be carefull.
I thing you have to structure your code a bit. What I recommend is :
At RESET :
- Turn off IRQ and NMI
- Init all stuff
- Vait several frames before starting your actual code and writing anything to the PPU
- Begin your actual code and eventually enable NMIs (depending on what you're doing)
At NMI :
- Do Sprite DMA ($2003, $4014)
- Do all your PPU Updates ($2006, $2007) for the name table, attribute table or pattern table (only if you're using Chr-Ram). The use of FIFO buffers is the better way to do write data strings to the PPU, but you can do it the way you want. This part of the code should be as quick and stressfull as possible.
- Setup Scroll and Screen ($2005, $2000)
- Do the rest of sfuff you want, but here you have all your time, this include upload the FIFO buffer that could be read in VBlank, and clear/fill the sprite DMA page (usually at $200, but if you want you can put it anywhere else)
The main problem is to decide what will be in the NMI code and what won't. Games like Mario, Zelda, and many Konami's games does everithing in their VBlank code and the non-NMI code get's unaused. Some games like Final Fantasy have absolutely no NMI code, and returns to the main code immediately. You can setup the main structure of your code freely, and that's good stuff.
I just forget write "dex" here,it had been done in my code.
It seems as if that I had done everything right,but screen still have a little shake.
I think it's the nmi taking to long.But I don't know how to solve this problem really.
I have so much function to added still in the game,scroll,enemies,paused,die,game over ,win,music,DEMOI and so on.I can not add anything now...
I want to copy my code here,but it is too long~
Could you read my code cursorily and then tell me what's wrong?
OK,it works well now.Screen shook because of the position of two sentences: lda #$00, sta $2006, sta $2006.
And I clear my sprites well now.I do that like:
Code:
lda #$00
sta $2003
lda #$02
sta $4014
jsr loadspr
ldx #$3f
lda #$ff
loop:
sta $300,X
sta $340,x
dex
bne loop
But I don't kown how to do it out of nmi.[/code]
I am sorry.I write code wrong.
It must be
Code:
lda #$00
sta #$2003
lda #$02
sta #$4014
ldx #$3f
lda #$ff
loop:
sta $300,X
sta $340,x
dex
bne loop
jsr loadspr
[/quote]