Points of Required Attention™
Please chime in on a proposed restructuring of the ROM hacking sections.
Views: 88,484,519
Main | FAQ | Uploader | IRC chat | Radio | Memberlist | Active users | Latest posts | Calendar | Stats | Online users | Search 04-26-24 01:56 AM
Guest: Register | Login

0 users currently in The Landfill | 2 guests

Main - The Landfill - Optimizing Tilemaps Around SNES Space Limitations New thread | Thread closed


cory21391
Posted on 03-25-10 05:53 AM (rev. 2 of 03-25-10 05:54 AM) Link | Quote | ID: 128844


Flurry
Level: 37

Posts: 255/260
EXP: 331857
Next: 6396

Since: 03-01-07
From: NC, US

Last post: 5128 days
Last view: 5128 days
I'm done setting up all of my graphics related subroutines (as far as Background/Sprite Graphics goes, anyways) and when I set up my template for tilesets (using Lunar Magic's 128 tile 4bpp sets) I realized something....

In my engine, I use a separate bank each for background tiledata, tilemaps, palettes, and sprite tiledata. And that's when I noticed it. Space limitations.

I'm using a slowrom lorom with 256 KB of space. each bank being 32,768 bytes leaves my tiledata bank big enough to hold 8 full 128 tile 4 bpp tilemaps (or 7 full 4bpp and 2 full 2bpp, which is what i was thinking of using.) Now this isn't too bad, I'm only using 5 banks (bank 0-code, 1-palettes, 2-tiledata, 3-tilemaps, and 4-sprites) leaving 3 free. Even if I say, save 2 more banks for code, that leaves an extra for tiledata, meaning I can now have 15 full 4bpp and 2 full 2bpp, which in turn is a decent amount of unigue tilesets, plus I can always reuse stuff here and there and whatnot.

1 bank for palettes is plenty, I don't kno spc programming (no sound) and I haven't gotten around to implementing HDMA yet, so no need for HDMA table storage (yet.)

All of this leads to my question about tilemaps regarding the space they take up.

A full 32x32 tile screen's tilemap is 4 KILOBYTES in size. 1 64x64 screen would then be 16 KILOBYTES
I can only store 8 32x32 tilemaps in a bank.

How in the hell do games like SMW with 20 or so screens (horizontally, mind you, 40 or so + including the upper screens) per level manage to store all of this data?!?!

Also to note that I know nothing about ROM configuration (I know you can expand it, but I don't know how or what that effects in terms of addressing or anything.)

Suggestions for how to drastically cut down tilemap space?

____________________




paulguy
Posted on 03-25-10 06:01 AM Link | Quote | ID: 128845


Flurry
Level: 37

Posts: 230/258
EXP: 326969
Next: 11284

Since: 04-10-07
From: Buffalo, NY

Last post: 5027 days
Last view: 4568 days

Super Mario World didn't store tilemaps in ROM. It stored object lists in ROM. When you played a level, these were then expanded in to tilemaps in RAM. These take up much less data since each object only has pretty much a type, position and maybe a size, depending on what it was, and most of these could cover a large amount of space for just a few bytes, rather than a few bytes for each tile.

I don't know the gritty details, since I don't even know assembly, but that's the extent of my understanding.

____________________
"In other news, Scientists theoretize that CHEESECAKE CHEESECAKE CHEESECAKE." --Blackhole89

Kawa
Posted on 03-25-10 05:08 PM Link | Quote | ID: 128873


CHIKKN NI A BAAZZKIT!!!
80's Cheerilee is best pony
Level: 138

Posts: 3430/5344
EXP: 30943947
Next: 719034

Since: 02-20-07
From: The Netherlands

Last post: 4498 days
Last view: 2633 days
Your understanding is spot on.

____________________
Wife make lunch - Shampoo
Opera - give it a spin
Spare some of your free time?
<GreyMaria> I walked around the Lake so many goddamn times that my sex drive was brutally murdered
Kawa rocks — byuu

MathOnNapkins
Posted on 03-25-10 05:58 PM Link | Quote | ID: 128879


Super Koopa
Level: 62

Posts: 757/842
EXP: 1935451
Next: 49235

Since: 02-19-07
From: durff

Last post: 4488 days
Last view: 4011 days
If you really need to store full tilemaps or larger collections of tilemap you could also consider a compression format if objects aren't appropriate for your design.

____________________
Zelda Hacking Forum
hobbies: delectatio morosa

cory21391
Posted on 03-28-10 06:34 PM (rev. 3 of 03-29-10 04:12 AM) Link | Quote | ID: 129063


Flurry
Level: 37

Posts: 256/260
EXP: 331857
Next: 6396

Since: 03-01-07
From: NC, US

Last post: 5128 days
Last view: 5128 days
I've taken a look at Lunar Magic to see what the average difference would be and WOW. my first level in Super Mario Journey is 16 screens, with each "screen" being 2 vertically stacked 32x32 screens, that would be a staggering 32,768 tiles, or 65,536 bytes of tilemap data! However when I selected all the FG object tiles, there were only 3116 tiles in the level, or 6,232 bytes of tilemap data. HUGE difference. So I decided to make a simple macro to read values from an object table to a tilemap copy in WRAM and then DMA that to VRAM. After creating the macro, however, and setting up a simple test table with only 1 tilemap entry, it won't compile for some reason. WLA seems to spit out errors that aren't all that helpful, so I thought maybe someone here could help me out with finding what the problem is.

The error message simply says:
INPUT_NUMBER: Out of 16bit range
ERROR: Couldn't parse "sta"

the table is in format:
table 1:
.dw [tilemap address]
.db [tilemap entry low byte]
.db [tilemap entry high byte]

tilemap WRAM copy is $800 bytes from $7e:2221-$7e:2A21
tilemap in VRAM is $1000 words from $0000-$0FFF (64x64 screen)

the code:
(8 bit A, 16 bit X/Y)

.MACRO load_fg_object_table
; MACRO CALL [object table address], [object table size]
ldx $00 ;initialize table pointer
table_end_loop_1:
ldy \1, x ; offset address in tilemap
inx
inx
lda \1, x ;first byte of tilemap entry data
sta $7e2221, y
inx
iny
lda \1, x ;second byte of tilemap entry data
sta $7e2221, y
inx

cpx #\2 ;compare to length of table
bne table_end_loop_1

;DMA THE DATA TO VRAM TILEMAP

lda #$80
sta $2115 ;initialize VRAM
ldx #$0000
stx $2116 ;start address in VRAM

lda #$7E ;WRAM bank
ldx #$2221 ;starting offset
ldy #$800 ;amount of bytes to copy
sta $4304 ;bank
stx $4302 ;offset
sty $4305 ;size
lda #$01
sta $4300 ;Set DMA mode (word, normal increment)
lda #$18
sta $4301 ;Set the destination register (VRAM write register)
lda #$01
sta $420B ;initiate DMA transfer
.ENDM


( table is in the main code section, bank 0)


table1:
.dw $0000
.db $02
.db $08



EDIT:
To make sure it wasn't a macro problem (like parameters), or length of address problem (like $7e2221) I tried the following code:


ldx #$00 ;initialize table pointer
table_test_loop:
lda Table_1, x
sta $0000, x
inx
cpx #$04
bne table_test_loop

loop:
jmp loop

Table_1:
.db $00
.db $00
.db $08
.db $02


The compiler error this time was:
FIX_REFERENCES: Value ($8458) of "Table_1" is too much to be a 8bit value.

This is even more baffling than the previous error.....
NOWHERE in my table is there anything remotely close to being $8458, and all my data types are in bytes (.db) in my table......

Any guesses as to what might be the problem?



____________________




cory21391
Posted on 04-01-10 05:22 PM Link | Quote | ID: 129319


Flurry
Level: 37

Posts: 259/260
EXP: 331857
Next: 6396

Since: 03-01-07
From: NC, US

Last post: 5128 days
Last view: 5128 days
I think I've narrowed the problem down. When I tried the code:

ldx #$05
lda table_1, x
sta $7e0000
loop:
jmp loop

table_1:
.db $80, $60, $70, $50, $65, $85, $65


The compiler gave the same error as before, FIX_REFERENCES value ($8454) of "Table_1" is too much to be an 8 bit value.

BUT, when I tried a hex address rather than a label, it worked.


ldx #$05
lda $2F3564, x
sta $7e0000
loop:
jmp loop


This can only lead me to believe that I'm doing something wrong in relation to addressing my table using labels and .db/.dw/.dl

Such a simple concept causing all these problems....

____________________




Aaendi
Posted on 04-10-10 11:49 PM Link | Quote | ID: 129722


Red Koopa
Level: 27

Posts: 78/131
EXP: 109187
Next: 6972

Since: 10-18-09

Last post: 4670 days
Last view: 4330 days
I don't know what your using, but I use Xkas and I write "org $008000" before my code, or else it doesn't find labels properly.

cory21391
Posted on 04-11-10 06:07 PM (rev. 2 of 04-11-10 10:27 PM) Link | Quote | ID: 129757


Flurry
Level: 37

Posts: 260/260
EXP: 331857
Next: 6396

Since: 03-01-07
From: NC, US

Last post: 5128 days
Last view: 5128 days
I'm using WLA, I'm assuming org $008000 is similar to the WLA code, .ORG XX, which sets SNES cart slot or something like that...

My full code (after taking out everything unrelated to this table problem):


;==========
;HEADER
;==========
.INCLUDE "I:\Projects\src\header\myheader.inc"
; header I made based on some tutorial I read
.INCLUDE "I:\Projects\src\header\snesinit.inc"
; initialization routine from vintage dev tutorials

;==========
;LIBRARY
;==========
.INCLUDE "I:\Projects\src\library\macros.inc"
.INCLUDE "I:\Projects\src\library\subroutines.inc"

;==========
;MAIN
;==========
.BANK 0
.ORG 0 ;Here's the .ORG statement which sets snes slot to default 0
.SECTION "Main"
Start:
InitSNES
sep #$20 ;8 bit A
rep #$10 ;16 bit X/Y

lda TABLE1 ;8 bit A loading 8 bit values (.db) from the label TABLE1

-:
bra -

TABLE1:
.db $45, $56, $78, $89, $12

.ENDS


Get the error:
FIX_REFERENCES: Value ($830F) of "TABLE1" is too much to be a 8 bit value.

This is very confusing, I'm using .db, there is no $830F in my table anywhere, even if there is word values in my table, the Accumulator is 8 bit and should just read 1 byte of it.... Thinking it was a problem with loading into A, supposedly being larger than 8 bits, I changed it to ldx TABLE1, AND GET THE SAME ERROR.

If anyone knows what could be wrong I'd really appreciate some help on this because logically to me, it should work perfectly, and I need tables not just to save rom space with tilemaps, but I'm quite sure I'll need them later on when I'm actually putting together game code....

Here's the full source if anyone wants to take a look.


EDIT:
To clarify about labels not working correctly:

Labels work fine with direct addressing (like in my dma macros, loading the register with the argument))
ex.
lda #LABEL
sta $4302

The problem is absolute addressing (loading by using the argument as an offset address and loading from said offset)
ex.
lda LABEL
sta $7e0000


____________________




dieudunet
Posted on 01-19-11 09:25 AM Link | Quote | ID: 139213

Newcomer
Level: 3

Posts: 1/1
EXP: 69
Next: 59

Since: 01-19-11

Last post: 4845 days
Last view: 4845 days
Hello,

the WLA Compiler is a little weird it seems.

try loading your Table_1 using

lda.w Table_1,x

It works for me

Kawa
Posted on 01-19-11 09:25 PM Link | Quote | ID: 139224


CHIKKN NI A BAAZZKIT!!!
80's Cheerilee is best pony
Level: 138

Posts: 4404/5344
EXP: 30943947
Next: 719034

Since: 02-20-07
From: The Netherlands

Last post: 4498 days
Last view: 2633 days
Hello dieudunet.

Thank you for making such an informative post. However, I must ask you to watch the time stamps (noted at the top of each post) to try not to post in threads that are several months old. You may notice that Cory's post was from April 2010. It is now January 2011.

Please be more careful in the future.


And yeah WLA is kinda strange.

____________________
Wife make lunch - Shampoo
Opera - give it a spin
Spare some of your free time?
<GreyMaria> I walked around the Lake so many goddamn times that my sex drive was brutally murdered
Kawa rocks — byuu

Main - The Landfill - Optimizing Tilemaps Around SNES Space Limitations New thread | Thread closed

Acmlmboard 2.1+4δ (2023-01-15)
© 2005-2023 Acmlm, blackhole89, Xkeeper et al.

Page rendered in 0.020 seconds. (323KB of memory used)
MySQL - queries: 73, rows: 91/93, time: 0.014 seconds.