First, a quick question: I noticed in some examples have instructions like "lda CameraY+0". Is that the same as "lda CameraY"? If not, what's the difference?
Ok, now to the main point of this post: I got to the point where I have to load big maps to the game, but I'm stumped. Up until now, I only had one 256x240 screen, so my approach was a simple loop that stored all 960 bytes into the PPU.
In my RPG, maps can have an arbitrary width and height (all I've stablished is that width must be multiple of 256 and height must be multiple of 240). So, the world map can be a very big map, while a town would be considerably smaller. The world map in Dragon Warrior 4, for example is 4096x3840 pixels. I don't know if mine will be as big, but it'll be pretty big too.
I'm feeling overwhelmed now, because I have no idea how to find the tiles I need to show on screen. It'd be so much easier if ASM could work with 2D arrays, but alas
Not only that, but I know a next step will be to implement a RLE compression on map data, so I'm afraid if I to work on a solution that doesn't consider it, I'll have to scrap it and think of something else because of the compression.
I've even considered rethinking how I'm storing map tile bytes. So far, I have stored as shown below. each number represents a byte in a 256x240 area. So, all 1's are byte that for the top left area (the top left 256x240 area). The 2's represent the bytes to the right of the area 1. Also, just because they are all 1's, it doesn't mean the bytes are the same, just that the bytes are from one area. So, for a map that is 4 screens width and 2 tall (1024 x 480 tiles), we have the following:
Code: Select all
11111111222222223333333344444444
11111111222222223333333344444444
11111111222222223333333344444444
11111111222222223333333344444444
11111111222222223333333344444444
11111111222222223333333344444444
55555555666666667777777788888888
55555555666666667777777788888888
55555555666666667777777788888888
55555555666666667777777788888888
55555555666666667777777788888888
55555555666666667777777788888888
I've even considered bundling all the bytes from each area together, but I think that'll make things more complicated.
Code: Select all
111111111111111111111111111111111111111111111111
222222222222222222222222222222222222222222222222
333333333333333333333333333333333333333333333333
444444444444444444444444444444444444444444444444
555555555555555555555555555555555555555555555555
666666666666666666666666666666666666666666666666
777777777777777777777777777777777777777777777777
888888888888888888888888888888888888888888888888
So, suppose I work with the first option.
- img5.png (2.65 KiB) Viewed 6964 times
When the screen loads up (e.g. after the map is just loaded), this is how I can get the bytes I need to display
1) I have to figure out what's the address of the byte on the top left tile within the camera, something like
Code: Select all
first_byte = start + (cameray * map_width) + camerax
2) Then, I'd have to loop go get all bytes in that row, so 32 times.
3) After that, I'd have to find the first byte of the next row. I can do that by adding the width to the first byte
Code: Select all
first_byte_in_row = prev_first_byte + map_width
4) go back to (2). Rules 2, 3 and 4 will be executed 30 times
Then, after I scroll to the right, for example:
1) get the first byte inside the camera, like (1) above
2) add 256 to it, so we have the byte right on the top left part that is to the right of what's displayed on screen
3) get byte 1 and byte 2 so we have a 16x16 tile
4) go to the next row, by adding "map_width" to the address we found in 2
5) go back to (3). repeat 3,4,5 30 times.
I want to make sure this is the idea, because if so, it involves a bunch of things I still don't know how to do in ASM, like 16 bit operations and multiplication. I also want to make sure that it's feasible to do these things the way I thought without causing lag and stuff
Also, will this idea work if my map is RLE compressed?