It is currently Mon Sep 25, 2017 10:23 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 7 posts ] 
Author Message
PostPosted: Thu Dec 22, 2016 6:43 pm 
Offline
User avatar

Joined: Sun Jul 29, 2012 9:58 am
Posts: 19
Location: Mexico
My NES project will be similar to SMB1 and I actually need to compress the levels. So while searching around here, I've seen people that recomends to make the map data to object-based format. So how do I do object-based? Any ideas, tutorials, or other suggestions? P.S: It's about a side scrolling game.


Top
 Profile  
 
PostPosted: Thu Dec 22, 2016 7:02 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10017
Location: Rio de Janeiro - Brazil
I believe that object based maps can't be easily drawn to the screen or checked for collisions directly, so you'll most likely need to have a grid based buffer in RAM where to decompress your maps ahead of time, and then use that buffer for drawing and for collisions.

As for how the maps are stored, that's ultimately up to you. Each screen could be defined by a list of objects, each with an ID (which could be used to look up entries in a table containing addresses of routines that handle each type of object) followed by the parameters necessary to define that object (x and Y coordinates, width, height, color, and so on).


Top
 Profile  
 
PostPosted: Fri Dec 23, 2016 2:54 pm 
Offline
User avatar

Joined: Mon Dec 07, 2009 11:08 am
Posts: 78
Location: USA
SMB1 disassemblies may be helpful:

* http://www.romhacking.net/documents/344/
* https://gist.github.com/1wErt3r/4048722

For an example, here is an encoded level from my game Nebs & Debs which uses a similar format to SMB1. This is generated from a Tiled tmx file via a ruby script. Objects are like SMB1 objects and the metasprites are actors and powerups, etc:

Code:
.code
.include "../src/objects/objects.h"
.include "../src/tiles/tiles.h"
.include "../src/palettes/palettes.h"

.segment "RODATA"
.proc mines1_1
  ; sprite palette
  .byte palette_names::hero_pal
 
  ; background palette
  .byte palette_names::background_pal
 
   ; default tile ID
   .byte object_names::sky
 
   ; scene width
   .byte 224

   ; trigger count
   .byte 0

   ; object count
   .byte 84

   ; object IDs
   .word object_ids

   ; object column positions
   .word object_cols

   ; object row and length bytes
   .word object_row_lens

   ; object width and collision bytes
   .word object_width_cols
   
  ; metasprite count
  .byte 46
   
  ; metasprite IDs
   .word metasprite_ids

   ; metasprite column positions
   .word metasprite_cols

   ; metasprite row and length bytes
   .word metasprite_rows

   object_ids:
      .byte object_names::floor, object_names::plants, object_names::floor_shadow, object_names::floor, object_names::plants, object_names::floor, object_names::plants, object_names::floor, object_names::plants, object_names::floor_shadow, object_names::plants, object_names::floor, object_names::floor, object_names::plants, object_names::plants, object_names::floor, object_names::floor, object_names::floor, object_names::plants, object_names::plants, object_names::floor, object_names::floor_shadow, object_names::floor, object_names::plants, object_names::floor, object_names::floor_shadow, object_names::floor, object_names::plants, object_names::abyss, object_names::floor, object_names::plants, object_names::floor, object_names::plants, object_names::floor, object_names::floor_shadow, object_names::plants, object_names::floor, object_names::plants, object_names::abyss, object_names::floor, object_names::floor, object_names::plants, object_names::floor, object_names::plants, object_names::abyss, object_names::floor_shadow, object_names::floor, object_names::plants, object_names::floor_shadow, object_names::plants, object_names::floor, object_names::floor_shadow, object_names::floor, object_names::plants, object_names::abyss, object_names::floor, object_names::floor, object_names::plants, object_names::abyss, object_names::floor, object_names::floor, object_names::abyss, object_names::plants, object_names::floor_shadow, object_names::floor, object_names::floor, object_names::floor_shadow, object_names::floor, object_names::plants, object_names::floor, object_names::plants, object_names::floor_shadow, object_names::plants, object_names::floor, object_names::plants, object_names::floor_shadow, object_names::floor, object_names::plants, object_names::floor, object_names::plants, object_names::floor, object_names::abyss, object_names::plants, object_names::floor

   object_cols:
      .byte 0, 0, 9, 9, 9, 15, 15, 21, 21, 21, 21, 21, 28, 28, 31, 31, 37, 38, 39, 43, 43, 43, 43, 43, 47, 47, 48, 48, 49, 52, 52, 54, 55, 55, 55, 56, 58, 58, 64, 68, 71, 72, 76, 76, 80, 83, 83, 83, 89, 89, 89, 93, 93, 93, 96, 96, 98, 100, 105, 108, 109, 110, 111, 111, 111, 121, 123, 123, 123, 138, 138, 146, 146, 146, 156, 156, 156, 164, 164, 171, 171, 178, 181, 181

   object_row_lens:
      .byte 60, 27, 26, 25, 24, 45, 28, 60, 23, 25, 27, 24, 90, 25, 28, 45, 60, 27, 27, 28, 45, 26, 25, 24, 23, 24, 22, 21, 30, 45, 28, 28, 23, 24, 25, 28, 60, 27, 45, 60, 42, 27, 42, 25, 45, 28, 57, 24, 23, 21, 22, 23, 22, 21, 30, 59, 21, 21, 29, 44, 36, 45, 21, 28, 42, 21, 27, 41, 24, 105, 24, 23, 21, 22, 21, 23, 22, 21, 150, 18, 195, 45, 27, 60

   object_width_cols:
      .byte 143, 143, 133, 133, 133, 134, 134, 135, 133, 133, 135, 133, 131, 131, 134, 134, 134, 129, 132, 134, 134, 131, 131, 131, 131, 131, 130, 130, 131, 134, 130, 130, 131, 131, 131, 130, 134, 134, 132, 140, 129, 132, 132, 132, 144, 134, 134, 134, 130, 130, 130, 158, 158, 133, 142, 137, 130, 137, 131, 130, 130, 156, 138, 134, 134, 130, 141, 141, 141, 154, 154, 133, 133, 133, 133, 133, 133, 135, 135, 135, 135, 131, 154, 154

  metasprite_ids:
      .byte metasprite_names::balloon, metasprite_names::balloon, metasprite_names::balloon, metasprite_names::balloon, metasprite_names::balloon, metasprite_names::balloon, metasprite_names::balloon, metasprite_names::balloon, metasprite_names::balloon, metasprite_names::balloon, metasprite_names::balloon, metasprite_names::balloon, metasprite_names::balloon, metasprite_names::z65, metasprite_names::balloon, metasprite_names::balloon, metasprite_names::balloon, metasprite_names::balloon, metasprite_names::balloon, metasprite_names::z65, metasprite_names::z65, metasprite_names::z65, metasprite_names::balloon, metasprite_names::z65, metasprite_names::balloon, metasprite_names::balloon, metasprite_names::balloon, metasprite_names::z65, metasprite_names::z65, metasprite_names::balloon, metasprite_names::z65, metasprite_names::balloon, metasprite_names::balloon, metasprite_names::balloon, metasprite_names::z65, metasprite_names::balloon, metasprite_names::balloon, metasprite_names::z65, metasprite_names::balloon, metasprite_names::balloon, metasprite_names::balloon, metasprite_names::balloon, metasprite_names::balloon, metasprite_names::balloon, metasprite_names::balloon, metasprite_names::balloon

   metasprite_cols:
      .byte 10, 12, 17, 21, 22, 24, 25, 29, 31, 38, 38, 41, 41, 47, 51, 53, 55, 61, 66, 73, 75, 95, 100, 101, 101, 103, 104, 106, 113, 117, 118, 121, 132, 134, 149, 151, 155, 160, 165, 169, 179, 179, 179, 179, 179, 182

   metasprite_rows:
      .byte 6, 6, 6, 5, 4, 4, 5, 6, 6, 9, 7, 9, 7, 12, 5, 5, 6, 6, 6, 11, 11, 4, 9, 5, 8, 8, 9, 5, 5, 8, 5, 8, 6, 6, 5, 4, 4, 8, 3, 1, 7, 9, 11, 3, 5, 11

.endproc


Top
 Profile  
 
PostPosted: Fri Dec 23, 2016 3:43 pm 
Offline
User avatar

Joined: Fri May 08, 2015 7:17 pm
Posts: 1734
Location: DIGDUG
Here's a quick rundown of how SMB does level compression...

It gets 2 pointers to data, at the start of the level, one for BG objects, one for Sprite Objects (Enemies).

For greater compression, a byte may contain 2+ pieces of information...like the top 2 bits for, type of level, bottom 6 bits for which level, within that type.

The level type (water, castle, hills, underground) is used to set the palette, the music, etc.

There is a master room pattern, like...1 ceiling, 8 sky, 2 floor. This is often changed on the fly, for example, in the underground or in castles. Once it is set, it will automatically draw that pattern Left to Right.

Then, each data byte describes how to draw things...starting at X=3, Y=6, draw 3 bricks left to right. Starting at X=5, Y=7, draw 6 coins...starting at X=7, draw a gap in the floor.

And there's a bit for...wait until you cross into the next room, then draw object Z here...

And, like tokumaru said, there is a collision map in the RAM that is also drawn, as you scroll.

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


Top
 Profile  
 
PostPosted: Sat Jan 28, 2017 11:16 pm 
Offline
User avatar

Joined: Sun Jul 29, 2012 9:58 am
Posts: 19
Location: Mexico
OK, as for the attributes what do you recommend? A separated array to store them, or to include them in the list of objects? In order to both load the level and scrolling. I use 16x16 pixel metatiles ( 4 groups of 8x8 pixel tiles squared ) and as far as I know in the attribute table, the areas are 32x32 pixels-sized. Any good ideas to align?


Top
 Profile  
 
PostPosted: Sun Jan 29, 2017 5:57 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10017
Location: Rio de Janeiro - Brazil
After deciding on an object based format to save space, wasting 64 bytes per screen on attributes hardly sounds like the most sensible solution, don't you think? It might be (much) easier, but so is using uncompressed 960-byte name tables.

Anyway, attributes on the NES aren't very fun to work with, but once you understand how you can use bitwise operations (AND, OR, XOR) to clear/set/toggle individual bits of a byte, you can easily manipulate the 16x16-pixel attribute areas.

DRW recently had the exact same problem: viewtopic.php?f=2&t=15396


Top
 Profile  
 
PostPosted: Sun Feb 05, 2017 6:57 am 
Offline

Joined: Mon May 27, 2013 9:40 am
Posts: 348
I personally use a lookup table which tell me exactly which bits I should OR for each kind of 16x16 metatile when located on each of the 4 possible positions inside of an attribute, so printing new metatiles is easy and fast.

_________________
http://www.mojontwins.com


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

All times are UTC - 7 hours


Who is online

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