Jump to content
IGNORED

Super TI-99 Mario Bros (F18A required)


Asmusr

Recommended Posts

This is the development thread for my remake of the NES version of Super Mario Bros for the TI-99/4A with F18A video board.

 

My current plan for this project is to make at least one fully playable level with sub-levels and all details of the original included. After that, let's see...

  • The programming is done in TMS9900 assembly language without use of the original source code.
  • The game physics is based on a guide found here, which has been a huge help.
  • The graphics has been imported from the spriters resource and reworked in Magellan.
  • The music has been entered by hand from the sheet music into Mod2PSG2 and is played using Tursi's VGM compression and playback library.
  • The code is assembled using ralphb's Cross-Development Tools (xdt99).
  • Testing and debugging is done in my own js99er.net emulator, and the program has been verified to work on real hardware.

Note that the control is joystick only. Up is used for jumping and Fire is used for running. Use B during the game to turn the background on/off.

This is the latest video, which is slightly out-of-date because it doesn't include the secret room:

 

 

Latest version and source code attached (run E/A#5 MARIO1).

 

Status 18 Feb 2016: World 1-1 including secret room fully implemented.

 

post-35226-0-94968800-1455802193_thumb.png

MARIO.dsk

Source-18-feb-2016.zip

  • Like 14
Link to comment
Share on other sites

Thanks for this update and the effort that went in.

Which screen mode are you using for this? Afaik the Nes features a 30 character mode as well, which was added by Matthew to the F18A.

The tiles seem to have more than 2 colors which is not supported by the TMS9918A.

You said, no use of the GPU. Is there any usage of the additional 2K of VRAM?

 

It's perfectly timed as well, in Vienna there is a TI meeting tomorrow. This will make the guys speechless.

Do you know that there will be the international TI meeting in Kopenhagen this year? Isn't this close to where you live?

 

Btw: i also tried to program a TI Mario World once, however for the TI-92 calculator, I know how hard the physics were to implement, without any guides I got frustrated:

https://web.archive.org/web/20050224160734fw_/http://www.fortunecity.com/skyscraper/mulder/376/puds/pudmario.htm

I was 17 years old, so not even half my current age. :)

 

Once you got the engine running, storing additional levels is not that difficult. You can even let others do this if you document the level data and separate that data to an external file.

Link to comment
Share on other sites

Which screen mode are you using for this? Afaik the Nes features a 30 character mode as well, which was added by Matthew to the F18A.

If using the 30 row mode. On the NES I understand that the top and bottom rows would normally be hidden in the TV picture.

 

The tiles seem to have more than 2 colors which is not supported by the TMS9918A.

 

I'm using the F18A ECM2 color mode (4 color per tile). You can actually do a pretty good approximation in 9918A bitmap mode, but you can't do the smooth horizontal scrolling.

 

You said, no use of the GPU. Is there any usage of the additional 2K of VRAM?

No, you can't use the extra 2K without the GPU.

 

Do you know that there will be the international TI meeting in Kopenhagen this year? Isn't this close to where you live?

 

Never, I think.

 

Btw: i also tried to program a TI Mario World once, however for the TI-92 calculator, I know how hard the physics were to implement, without any guides I got frustrated:

https://web.archive.org/web/20050224160734fw_/http://www.fortunecity.com/skyscraper/mulder/376/puds/pudmario.htm

I was 17 years old, so not even half my current age. :)

 

Cool.

 

Once you got the engine running, storing additional levels is not that difficult. You can even let others do this if you document the level data and separate that data to an external file.

 

Sure, provided that the engine is generic enough. Later levels have other enemies, trampolines, swimming, etc. This has to be programmed in.

Link to comment
Share on other sites

 

Do you know that there will be the international TI meeting in Kopenhagen this year? Isn't this close to where you live?

Never, I think.

 

Well, until further notice I've reserved the first two weekends in October. Yearly TI-99/4A European Meeting, Copenhagen, Hotel Svalen, Hedehusene. Ref. Berry Harmsen.

 

Me and my family will be traveling from Jutland. We will probably stay with friends.

 

I really do hope there will be more info available.

 

;)

Edited by sometimes99er
Link to comment
Share on other sites

Posted Today, 10:44 AM

Asmusr, on 19 Jan 2016 - 08:56 AM, said:snapback.png

kl99, on 19 Jan 2016 - 08:15 AM, said:snapback.png

Do you know that there will be the international TI meeting in Kopenhagen this year? Isn't this close to where you live?

Never, I think.

 

Well, until further notice I've reserved the first two weekends in October. TI-99/4A European Copenhagen, Hotel Svalen, Hedehusene. Ref. Berry Harmsen.

 

Me and my family will be traveling from Jutland. We will probably stay with friends.

 

I really do hope there will be more info available.

 

;)

 

Oh sorry, I thought you were asking when there would be an event..

Link to comment
Share on other sites

Just got a chance to play this for the first time. Amazing work, very impressive indeed! It's also awesome to see the TI get some F18A love, as well as some platforming love :).

 

Can you share a little bit about how you manage entities (enemies) in this? I'd also be interested in hearing how you manage memory for the map, special blocks, destructible blocks, etc...

Link to comment
Share on other sites

Just got a chance to play this for the first time. Amazing work, very impressive indeed! It's also awesome to see the TI get some F18A love, as well as some platforming love :).

 

Can you share a little bit about how you manage entities (enemies) in this? I'd also be interested in hearing how you manage memory for the map, special blocks, destructible blocks, etc...

 

Welcome back, I was afraid you might have lost interest. :)

 

To start with the map, this is stored as 2x2 metatiles, and unlike other games where I use metatiles I use this map directly instead of expanding it to tiles first. I have a table for looking up the type of each metatile, whether it's background, brick, ground, question block, etc. There are slightly more than 32 metatiles on level 1-1, so there are two bits left in each byte that I could use for storing additional data about each metatile, e.g. what 'present' a question block contains. I haven't used this yet, instead I have just used different metatile number for each type of present.

 

The sprite attribute table is stored in CPU RAM and is copied to VDP RAM each frame. This is actually the biggest chunk of VDP transfer, since the scrolling only require 13 bytes each frame. The first two sprites are allocated to Mario, but the others can be allocated dynamically for enemies etc. The enemies are stored as a list of structures, each containing position (x,y), velocity (vx, xy), acceleration (ax, ay), type, pattern and color, and a pointer to the sprite attributes currently allocated to the enemy. Position, speed and acceleration are stored as 12.4 fixed point. The position is in map coordinates, and the MSB is the position in metatiles, so it's easy to look up the corresponding metatile. I iterate through the enemy list each frame, and only enemies within a certain window relative to the scroll position, which extends a bit beyond the visible screen, are processed. Basically this involves adding velocity to position, adding acceleration to velocity, and doing collision detection.

 

The special sprite effects when a spinning coin appears, a Goomba (mushroom) is stomped, or a brick turns into debris are not handled as 'enemies' but as something I call 'sprite animations'. A sprite animation has position, velocity, and acceleration, but no collision detection takes places. It has a duration after which the sprite is deallocated and an address of an optional callback. First I thought I needed to stored the paths for a animation, but it turns out that velocity and acceleration is enough to obtain the desired effects.

 

This game has an amazing richness of things you can do on just the first level, the code is already longer than any of my other games, and I'm still discovering new details. I have tried to make my engine reasonably generic without overthinking it, but when I start looking at other levels I will probably have to make major changes.

  • Like 9
Link to comment
Share on other sites

To elaborate a bit further on the use of sprite animations: When Mario hits a metatile block with his head the block seems to move up and down. What really happens is that I remove the metatile from the screen and replace it with a sprite animation with a upwards velocity and a downwards acceleration. When the counter of the sprite animation reaches zero it is removed and the callback is executed, which reinstates the metatile on the screen.

  • Like 6
Link to comment
Share on other sites

To elaborate a bit further on the use of sprite animations: When Mario hits a metatile block with his head the block seems to move up and down. What really happens is that I remove the metatile from the screen and replace it with a sprite animation with a upwards velocity and a downwards acceleration. When the counter of the sprite animation reaches zero it is removed and the callback is executed, which reinstates the metatile on the screen.

That's exactly the kind of detail I was hoping to get with my question! That is a nice and clean way to handle this, I assume you use a similar thing when big Mario head-butts a block but you just don't replace the metatile?

 

How about the different enemy behaviors (like how the Koopa's shells fly around after 'kicking' them), I'm guessing you have a jumptable to specific code for each enemy type? Or are you defining attributes?

Link to comment
Share on other sites

That's exactly the kind of detail I was hoping to get with my question! That is a nice and clean way to handle this, I assume you use a similar thing when big Mario head-butts a block but you just don't replace the metatile?

 

How about the different enemy behaviors (like how the Koopa's shells fly around after 'kicking' them), I'm guessing you have a jumptable to specific code for each enemy type? Or are you defining attributes?

 

It may turn into a jump table at some point, but at the moment it's more like a bunch of 'if' statements. :-)

 

The Koopa (turtle) at level 1 has taken a lot of work. I'm attaching the latest version where it's almost complete. First problem was that it consists of two sprites: the head and the body. For simplicity I have chosen to implement this as two single sprite enemies instead of allowing one enemy to consist of several sprites, but this if one of the decisions I might want to change later when I need to support other larger enemies. But for now I know that the the body always follows the head in the enemy list.

 

When Mario jumps on the head or body I disable the head (by setting the X position to zero) and change the type attribute for the body to indicate it's now a shell. I also set the velocity to zero and change pattern for the body into a shell. If Mario now touches the shell it speeds off in the same direction as Mario, and enemy to enemy collision detection ensures that if it hits a Goomba this is knocked out (e2e collision is new in the latest version).

 

If Mario doesn't touch the shell it grows legs after a few seconds. To implement this I added a general system of timers that you can set up to fire after a given time. The callback function changes the pattern to a shell with legs and sets the animation. After waiting a few more seconds the Koopa should start moving again, so the first callback starts a second timer, and the second timer callback restores the Koopa head and resets the type - phew!

 

Edit: A new version with more bug fixes attached.

MARIO.dsk

MARIO.dsk

  • Like 6
Link to comment
Share on other sites

Are you using the F18A sprite linking features? The idea was to make doing larger sprites easier. Are you planning to avoid the GPU? If not, it might be a good candidate to do the collision detection calculations.

 

No I'm not using sprite linking at the moment, but it might come in handy later. I would still have to manage animation and collision detection for each if the individual sprites, so the advantage is not that big when you only have relatively small sprites.

 

I haven't used the GPU yet because it hasn't been necessary. It's also complicating the programming, and js99er only has limited support for debugging GPU code (even more limited than for CPU code).

Link to comment
Share on other sites

I wonder if it would be blasphemy to add a slow scrolling background behind the main graphics?

 

Blasphemy, or an artistic touch? I notice in a lot of games, conversion to other platforms often have something which make them "belong" uniquely to that particular platform: a change in color schemes, up- (or down-) graded sounds, speech, etc. So why not add something which gives it the special "Made by Rasmus" signature, and that unique "made for the TI" characteristic?

  • Like 1
Link to comment
Share on other sites

I wonder if it would be blasphemy to add a slow scrolling background behind the main graphics?

 

I would say as long as it stops scrolling when the player isn't moving, then go for it. It may look a bit odd if it scrolls the same speed

when Mario is stopped, going slow, or fast.

If You are just thinking of a cloud or 2 moving along, then probably doesn't matter.

 

Enhancing a game in a way that adds to the atmosphere should never be considered Blasphemy, some Nintendo diehards may

not agree though.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...