It is currently Fri Nov 17, 2017 2:09 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 4 posts ] 
Author Message
PostPosted: Thu Oct 19, 2017 11:11 am 
Offline
User avatar

Joined: Wed Sep 21, 2016 12:08 pm
Posts: 35
If I want to to define a sprite animation my AMS6 code structure looks like this:

Code:
DAT.Animation.Pacman.Walk:
  .db $08 ; Animation Timer Speed (Number of NMIs before transition)
  .db $03 ; Animation # of Frames
  .dw DAT.Sprite.Pacman.Walk3
  .dw DAT.Sprite.Pacman.Walk2
  .dw DAT.Sprite.Pacman.Walk1
  .dw DAT.Sprite.Pacman.Walk2

DAT.Sprite.Pacman.Walk1:
  .db $04 ; Number of Sprites
  .db $10 ; X Adjustment When Flipped
  .db $F8, $8A, %00000001, $00
  .db $F8, $8B, %00000001, $08
  .db $F0, $9B, %00000001, $00
  .db $F0, $9A, %00000001, $08

DAT.Sprite.Pacman.Walk2:
  .db $04 ; Number of Sprites
  .db $10 ; X Adjustment When Flipped
  .db $F8, $B4, %00000001, $00
  .db $F8, $c4, %00000001, $08
  .db $F0, $B7, %00000001, $00
  .db $F0, $C6, %00000001, $08

DAT.Sprite.Pacman.Walk3:
  .db $04 ; Number of Sprites
  .db $10 ; X Adjustment When Flipped
  .db $F8, $BA, %00000001, $00
  .db $F8, $BB, %00000001, $08
  .db $F0, $BC, %00000001, $00
  .db $F0, $BD, %00000001, $08


The code that manages the player updates is defined here:

Code:
LBL.Draw.Player:

  ; Set the Pointer to the Frame Data
  LDA VAR.Player.Animation.Frame
  ASL
  TAY
  INY
  INY
  LDA (VAR.Player.Animation.Data),Y
  STA VAR.TEMP
  INY
  LDA (VAR.Player.Animation.Data),Y
  STA VAR.TEMP+1

  ; Set the Tile Byte Counter
  LDY #$00
  LDA (VAR.TEMP),Y
  ASL
  ASL
  TAY
  INY
  INY
  STY VAR.TEMP+2

  ; Set the Horizontal Flipping Offset
  LDY #$01
  LDA (VAR.TEMP),Y
  STA VAR.TEMP+3

  LDY #$02
  LDX #$00

LBL.Draw.Player.Loop:

    ; Copy Vertical Position Data
    LDA (VAR.TEMP),Y
    CLC
    ADC VAR.Player.Y
    STA BUF.Sprites,X

    ; Copy Tile
    INY
    INX
    LDA (VAR.TEMP),Y
    STA BUF.Sprites,X

    ; Copy Tile Attributes
    INY
    INX
    LDA (VAR.TEMP),Y
    STA BUF.Sprites,X

    ; Check if Horizontally Flipped
    LDA VAR.Player.VX.Dir
    BEQ LBL.Draw.Player.SetX
      LDA (VAR.TEMP),Y
      EOR #%01000000
      STA BUF.Sprites,X

    ; Copy Horizontal Position Data
LBL.Draw.Player.SetX:
    INY
    INX
    LDA (VAR.TEMP),Y
    CLC
    ADC VAR.Player.X
    STA BUF.Sprites,X

    ; Check if Flipped
    LDA VAR.Player.VX.Dir
    BEQ LBL.Draw.Player.Loop.Continue
       LDA VAR.Player.X
       SEC
       SBC (VAR.TEMP),Y
       SEC
       SBC #$08
       CLC
       ADC VAR.TEMP+3
       STA BUF.Sprites,X

LBL.Draw.Player.Loop.Continue:
    INY
    INX
    CPY VAR.TEMP+2
    BNE LBL.Draw.Player.Loop
 
  LDA TRUE
  STA FLAG.UpdateSprites
         
RTS


This works well for most cases, except when I get need to do the following

1. I need to indicate where in the sprite buffer the sprite attributes need to go (since the player can go "behind" other sprites)
2. Indicate where the tile date should be put in CHR-RAM (tile index) when it's loaded.

How do you handle this?


Top
 Profile  
 
PostPosted: Fri Oct 20, 2017 5:28 am 
Offline
User avatar

Joined: Thu Sep 15, 2016 6:29 am
Posts: 375
Location: Denmark (PAL)
Unless you hardcode specific positions in the sprite buffer (which is horribly ineffecient when you want to make full use of all 64 hardware sprites, but a lot of old games actually did that), I'd say it's all in the order you decide to write to your buffer.

What I have done previously is two separate solutions:

1. Make a separate "draw" routine at the end of my main loop which reads object information in the order I want to send them to the sprite buffer. Basically, the items I write first get the highest priority. So if a sprite needs to be in front, I'll make a special routine to handle those objects first, and then maybe the player character followed by data from a generic object table, etc., proceeding until no objects are left, or my "X" register (used to index the position in the sprite buffer, same as you do) rolls over.

2. Keep my X index saved to a variable in memory that I dig out whenever I want to draw a sprite during my object update routines. This is less neat to look at, but gives you more freedom to draw different items in different ways. However you'd still have to consider the order you draw them in, if you want to give some of them higher priority.

The biggest issue is of course if you want to have some kind of sprite cycling method to keep your sprites blinking instead of disappearing if you expect to go over 8 on the same scanline. This makes it difficult to always give some objects higher priority, so if that's important to you I'd say it's a good idea to keep a seperate "draw" routine which always draws the high priority sprites first, and then loops through the remaining object in a ways that differs on each frame.


Top
 Profile  
 
PostPosted: Fri Oct 20, 2017 5:50 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5821
Location: Canada
Yeah, make your sprite drawing routines concatenate to the end of the sprite list, and then it's just a matter of calling the draws in order of priority.

If you have something that does that already, it's not too hard to then randomize or otherwise vary the order to get sprite flickering. (e.g. you could call the draws in reverse order every second frame)


Top
 Profile  
 
PostPosted: Mon Oct 23, 2017 12:29 pm 
Offline
User avatar

Joined: Wed Sep 21, 2016 12:08 pm
Posts: 35
Thanks Everyone! I hadn't though about doing it that way, makes it much easier.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 6 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group