Super Mario Land

Use this forum to share and discuss Uzebox games and demos.
User avatar
nicksen782
Posts: 666
Joined: Wed Feb 01, 2012 8:23 pm
Location: Detroit, United States
Contact:

Super Mario Land

Post by nicksen782 » Sun Jun 16, 2019 8:40 pm

I'm working on something new!

Super Mario Land. This was a Gameboy game released in 1989. I played this a lot as a young kid and really want to try to port it to the Uzebox.

It will use SPIRAM. I've just started but I have all the graphical assets ready and reduced. The background tile counts are at 206 and the title screen is at 100. Sprite tiles are around 298 and I'll be splitting them up into separate tilesets. Currently, that is 604 in total taking up 38656 bytes. I may still do further sprite tile reductions too. I'll need to set aside some room for music as well but that will be using SPIRAM streaming music so it won't cost a whole lot.

I'll update as I reach milestones. I still need to figure out how to handle sprite spawning and behavior. Fortunately, the game doesn't have many sprites on screen and I can keep coins and super flowers as background tiles. I want to do a horizontal screen split at the top where the score and stuff will be. That way I can use a dedicated tileset for the fonts. Only occasionally are font tiles on the lower screen. I'm thinking of just copying tiles into ram tiles and displaying them that way.

Go Uzebox!

P.S. I've attached a .uze file that scrolls through World 1-1.
Attachments
SuperMarioLand_W1_1_SCROLL.uze
(28.15 KiB) Downloaded 28 times

User avatar
uze6666
Site Admin
Posts: 4448
Joined: Tue Aug 12, 2008 9:13 pm
Location: Montreal, Canada
Contact:

Re: Super Mario Land

Post by uze6666 » Tue Jun 18, 2019 5:12 am

Oh my, you struck a chord! I had this game the year it got out...so this is so amazing to see on the Uzebox! I always though porting Super Mario Land would be much easier than say SMB because of the smaller sprites. I am definitely willing to port the music for this if you work out the rest! And while we are there, we have to do a full color version, the Internets will love it. :geek: :mrgreen:

I didn't do the calculations, but do you think this could fit the stock Uzebox resources using Jubatian's palette modes?

User avatar
nicksen782
Posts: 666
Joined: Wed Feb 01, 2012 8:23 pm
Location: Detroit, United States
Contact:

Re: Super Mario Land

Post by nicksen782 » Tue Jun 18, 2019 4:14 pm

Thanks! Yes, I would appreciate your help with music and sound effects.

I've attached my current version. It scrolls through all the levels. It works fine on the emulator but has artifacts and other inconsistencies on hardware at the moment. I remember running into this in the past but remember fixing it somehow. I'll have to look through old code and see what I did. Something to do with the CS pins I think. I had the same problem with my normal TV Uzebox an the portable. The portable screen appears to "tear" a bit when scrolling. I'm doing tile scrolling, not the smooth scrolling in my current demos.

I got to 55k with the sprite tiles included and the tilemaps on SPIRAM. Unless there was some awesome compression I don't think I could fit the tilemaps for the worlds without SPIRAM. Since it is scrolling right it isn't just a matter of grabbing a block of bytes. I need random access so SD scrolling would likely be very slow. Perhaps I could cache a few columns or something in RAM and use some sort of circular buffer though. I'm still thinking to use SPIRAM though.

I'm already thinking of a way to use ram sprites for the enemies (or at least some of them.) There aren't many enemy sprites on screen at a time so I think I may be able to get away with it. That can save me some flash.

As for color my maps were original the black and white (Gameboy Pocket) colors and I recolored them to the original DMG green colors. Right before compile it wouldn't be hard to recolor the tiles for a black/white mode or original green mode. I'm not sure about the enemy sprites, probably could do the same thing including with color. I grew up with the green screen so I thought to use that. It was really cool seeing it on the Uzebox screen.

So, each level map is 18 tiles high. However, the top two rows are always the same and are used for the score and stuff. So, really, world maps are 16 tiles high. However, I couldn't read from the SD card when the VRAM_TILES_V was 18. It only started to work when I set it to 21. So, I'm doing a SetRenderingParameters(FIRST_RENDER_LINE, FRAME_LINES-(8*3)); to fix the view. Any idea why this might be?

I really am only familiar with mode 3 no scrolling. It is based on a Gameboy game so I didn't even consider palettes. I'm not against a new video mode.

I've attached an auto scrolling demo of all worlds. Uses SPIRAM. You'll need the emulator since it doesn't work on the hardware correctly at this point.
Attachments
sml.zip
(25.31 KiB) Downloaded 22 times

User avatar
Jubatian
Posts: 1355
Joined: Thu Oct 01, 2015 9:44 pm
Location: Hungary
Contact:

Re: Super Mario Land

Post by Jubatian » Tue Jun 18, 2019 7:05 pm

Huh, this looks neat! :)

I was thinking about which video mode might be underneath, but it may not matter that much. The Gameboy would fit particularly well for Mode 52, however if you are primarily tile count constrained, it doesn't help. Here you certainly won't quite have any sprite drawing bottleneck either due to the very narrow screen (lots of VBlank time), and if you have a single tileset, Mode 52 won't help in ROM usage either (as the mode's code is much bigger than Mode 3's).

Some of the artifacts may esaily be the result of incorrect sync, you will need to look into that, the observable sync defects are such which could confuse some TV sets.

Which SD library are you using? The new bootloader one has a slight problem that if you have too much VBlank time, the SD init timeouts might become too short (notably not taking at least one frame as the timeout elapses before the frame interrupt would strike). You could offset this even by choosing a more complex mixer to throw CPU resources at something useful. I only noticed it for completely disabled video frame though. Other libraries might have similar problems as all of them use a simple polling loop.

User avatar
nicksen782
Posts: 666
Joined: Wed Feb 01, 2012 8:23 pm
Location: Detroit, United States
Contact:

Re: Super Mario Land

Post by nicksen782 » Wed Jun 19, 2019 1:34 pm

I have around 600 tiles. Is that too many for mode 52?

At this point in the demo I'm scrolling with tiles (not smooth.) Of course, the sprites, especially the player sprite, will need to move smooth. Smooth and not smooth together will likely appear jerky. I don't know. Maybe I can make it work.

It isn't really artifacts. It is incorrect tile ids. Most of the screen may draw but a few lines near the top will be totally incorrect. Sometimes it all displays wrong. I've noticed that reducing VRAM_TILES_V lower that 21 (I need 18) would give me error 4 on SD init. I've also noticed that I would get an error if I set SetRenderingParameters to one line. Is this a bug in the SD code then? I'm using the bootlib library (yours.)

So, what the the pros/cons of video mode 3 vs video mode 52 in this game's case? I don't really need color palettes unless I create a color version (which I may eventually.)

User avatar
Jubatian
Posts: 1355
Joined: Thu Oct 01, 2015 9:44 pm
Location: Hungary
Contact:

Re: Super Mario Land

Post by Jubatian » Wed Jun 19, 2019 6:58 pm

nicksen782 wrote:
Wed Jun 19, 2019 1:34 pm
I have around 600 tiles. Is that too many for mode 52?
I didn't even consider that you were swapping tilesets. In that case Mode 52 is the clear winner. If you had only the typical one Mode 3 set, which is somewhere around 14K (224 ROM tiles), then the Mode 52 gain would be negligible (224 Mode 52 tiles take 3.5K, but the mode itself could be ~10K). At 600 tiles however if you even managed to fit that much alongside an actual game with Mode 3, the win would be massive (38K of tiles in Mode 3 versus 10K in Mode 52).
nicksen782 wrote:
Wed Jun 19, 2019 1:34 pm
It isn't really artifacts. It is incorrect tile ids. Most of the screen may draw but a few lines near the top will be totally incorrect. Sometimes it all displays wrong.
Something is clearly wrong with the sync too, didn't you modify Mode 3 in some manner? Does the code synchronize to the video frame (WaitVSync())? If not, it could be some dreaded interrupt hazard as well, depending on whether you might have some sprite code lurking there doing something, just not directly visible.
nicksen782 wrote:
Wed Jun 19, 2019 1:34 pm
I've noticed that reducing VRAM_TILES_V lower that 21 (I need 18) would give me error 4 on SD init. I've also noticed that I would get an error if I set SetRenderingParameters to one line. Is this a bug in the SD code then? I'm using the bootlib library (yours.)
Definitely the too short init case then (that's when it throws error code 4). Since it uses the bootloader's code, there is no way to fix it (too many of these are already "out in the wild"). As a workaround, during init, use a normal height screen (200 pixels or more). After the card is initialized, there will be no problems with the narrow screen.
nicksen782 wrote:
Wed Jun 19, 2019 1:34 pm
So, what the the pros/cons of video mode 3 vs video mode 52 in this game's case? I don't really need color palettes unless I create a color version (which I may eventually.)
The cons are mostly that it is new to you, so you need to learn using it. It has a quite clean interface. Otherwise if you later planned to colour it, that could be tricky due to its 4bpp nature.

The pros are that it gives you massive advantage in ROM size if you use a lot of tiles for different levels, the sprites likewise are very ROM economic "out of the box". The RAM tiles are also very small, so you can either have a lot more sprites than with Mode 3 (especially on this narrow screen), or you can have lots of RAM remaining. The remaining RAM of course can also be utilized for RAM tiles, which can give you more diversity in level design (you don't necessarily have to have every tile in ROM, could be particularly useful for title screens and likes).

If you would like to look into it, keep in mind that lots of documentation is contained on the top of each source file (the assembly ones)!

Hope it helps!

User avatar
nicksen782
Posts: 666
Joined: Wed Feb 01, 2012 8:23 pm
Location: Detroit, United States
Contact:

Re: Super Mario Land

Post by nicksen782 » Wed Jun 19, 2019 7:19 pm

I need 206 for all worlds background tiles. I'll need the remainder for the title screen/fonts, and for sprites themselves. I do want to try to use ram tile sprites for some enemies or bosses though just to save room. I'm around 55k right now (with no real game logic or music/sfx.)
So, I'm thinking 1 background tile set, one for the title screen and fonts (which will be used on the overlay at the top.) and 1 for Mario and then I'll break down the rest of the sprites into 2 sets.

I didn't modify mode 3. You are thinking of my experiments with Kung-Fu Heroes which ultimately failed due to ram restraints. Super Mario Land is presently mode 3 with no scrolling.

The code only has the level draw/scrolling in it. But, it requires one read for each line where each read is 1 byte and requires random-access.

The code looks something like this (not complete here:)

Code: Select all

	while(1){
		for(u8 world=0; world<sizeof(worlds)/4; world+=1){
			// Draw the first screen of this world.
			drawWholeScreen(worlds[world], 0);
			WaitVsync(50);

			// Get the map width and then reset x.
			width = SpiRamReadU16( getBankFromPos(0+worlds[world]), getAddrFromPos(0)+worlds[world] );
			x=0;

			debugDisplay(0, world+1);
			debugDisplay(1, width);

			// Shift vram left, read in the next column into the right side of the screen. Repeat until finished.
			for(u16 i=0; i<width; i+=1){
				shiftVram_left(1, 0);
				// shiftVram_left(1, 1);
				drawRightmostCol(worlds[world], x++);

				debugDisplay(4, x);

				WaitVsync(1);
			}
			WaitVsync(50);
		}
	}
So, use the full size screen for the init and then for the FS_Find part I can set it to one line? I would also do that during the reading of the SD file into SPIRAM, right? That reading code looks something like this:

Code: Select all

		// Configure SPI RAM variables.
		u8 bank;
		u32 addr;

		// Select the SD FS file cluster.
		FS_Select_Cluster(&sdFile1Ptr, t32);

		// Determine number of sectors to read.
		unsigned char numSectorsToRead;
		// numSectorsToRead = ((offset_endofspiram * 1UL) + 511UL) / 512UL;
		numSectorsToRead = ((FT_RM_OFFSET_END * 1UL) + 511UL) / 512UL;

		// Determine number of sectors remaining.
		unsigned char sectorsRemaining;
		sectorsRemaining = numSectorsToRead++;

		// Set the initial position.
		u32 sectorCount = 0;

		SetRenderingParameters(FIRST_RENDER_LINE, 8);

		// Read 512 block from SD to VRAM and then from VRAM to SPIRAM.
		do{
			FS_Read_Sector(&sdFile1Ptr);
			bank              = getBankFromPos(sectorCount*512UL);
			addr              = getAddrFromPos(sectorCount*512UL);
			SpiRamWriteFrom(bank, addr, &ram_tiles[0], 512UL);
			sectorCount++;
			FS_Next_Sector(&sdFile1Ptr);
			// WaitVsync(50);
		}
		// Repeat until done.
		while(sectorsRemaining--);
So, mode 52 has smaller rom tile sizes and ram tile sizes but the mode itself requires more flash? A key problem in Bubble Bobble (aside from not having enough ram for bubble flickering with the design it had) was that it had so many graphics that I ran out of space for game instructions. I really had to learn some compiler flags to get it to fit.

So, mode 52 can afford me smaller tiles (in terms of bytes.) 4bpp, so, half size (instead of 8bpp?) I need room for the game program and I'm already thinking of reading sprite tiles from SPIRAM into RAM for ram sprites. I think I can get away with it but I want to make sure that the game can be finished. I need the program space. I use my own version of gConvert which works great for 8x6 or 8x8 tilesets where it is 8bpp. Does the official gConvert have support for mode 52? If so then I would like to copy that support into my own toolchain since it has extra features. Does that sound reasonable?

Let's consider SML to be the 4 color 1989 Gameboy version for now. Thus, I don't really need to be able to change tile colors on-the-fly. Can you provide a brief overview to how flash/ram tiles work? Can I have direct access to vram (like in mode 3) if I wanted?

User avatar
Jubatian
Posts: 1355
Joined: Thu Oct 01, 2015 9:44 pm
Location: Hungary
Contact:

Re: Super Mario Land

Post by Jubatian » Wed Jun 19, 2019 10:21 pm

nicksen782 wrote:
Wed Jun 19, 2019 7:19 pm
So, mode 52 has smaller rom tile sizes and ram tile sizes but the mode itself requires more flash?
Yes. It is 2bpp (not 4bpp), just right for the GameBoy, which means ROM tiles and RAM usage is quarter of that of Mode 3. As you describe the problems, the latter seems also important as you can have huge amounts of RAM tiles with Mode 52 compared to Mode 3 (If you had room for 32 RAM tiles in Mode 3, you would have 128 in Mode 52 in the same RAM). This means you could also afford to put much less tiles into ROM permanently.
nicksen782 wrote:
Wed Jun 19, 2019 7:19 pm
I didn't modify mode 3. You are thinking of my experiments with Kung-Fu Heroes which ultimately failed due to ram restraints. Super Mario Land is presently mode 3 with no scrolling.
What combination you are using currently then? It might be that some bug in the mixer is manifesting there, throwing sync off. Although probably it has nothing to do with corrupted tiles, but it definitely could cause issues on real HW.

Are you experimenting the problem on real HW only? If so, how that HW looks like? (the V1.3.1 PCB in particular has a problem that the hold pin of the SPI RAM is left floating, which can easily cause data corruption due to noise pulling the pin low)
nicksen782 wrote:
Wed Jun 19, 2019 7:19 pm
Does the official gConvert have support for mode 52? If so then I would like to copy that support into my own toolchain since it has extra features. Does that sound reasonable?
No such support exists, I believe there are no other modes for which code could apply (there are no other 2bpp tiled modes). However the data format is simple, and in arrangement nothing "weird", so I guess it wouldn't be difficult to create tools for it or to add it to other tools (it is definitely a lot simpler than Mode 13 for example!). The data layouts are described in the mode's manual (M52_Manual.rst), simple tool examples are in the "generators" folder.
nicksen782 wrote:
Wed Jun 19, 2019 7:19 pm
So, use the full size screen for the init and then for the FS_Find part I can set it to one line? I would also do that during the reading of the SD file into SPIRAM, right?
Yes, you only need full size during the SD Init. Anything else (including FS_Find which is just a bunch of sector reads under the hood) will work just fine at any height, even at completely disabled display (which I did in the Square Kernel, so it is not even untrodden territory: you can utilize all the CPU to transfer stuff into SPI RAM).

User avatar
nicksen782
Posts: 666
Joined: Wed Feb 01, 2012 8:23 pm
Location: Detroit, United States
Contact:

Re: Super Mario Land

Post by nicksen782 » Fri Jun 21, 2019 10:53 pm

In my testing I think I've been able to determine that the SD card file is not being read in correctly. I tried setting all of SPIRAM to 1 and then reading though it to look for a value that is not one. Also, once loaded, the SPIRAM always shows the same results. I think the SPIRAM is fine.

The SD card though I am still questioning. So, I set it to write to SPIRAM one byte at a time with a WaitVsync(1) between each byte. I got 0 problems with the map tiles aside from the first map which always fails.

I've shown my read code before for the SD card. The same read code worked for two other games. So, perhaps I am not init-ing the sd correctly or adding the libraries in the wrong order or something. I'm running out of ideas. My first world map is width 300 and I read through the entire SPIRAM to find even one value of 300 (only world that has that width.) The emulator, again, works just fine. The hardware always fails. I'm running out of ideas.

Is there perhaps a way of reducing the SPI SD card reading while I am reading the data file in? I think the SPIRAM works just fine.

I am using the portable to test but I have also encountered similar problems on my normal Uzebox unit. Maybe something as simple as fuse settings??

User avatar
Jubatian
Posts: 1355
Joined: Thu Oct 01, 2015 9:44 pm
Location: Hungary
Contact:

Re: Super Mario Land

Post by Jubatian » Sat Jun 22, 2019 9:53 am

nicksen782 wrote:
Fri Jun 21, 2019 10:53 pm
I've shown my read code before for the SD card. The same read code worked for two other games. So, perhaps I am not init-ing the sd correctly or adding the libraries in the wrong order or something. I'm running out of ideas.
Just a cross-check: Does the Square Kernel's image viewer work? (attachment here) It uses the same mechanism for loading data into SPI RAM. Library order really shouldn't matter at all. Initialization shouldn't matter at all, if it is initialized, then it would load, otherwise it wouldn't. The SD library checks CRC (and asks the card to do so likewise), so data corruption shouldn't happen.

Maybe add return value test for FS_Read_Sector and check whether it succeeded?

It really shouldn't normally fail, but it could pinpoint something if it does (what is the return value if so). If it is real HW only, I would expect most likely something around here (other guess would be overwriting the area into which you are loading, such as by Mode 3's sprite engine which runs in interrupt, but that would likely happen in emulator too, although due to timing differences it might not, only a slower real SD card triggering it).

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest