It is currently Sat Jun 23, 2018 10:14 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 8 posts ] 
Author Message
PostPosted: Wed Feb 14, 2018 3:22 am 
Offline
User avatar

Joined: Fri Feb 02, 2018 4:45 am
Posts: 5
Hi. Here's code that loads monster data (type, x y pos, etc.).

Code:
LoadEnemies:
  LDA MobLoadingStatus
  BEQ +
  RTS
  +
  LDY #$08
  LDX #$00
LoadEnemiesLoop:
  LDA spawn_test0 - 1, y
  STA Mob8Id - 1, y
 
  LDA spawn_test0 + 7, y
  STA Mob8Hp - 1, y

  LDA spawn_test0 + 15, y
  STA EnemyRam + 3, x

  LDA spawn_test0 + 23, y
  STA EnemyRam, x

  LDA spawn_test0 + 31, y
  STA Mob8Direction - 1, y

  TXA
  CLC
  ADC #$10
  TAX

  DEY
  BNE LoadEnemiesLoop
  INC MobLoadingStatus
  RTS


and sample spawndata:
Code:
spawn_test0:

;mob ids
.db #oak, #oak, #oak, #oak, #oak, #oak, #oak, #oak

;hp
.db $05, $05, $05, $05, $05, $05, $05, $05

;x pos
.db $20, $20, $20, $20, $90, $85, $50, $C0

;y pos
.db $20, $40, $60, $80, $40, $30, $60, $90

;direction
.db #Mob_Dir_West, #Mob_Dir_South, #Mob_Dir_North, #Mob_Dir_West, #Mob_Dir_East, #Mob_Dir_South, #Mob_Dir_North, #Mob_Dir_West


The thing is that I don't know how to make it read from anything else than spawn_test0. I don't want to copy and paste that subroutine as many times as there are rooms in my game of course. I want it to be something like this:

Code:
LoadEnemies:
  LDA MobLoadingStatus
  BEQ +
  RTS
  +
  LDY #$08
  LDX #$00
LoadEnemiesLoop:
  LDA CurrentSpawn - 1, y
  STA Mob8Id - 1, y
 
  LDA CurrentSpawn + 7, y
  STA Mob8Hp - 1, y

  LDA CurrentSpawn + 15, y
  STA EnemyRam + 3, x

  LDA CurrentSpawn + 23, y
  STA EnemyRam, x

  LDA CurrentSpawn + 31, y
  STA Mob8Direction - 1, y

  TXA
  CLC
  ADC #$10
  TAX

  DEY
  BNE LoadEnemiesLoop
  INC MobLoadingStatus
  RTS


I want to be able to set what CurrentSpawn means before calling LoadEnemies subroutine.
CurrentSpawn = spawn_test0
JSR LoadEnemies
CurrentSpawn = spawn_test1
JSR LoadEnemies
etc.


Top
 Profile  
 
PostPosted: Wed Feb 14, 2018 7:26 am 
Offline
User avatar

Joined: Fri May 08, 2015 7:17 pm
Posts: 2092
Location: DIGDUG
Quote:
The thing is that I don't know how to make it read from anything else than spawn_test0


I would solve this by having 2 pointers (indirect), y. One source (points to data set) and one destination (which mob object). You then adjust each pointer itself rather than adjusting y. Keep y at #0.

You can use a temporary variable as a loop counter.
LDA #count
STA temp
...
DEC temp
BNE @loop


EDIT, now that I think about it, it would be more efficient to still use y as the index and the loop counter. So you would INY and CPY.

_________________
nesdoug.com -- blog/tutorial on programming for the NES


Top
 Profile  
 
PostPosted: Sat Feb 17, 2018 9:54 am 
Offline
User avatar

Joined: Fri Feb 02, 2018 4:45 am
Posts: 5
Wouldn't it require dumping all the spawn data into the ram?


Top
 Profile  
 
PostPosted: Sat Feb 17, 2018 11:26 am 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 887
Location: cypress, texas
Eisetley wrote:
Wouldn't it require dumping all the spawn data into the ram?
No, put all of your spawn data into ROM. :) We have limited RAM: $0000 through $07FF. You have lots and lots of ROM though (an abundant amount of ROM if you use a mapper, like MMC1).

Putting spawn data into RAM would just enable you to change it at will; however, changing all of that data would take many cycles and would take up ROM space as well (for all the instructions doing the changing).

---
Eisetley wrote:
Code:
  LDY #$08
  LDX #$00

...

 LDA spawn_test0 + 15, y
 STA EnemyRam + 3, x
If I'm remembering what tokumaru told me correctly, it isn't possible to add and subtract from memory locations when using the Zero Page Indexed by X, Absolute Indexed by X, and Absolute Indexed by Y addressing modes. (Zero Page Indexed by Y doesn't allow that either.)

Advice:
  • Change Y instead of trying to change the memory address.
  • or follow dougeff's advice and use a pointer
  • Since your X is constantly at 0, just remove the , x and
Code:
 STA EnemyRam + 3
would work just fine. :)

Done editing this post now. : ) Edited once more: added "use" infront of "a mapper" and fixed my misspellings of "advice" : )


Top
 Profile  
 
PostPosted: Sat Feb 17, 2018 2:41 pm 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 887
Location: cypress, texas
Eisetley wrote:
I want to be able to set what CurrentSpawn means before calling LoadEnemies subroutine.
CurrentSpawn = spawn_test0
JSR LoadEnemies
CurrentSpawn = spawn_test1
JSR LoadEnemies

My, untested, pointer advice/example, from what I've learned so far: code is for Loopy's asm6
Code:
.enum $000
 CurrentSpawn .dsb 2  ;<the pointer
.ende

;then, somewhere in ROM
 ldx #00 ;or: ldx #01 ;anything higher than #01, in this example, will load incorrectly...
 ; because spawns_l and spawns_h only have 2 bytes each :)
 lda spawns_l, x
 sta CurrentSpawn+0
 lda spawns_h, x
 sta CurrentSpawn+1

;then inside LoadEnemies
;set y to whatever byte you want to read from the spawn_test loaded
 lda (CurrentSpawn), y

;then somewhere else in ROM
spawns_l:  .dl spawn_test0, spawn_test1 ;.db <spawn_test0, <spawn_test1
spawns_h:  .dh spawn_test0, spawn_test1 ;.db >spawn_test0, >spawn_test1

You could probably make your LoadEnemies faster than just calling lda (CurrentSpawn), y a bunch, I have to go, hopefully this example will help you or others to get started with pointers. :)

edit: Switched the order of spawns_h and spawns_l because, from my experience, it is less stressful for a NES game if you order the memory locations to mimic the order in which you use them. Since the low byte always comes first in a pointer, it makes sense, in my opinion, to order the bytes accordingly.


final edit: Am so very blessed to have discovered using Absolute Indexed by X for accessing the different groups of bytes in my sister's NES game. I wanted a really quick way of using pointers; I prayed about it and He helped me to solve that problem!! :mrgreen: :)


Top
 Profile  
 
PostPosted: Tue Mar 13, 2018 2:55 pm 
Offline
User avatar

Joined: Fri Feb 02, 2018 4:45 am
Posts: 5
Thanks for help, that's what I came up with at this point:
Code:
LoadEnemies:
  LDA MobLoadingStatus
  BEQ +
  RTS
  +
  LDX CurrentSpawnId
  LDA spawns_lo, x
  STA CurrentSpawn
  LDA spawns_hi, x
  STA CurrentSpawn + 1
  DEC CurrentSpawn

  LDY #$19 ;; copy first 25 bytes to ram
LoadEnemiesLoop1:
  LDA (CurrentSpawn), y
  STA MobAmount - 1, y
  DEY
  BNE LoadEnemiesLoop1

  LDY #$29 ;loop for 8 mobs, every loop stores 2 values -->cpy#$19
  LDX #$00
LoadEnemiesLoop2: ;;load last 16 bytes
  LDA (CurrentSpawn), y
  STA EnemyRam, x
  DEY

  LDA (CurrentSpawn), y
  STA EnemyRam + 3, x

  DEY
  CPY #$19
  BEQ +
  TXA
  CLC
  ADC #$10
  TAX
  JMP LoadEnemiesLoop2
  +
  INC MobLoadingStatus
  RTS


Code:
;;;;;TEST ROOM 0 - SPAWN;;;;;
;;room size =  41 bytes
spawn_test0:
;active mob amount
.db $08
;mob ids
.db #nettle, #nettle, #nettle, #nettle, #nettle, #nettle, #nettle, #nettle

;hp
.db $05, $05, $05, $05, $05, $05, $05, $05

;direction
.db #Mob_Dir_West, #Mob_Dir_East, #Mob_Dir_North, #Mob_Dir_West, #Mob_Dir_East, #Mob_Dir_East, #Mob_Dir_North, #Mob_Dir_West

    ;x   ;y
.db $20, $20    ;mob8
.db $30, $30    ;mob7
.db $40, $40    ;mob6
.db $50, $50    ;mob5
.db $60, $60    ;mob4
.db $70, $70    ;mob3
.db $80, $80    ;mob2
.db $90, $90    ;mob1


https://www.youtube.com/watch?v=3RzfjRgBO18

The only thing that bothers me is that I've had a really rough time loading the first value into the right place (;active mob amount .db $08). I've had to DEC the low byte to make it work.


Top
 Profile  
 
PostPosted: Tue Mar 13, 2018 4:04 pm 
Offline
User avatar

Joined: Fri May 08, 2015 7:17 pm
Posts: 2092
Location: DIGDUG
Array begins at zero.

see every programming joke written for reference. ;)

EDIT.
It seems you are exiting each loop before loading the 0th element.

_________________
nesdoug.com -- blog/tutorial on programming for the NES


Top
 Profile  
 
PostPosted: Tue Mar 13, 2018 10:01 pm 
Offline

Joined: Tue Feb 07, 2017 2:03 am
Posts: 449
Make sure you data is page aligned it XX00. Then make each array page aligned. Say you put the data at $9000 for example
Code:
* = $9000
Mob_IDs .db #oak, #oak, #oak, #oak, #oak, #oak, #oak, #oak, start screen 2 here...
align $100 ; not sure how do this in your assembler
Mob_HP .db $05, $05, $05, $05, $05, $05, $05, $05, start screen 2 here...
align $100
Mob_X .db $20, $20, $20, $20, $90, $85, $50, $C0, start screen 2 here...
align $100
Mob_Dir .db #Mob_Dir_West, #Mob_Dir_South, #Mob_Dir_North, #Mob_Dir_West, #Mob_Dir_East, #Mob_Dir_South, #Mob_Dir_North, #Mob_Dir_West, start screen 2 here...

Then you have 4 words in ZP ptrIDs,ptrHP,ptrX,ptrDir initilially you will load them as follows, but at some point you will get beyond 256 arrays being able to hold all spawn points
Code:
lda #0
sta ptrIDs
sta ptrHP
sta ptrX
sta ptrDir
ldx #>Mob_IDs
stx ptrIDs+1
inx
stx ptrHP
inx
stx ptrX
inx
stx ptrDir

Then you have a table of start and end index per screen
Code:
EnemySpawn_start .db 0,8
EnemySpawn_end .db 8,somevalue

to read the data you then do
Code:
ldx Screen
ldy EnemySpawn_start,x
lda EnemySpawn_end,x
sta ZPTemp
Loop
lda (ptrIds),y
; do something with it
lda (ptrHP),y
; do something with it
lda (ptrX),y
; do something with it
lda (ptrDir),y
; do something with it
iny
cpy ZPTEmp
bne Loop


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

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 2 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