Jump to content

Photo

DrawMap Example


9 replies to this topic

#1 saboteur OFFLINE  

saboteur

    Chopper Commander

  • 120 posts

Posted Mon Nov 5, 2018 3:09 AM

Finally managed to get some time this weekend and went back through my manicminer experiments and started plowing back through it.

 

Whilst I was doing this i noticed the drawmap.bas example in projects and got waylaid playing with that.

 

I have got it running as expected when using 4bpp tiles of 8x8 no problem.

 

However I cannot get it to work when using 16x16 tiles.

for map=0 to no_maps-1
    ' Draw map
    for y=0 to map_height-1
        for x=0 to map_width-1
            c=maps[map*map_height+y][x]
            tilex=(c % map_width)
            tiley=(c/map_width)
            for i=0 to 7
                ' Our tiles are 16x8 big in 4bpp mode, which means they are 8 bytes wide in RAM. Hence we need 2 LPOKEs per line.
                 lpoke strptr(scrbuf)+y*(dest_screen_width_in_bytes*tile_height)+x*tile_width_in_bytes+i*dest_screen_width_in_bytes,lpeek(strptr(tiles)+tilex*tile_width_in_bytes+tiley*(src_screen_width_in_bytes*tile_height)+i*src_screen_width_in_bytes)
                 lpoke strptr(scrbuf)+y*(dest_screen_width_in_bytes*tile_height)+x*tile_width_in_bytes+i*dest_screen_width_in_bytes+4,lpeek(strptr(tiles)+tilex*tile_width_in_bytes+tiley*(src_screen_width_in_bytes*tile_height)+i*src_screen_width_in_bytes+4)
            next i
        next x
    next y

    'Bring the map to screen
    for ph=0 to pi/2 step pi/90/2
        rlist[1].x=(352-sin(ph)*336)*65536
        vsync
    next i

Now i notice there is a loop for i=0 to 7 and I assumed this was for buidling the 8 rows of the original 16x8 or my 8x8 tiles. But if I change the tile height to 16 and set this loop to be 0 to 15 it just hangs.

 

so am i misunderstaning this.

 

On the plus side I have tile collision working based on the 8x8 tiles :) it's just my player sprite is 16x16 so it makes sense to draw the map based on 16x 16 tiles as well.

 

cheers

 

 



#2 ggn ONLINE  

ggn

    Stargunner

  • 1,452 posts
  • Location:Athens, Greece

Posted Mon Nov 5, 2018 3:38 AM

I should probably apologise for that code, it really doesn't look like anyone can understand it easily :). So I'll break the loops down so you can see what happens:

- First of all, you need to set up map_width and map_height properly to the dimensions of your map. The default values there are 20 and 20 respectively. That's for 16x8 tiles. So if you want to switch to 16x16 map_height will need to be halved, i.e. set it to 10.
- The y for...loop will run for as many times we set the value of map_height
- The x for...loop will run for as many times we set the value of map_width per line
- The i for...loop will do the actual tile drawing. Since your tiles have a height of 16, this needs to be changed to 16-1=15

Hopefully it makes more sense now?

Another thing to mention here is that the 2 lpokes are written in such a convoluted fashion in order to show people how to actually calculate the tile's screen address from scratch. So you could put that code inside a subroutine for any purpose (say you need to change a tile in-game).

Actually, I'll make some changes to the code and will put it up on github/bitbucket in a bit.

[EDIT] Done! https://github.com/g...awmap.bas#L1087
 
sub drawtile(x as SHORT, y as SHORT)
    for i=0 to map_height-1
        ' Our tiles are 16x8 big in 4bpp mode, which means they are 8 bytes wide in RAM. Hence we need 2 LPOKEs per line.
         lpoke strptr(scrbuf)+y*(dest_screen_width_in_bytes*tile_height)+x*tile_width_in_bytes+i*dest_screen_width_in_bytes,lpeek(strptr(tiles)+tilex*tile_width_in_bytes+tiley*(src_screen_width_in_bytes*tile_height)+i*src_screen_width_in_bytes)
         lpoke strptr(scrbuf)+y*(dest_screen_width_in_bytes*tile_height)+x*tile_width_in_bytes+i*dest_screen_width_in_bytes+4,lpeek(strptr(tiles)+tilex*tile_width_in_bytes+tiley*(src_screen_width_in_bytes*tile_height)+i*src_screen_width_in_bytes+4)
    next i
end sub
It is of course still tied to 16 pixels horizontally so with a bit of copy/pasting and changing offsets one could create versions for other widths!

P.S. I also had a bit of fun with object's vertical movement, it looked so boring before :)

Edited by ggn, Mon Nov 5, 2018 3:53 AM.


#3 saboteur OFFLINE  

saboteur

    Chopper Commander

  • Topic Starter
  • 120 posts

Posted Mon Nov 5, 2018 4:04 AM

Thanks for the info GGN - the i loop was what was throwing me out i think.

 

I'll let you know how i get on.

 

cheers


Edited by saboteur, Mon Nov 5, 2018 4:05 AM.


#4 saboteur OFFLINE  

saboteur

    Chopper Commander

  • Topic Starter
  • 120 posts

Posted Mon Nov 5, 2018 4:58 AM

OK still no joy.

 

So my source image is 48x16px = 24bytes ( 3 tiles of 16x16 )

 

if i set the tile height at 8px i get a map displayed but obviously all tile heights are half height.

 

If I change the tile height to 16px it all goes horibly wrong and crashes

 

Now as I undertsand it I shouldn't neet to change the POKES cos i'm still only doing 16px in 2  4 byte lumps.

 

Any ideas ?



#5 ggn ONLINE  

ggn

    Stargunner

  • 1,452 posts
  • Location:Athens, Greece

Posted Mon Nov 5, 2018 5:10 AM

OK still no joy.
 
So my source image is 48x16px = 24bytes ( 3 tiles of 16x16 )
 
if i set the tile height at 8px i get a map displayed but obviously all tile heights are half height.
 
If I change the tile height to 16px it all goes horibly wrong and crashes
 
Now as I undertsand it I shouldn't neet to change the POKES cos i'm still only doing 16px in 2  4 byte lumps.
 
Any ideas ?


Let me get this straight, do you feed your code 16x16 tiles? i.e. did you cut your tile data to 16x16 chunks or are they 48x16?

Still curious as to why this should crash, it probably starts drawing outside of the destination object.

Worst case if you can't figure it out you can upload what you have here and I'll take a look.

#6 saboteur OFFLINE  

saboteur

    Chopper Commander

  • Topic Starter
  • 120 posts

Posted Mon Nov 5, 2018 5:25 AM

The source image is 48x16px - so made up of 3 16x16px tiles

 

As I said when I set the tile height to 8px it all works fine except each tile is displayed half height - as I would expect.

 

However no map is displayed when setting tile height to 16px 

'
' Your code goes here
' Have fun!
'
rlist=(RAPTOR_LIST *)strptr(RAPTOR_sprite_table)
basic_r_indx=0
basic_r_size=0
'RLOCATE 0,202
'RPRINT "          RAPTOR BASIC+ - REBOOT        "
'basic_r_size=0
'basic_r_indx=0
'RLOCATE 0,218
'RPRINT "        Derived from BCX BASIC v6       "


DIM ID_player%
DIM GVAR_player_gfx_loc%
DIM GVAR_player_gfx_size%

ID_player    	  = 2						' RAPTOR Object number for player


'GVAR_player_gfx_loc  = RGETOBJ(ID_player, R_sprite_gfxbase)
'GVAR_player_gfx_size = RGETOBJ(ID_player, R_sprite_framesz)

set maps[15][20] as short
	'01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20
	{00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00},	' screen 1 row 01
	{00,01,02,01,02,01,02,01,02,01,02,01,02,01,02,01,02,01,02,00},	' screen 1 row 02
	{00,02,01,02,01,02,01,02,01,02,01,02,01,02,01,02,01,02,01,00},	' screen 1 row 03
	{00,01,02,01,02,01,02,01,02,01,02,01,02,01,02,01,02,01,02,00},	' screen 1 row 04
	{00,02,01,02,01,02,01,02,01,02,01,02,01,02,01,02,01,02,01,00},	' screen 1 row 05
	{00,01,02,01,02,01,02,01,02,01,02,01,02,01,02,01,02,01,02,00},	' screen 1 row 06
	{00,02,01,02,01,02,01,02,01,02,01,02,01,02,01,02,01,02,01,00},	' screen 1 row 07
	{00,01,02,01,02,01,02,01,02,01,02,01,02,01,02,01,02,01,02,00},	' screen 1 row 08
	{00,02,01,02,01,02,01,02,01,02,01,02,01,02,01,02,01,02,01,00},	' screen 1 row 09
	{00,01,02,01,02,01,02,01,02,01,02,01,02,01,02,01,02,01,02,00},	' screen 1 row 10
	{00,02,01,02,01,02,01,02,01,02,01,02,01,02,01,02,01,02,01,00},	' screen 1 row 11
	{00,01,02,01,02,01,02,01,02,01,02,01,02,01,02,01,02,01,02,00},	' screen 1 row 12
	{00,02,01,02,01,02,01,02,01,02,01,02,01,02,01,02,01,02,01,00},	' screen 1 row 13
	{00,01,02,01,02,01,02,01,02,01,02,01,02,01,02,01,02,01,02,00},	' screen 1 row 14
	{00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00}	' screen 1 row 15


end set

loadclut(strptr(tiles_clut),0,16)

dim x as short
dim y as short
dim c as short
dim tilex as short
dim tiley as short
dim map as short
dim i as int
DIM pi!: pi=3.1415926535897932384626433832795
dim ph!

' The screen to draw the map's width in bytes.
' Think of this as <width in pixels>*<bits per pixel>/8
const dest_screen_width_in_bytes=160
' Our tile's height in pixels
const tile_height=16
' Our tile's width in bytes.
' Think of this as <width in pixels>*<bits per pixel>/8
const tile_width_in_bytes=8
' Number of available maps.
const no_maps=1
' The screen to read the tile's width in bytes.
' Think of this as <width in pixels>*<bits per pixel>/8
const src_screen_width_in_bytes=24
' Map width inside the map array
const map_width=20
' Map height inside the map array
const map_height=15

map=0
    ' Draw map
	for y=0 to map_height-1
        for x=0 to map_width-1
            c=maps[map*map_height+y][x]
            tilex=(c % map_width)
            tiley=(c/map_width)
		
			drawtile(x,y)
        next x
    next y

        rlist[1].x=19*65536
        vsync

do
	call Player_Update_Position
	vsync
loop


sub drawtile(x as SHORT, y as SHORT)

    for i=0 to map_height-1

        ' Our tiles are 16x16 big in 4bpp mode, which means they are 8 bytes wide in RAM. Hence we need 2 LPOKEs per line.
         lpoke strptr(scrbuf)+y*(dest_screen_width_in_bytes*tile_height)+x*tile_width_in_bytes+i*dest_screen_width_in_bytes,lpeek(strptr(tiles)+tilex*tile_width_in_bytes+tiley*(src_screen_width_in_bytes*tile_height)+i*src_screen_width_in_bytes)
         lpoke strptr(scrbuf)+y*(dest_screen_width_in_bytes*tile_height)+x*tile_width_in_bytes+i*dest_screen_width_in_bytes+4,lpeek(strptr(tiles)+tilex*tile_width_in_bytes+tiley*(src_screen_width_in_bytes*tile_height)+i*src_screen_width_in_bytes+4)

    next i

end sub

could it be anything to do with rapinit?

 

cheers



#7 saboteur OFFLINE  

saboteur

    Chopper Commander

  • Topic Starter
  • 120 posts

Posted Mon Nov 5, 2018 5:47 AM

this is what i get using 8 pixels height

 

8xtileheight.png



#8 ggn ONLINE  

ggn

    Stargunner

  • 1,452 posts
  • Location:Athens, Greece

Posted Mon Nov 5, 2018 12:48 PM

First of all - sorry, stuff got in the way and I forgot about this!

Anyway, after fiddling around with your source I think I pinpointed your problem: It is indeed what you suspected. In your rapinit.s your screen object is probably still defined as 320x200. BUT your map height is 15 blocks! Which means that raptor reserves 320*200 bytes for the object while you request 320x(15x16)=320x240! So the poor tile drawer was writing outside the object, so it was either corrupting raptor stuff or going off RAM :).

Try that and let us know what happens!

#9 saboteur OFFLINE  

saboteur

    Chopper Commander

  • Topic Starter
  • 120 posts

Posted Mon Nov 5, 2018 2:36 PM

Thanks for the reply.

 

No need to apologise - your helping me, not the other way around :)

 

Anyhoo - nearly there, I had already changed the rapinit as you sugested but it still wouldn't work.

 

However, it got me thinking so i checked the blank.bmp and that wasn't the same size.

 

Also the drawtile procedure loop is wrong I think. Currently it's 

 

for i=0 to map_height-1

 

I think you meant 

 

for i=0 to tile_height-1

 

Now it works but the bottom row is not on the screen - so a bit of fettling and I think i'll be there.

 

Thanks for all the help - it really is appreciated.


  • ggn likes this

#10 ggn ONLINE  

ggn

    Stargunner

  • 1,452 posts
  • Location:Athens, Greece

Posted Mon Nov 5, 2018 2:48 PM

Thanks for the reply.
 
No need to apologise - your helping me, not the other way around :)
 
Anyhoo - nearly there, I had already changed the rapinit as you sugested but it still wouldn't work.
 
However, it got me thinking so i checked the blank.bmp and that wasn't the same size.
 
Also the drawtile procedure loop is wrong I think. Currently it's 
 
for i=0 to map_height-1
 
I think you meant 
 
for i=0 to tile_height-1
 
Now it works but the bottom row is not on the screen - so a bit of fettling and I think i'll be there.
 
Thanks for all the help - it really is appreciated.


Glad to see it works for you now :). Also, well spotted! I wonder why it didn't explode for me when I tested it... Anyway I'll upload a fixed version in a bit!



Reply to this topic



  


0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users