Jump to content
IGNORED

Alex Kidd Port


TheMole

Recommended Posts

I don't understand the __asm__ code, so I'll have to take it on faith that it emits the correct ALC. The fact that load() works certainly implies that it does.

 

%0 and %1 are the first and second parameter passed from the C environment, as defined in the post-colon sections of the __asm__ call ( "stat", and "op" in this case). The first line means that %0 in the assembly code refers to a write only parameter ( = ) that is cached in a register ( r ), with the name stat, the second indicates that %1 refers to a read-only parameter cached in a register. The third line tells the compiler that the values in r0 and r1 will be clobbered (official gcc term :) ) during the execution of the assembly code.

 

The only thing that comes to mind is that the VRAM address of 0x0000, which constitutes a null pointer (I think), perhaps causes a problem. Does it also fail at a non-zero VRAM address?

 

Well, the VRAM address is not really a pointer, since none of the VRAM memory is directly accessible by the CPU. On top of that, the null pointer is a perfectly valid address to write to as far as gcc is concerned, protection from writing to null pointers is actually a function of the OS/environment you are running in.

Edited by TheMole
  • Like 1
Link to comment
Share on other sites

Having said all the above, I am an idiot...

 

I started figuring there was something else wrong when I tried loading the graphics from another function. It worked, so there was nothing wrong with the file loading functions all along (well, after my first round of moving things about in VRAM). Turns that in my init_gfx function (which loads the patterns from disk, amongst other things) I had this little line:

vdpmemset(0, 0, 0x4000);

I was filling all of VRAM with zeroes, thus overwriting the "no-go" disk buffer/cache/whatever at the top of VRAM as well. The call was there to clear out memory so to make things easier to debug (just so I wouldn't have to distinguish random junk from true buffer overruns...). Commenting out that line makes everything work just perfectly. Go figure...

 

So, updated version of the disk image attached to this post, for all those that are interested to test and play with it. :)

 

Feedback appreciated, all caveats about shaky sprite-sprite collision detection and all from my previous post still apply though.

alexkidd.dsk

Edited by TheMole
  • Like 1
Link to comment
Share on other sites

Having said all the above, I am an idiot...

 

I started figuring there was something else wrong when I tried loading the graphics from another function. It worked, so there was nothing wrong with the file loading functions all along (well, after my first round of moving things about in VRAM). Turns that in my init_gfx function (which loads the patterns from disk, amongst other things) I had this little line:

vdpmemset(0, 0, 0x4000);

I was filling all of VRAM with zeroes, thus overwriting the "no-go" disk buffer/cache/whatever at the top of VRAM as well. The call was there to clear out memory so to make things easier to debug (just so I wouldn't have to distinguish random junk from true buffer overruns...). Commenting out that line makes everything work just perfectly. Go figure...

 

So, updated version of the disk image attached to this post, for all those that are interested to test and play with it. :)

 

Feedback appreciated, all caveats about shaky sprite-sprite collision detection and all from my previous post still apply though.

 

 

It's working fine now on the hardware (tested on nanoPEB with F18A) but I only had about 2 mins to try it. I fell into the lava and got stuck. There is a bit of flickering when the screen is scrolling, the same you see in MESS. Looks like the pattern table or name table update is not always vsynced.

 

Edit: If you move out of the screen to the left you can see one pixel of the sprite at the right side of the screen.

Link to comment
Share on other sites

Thanks for testing and the feedback.

 

It's working fine now on the hardware (tested on nanoPEB with F18A) but I only had about 2 mins to try it. I fell into the lava and got stuck.

 

Turns out I hadn't learned my lesson yet... last file I loaded still encroached on the VDP disk buffers. You were supposed to see Alex's ghost ascend to heaven and hear a game over tune play (which is loaded from disk). I resorted to simply caching the part of the buffers that are overwritten in RAM, just like you suggested a couple of days ago. Working version attached.

 

There is a bit of flickering when the screen is scrolling, the same you see in MESS. Looks like the pattern table or name table update is not always vsynced.

I think I'm taking too much time updating the screen during VBLANK. I managed to improve it to the point where there's only some minor screen tearing left (at least in MESS), but I'd like to get it perfect. Any idea how much time we have during VBLANK (and how many bytes we should be able to transfer).

 

Edit: If you move out of the screen to the left you can see one pixel of the sprite at the right side of the screen.

Yup, known issue. I use bytes for sprite locations, which means there is no room for 'negative' screen positions. It gets worse... try punching when at the left edge of the screen and facing left :). I need to limit how far to the left Alex can go, it's on my list of things to do though.

 

*edit* instead of attaching the new version to this post, I decided to always add the latest version to the first post

Edited by TheMole
  • Like 1
Link to comment
Share on other sites

I think I'm taking too much time updating the screen during VBLANK. I managed to improve it to the point where there's only some minor screen tearing left (at least in MESS), but I'd like to get it perfect. Any idea how much time we have during VBLANK (and how many bytes we should be able to transfer).

 

If you're double buffering the name table and only switches tables right after vblank you should never see the screen tearing. But since you're using the interrupt routine hook for timing I guess you cannot be 100% sure that your interrupt routine is called right after blank in particular if your main routine sometimes takes too long. I have not actually used the interrupt routine myself (only VDP status polling) so I'm probably not the right person advice on this, but you could try to make some measurements in the Classsic99 debugger for the duration of your various routines. I would not count on having time to do any screen update during vblank except to switch tables.

Link to comment
Share on other sites

Just great! :) Please continue, want to see this finished some day! :)

 

By the way, for some reason, I cannot see Miracle_island_1.png picture from the first post, it tries to load it, but nothing happens.

 

Thanks! I fully intend to polish it up into a real game. I don't think I'll do a one-on-one port of all the master system levels, but I will definitely add some more gameplay elements and levels. Not sure if I should include the janken matches though.

 

Does this open for you: http://s9.postimg.org/p37j885tb/miracle_island_1.png ?

Link to comment
Share on other sites

New version attached to post 1. New features:

  • Alex can now punch the yellow star boxes. About half of them will reveal a money bag, half of them will be empty (this is random, also it's different from the original game where you had a 50/50 chance of getting a small or large bag, but I don't have room left for "small bag" graphics).
  • Alex can now pick up money bags, both from star boxes as well as regular ones.
  • Alex can now destroy skull boxes, but beware: doing so is so scary that it will send shivers down Alex's spine, which will make him unable to move for a good second or so...
  • Added a bunch of sound effects. I'll probably need to tweak the "breaking stone" and "killing enemies" sound effects as they don't come across very well on the TI. I seem to remember reading somewhere that the SMS's sound chip had a slightly tweaked noise channel for more percussive sounds, which could be the reason why it sounds a bit off.
  • Added a loading screen, which is silly on emulation but I gather will be helpful on real hardware with actual slow-as-molasses floppy disks.

 

Next up: tweak the Alex graphics a bit so I can get by with less sprite patterns. I have to win back 64 bytes in the table to define the "bird" enemy at the end of the level so I can replace the placeholder. After that I'll start working on refactoring the code to make the gameplay slightly less hard coded so I can load entire level definitions from disk, I am not looking forward to that :).

 

  • Like 7
Link to comment
Share on other sites

 

 

I seem to remember reading somewhere that the SMS's sound chip had a slightly tweaked noise channel for more percussive sounds, which could be the reason why it sounds a bit off.

 

The TI uses a 15-bit shift register to generate its noise, while the SMS uses a 16-bit shift register. So, the difference in pitch on the noises is 15/16s. For the fixed frequency pitches, it's usually not a big deal, but if they are being combined with channel 3 for custom pitches, multiply the pitch value in channel 3 by 15/16 and you'll get the correct output on the noise channel. (If the tone is also audible, you can't win, but that's rare ;) ).

Link to comment
Share on other sites

it gave me 403 forbidden, but on the second try it worked. :) Thank you! Looks very nice! Speaking with MSX terms, sure it would look even more nicer with some Screen 2 extra colour, but I do like it the way it is now. :) If the background had any more colour, maybe it would look like non-TI-ish. :_( ;)

 

May I say that I would like to play the finished game on my TI someday? ;) Yeah, now I have my own TI!!!! At last!! :-D :grin: Well, now it´s said. :) Lovely looking computer!

  • Like 1
Link to comment
Share on other sites

Speaking with MSX terms, sure it would look even more nicer with some Screen 2 extra colour, but I do like it the way it is now. :) If the background had any more colour, maybe it would look like non-TI-ish. :_( ;)

 

True, and while it would be possible to add a bit more color ala Screen 2 in a non-game context (I think Rasmus demonstrated this with his omnidirectional scroller demo), I truly cannot afford the extra 6k of VRAM that this would consume. My VRAM layout is pretty full as it is (check out post #19 of this thread, I only have 2k left...), and I don't really see a way of making enough room for it :).

Link to comment
Share on other sites

 

True, and while it would be possible to add a bit more color ala Screen 2 in a non-game context (I think Rasmus demonstrated this with his omnidirectional scroller demo), I truly cannot afford the extra 6k of VRAM that this would consume. My VRAM layout is pretty full as it is (check out post #19 of this thread, I only have 2k left...), and I don't really see a way of making enough room for it :).

 

Actually the VDP setup used in the light year demo is only using 8K for colors and patterns, i.e. 16 bytes less than you do :-) but it's a very different animal. You cannot use the top 3rd of the screen for anything but sprites, and you have to update 2/3 of the SIT every frame. You also have the issue of shared colors to deal with, and where you have 1024 patterns in total to play with, the special mode only has 512also has 1024 (but only 512 in each third of the screen).

Link to comment
Share on other sites

Actually the VDP setup used in the light year demo is only using 8K for colors and patterns, i.e. 16 bytes less than you do :-) but it's a very different animal. You cannot use the top 3rd of the screen for anything but sprites, and you have to update 2/3 of the SIT every frame. You also have the issue of shared colors to deal with, and where you have 1024 patterns in total to play with the special mode only has 512.

 

Ah yes, the "Artrag" approach... :). But that's not technically "screen 2" anymore, right? Sort of a hybrid half bitmap mode? I really need to dig a bit deeper into that 'cause I really don't know enough about how it uses VRAM.

Link to comment
Share on other sites

Well, if you look at the bits in the vdp registers 0 and 1 that define the vdp mode, it is a plain screen 2.

The trick is in the fact you can mirror the color definition table without unwanted side effects on sprites (as you know, if you mirror tile definition table, only the first 8 sprites are safely usable). By "mirroring" I mean the use of the mask bits in registers 3 and 4 that allow to apply the same data at different addresses on the screen.

 

Provided that you do not use tiles in the first bank, you can arrange things to get two "pages" of tiles in screen 2 covering the lower 2/3 rds of the screen.

As each bank is 256 tiles and you have two pages of two banks each, in the end you get 1024 tiles to play with, in screen 2.

 

More precisely,

To display page 0 you have to use these settings

 

disp_page0: ; page 0 active
_setVdp 3,0x1F ; colours at 0x0000-0x07FF (mirrored table: it is used in the lower 2/3rd of the screen )
_setVdp 4,0x07 ; patterns at 0x2000 (regular tables: only use data at 0x2800 and at 0x3000)
To display page 1 you have to do:
disp_page1: ; page 1 active
_setVdp 3,0x9F ; colours at 0x2000-0x27FF (mirrored table: it is used in the lower 2/3rd of the screen )
_setVdp 4,0x03 ; patterns at 0x0000 (regular tables: only use data at 0x0800 and at 0x1000)
You cannot use (easily) tiles in the top 3rd of the screen as the same area of 2KB, when page 0 is active, is used as colors (valid in the whole screen) while, when page 1 is active, means "patterns".
The other restriction is that middle and lower banks, in page 0, share the same color definition table in 0x0000-0x07FF and in page 1 the same color definition table in 0x2000-0x27FF.
Edited by artrag
  • Like 2
Link to comment
Share on other sites

 

Well, if you look at the bits in the vdp registers 0 and 1 that define the vdp mode, it is a plain screen 2.

The trick is in the fact you can mirror the color definition table without unwanted side effects on sprites (as you know, if you mirror tile definition table, only the first 8 sprites are safely usable). By "mirroring" I mean the use of the mask bits in registers 3 and 4 that allow to apply the same data at different addresses on the screen.

 

Provided that you do not use tiles in the first bank, you can arrange things to get two "pages" of tiles in screen 2 covering the lower 2/3 rds of the screen.

As each bank is 256 tiles and you have two pages of two banks each, in the end you get 1024 tiles to play with, in screen 2.

 

More precisely,

To display page 0 you have to use these settings

 

disp_page0: ; page 0 active
_setVdp 3,0x1F ; colours at 0x0000-0x07FF (mirrored table: it is used in the lower 2/3rd of the screen )
_setVdp 4,0x07 ; patterns at 0x2000 (regular tables: only use data at 0x2800 and at 0x3000)
To display page 1 you have to do:
disp_page1: ; page 1 active
_setVdp 3,0x9F ; colours at 0x2000-0x27FF (mirrored table: it is used in the lower 2/3rd of the screen )
_setVdp 4,0x03 ; patterns at 0x0000 (regular tables: only use data at 0x0800 and at 0x1000)
You cannot use (easily) tiles in the top 3rd of the screen as the same area of 2KB, when page 0 is active, is used as colors (valid in the whole screen) while, when page 1 is active, means "patterns".
The other restriction is that middle and lower banks, in page 0, share the same color definition table in 0x0000-0x07FF and in page 1 the same color definition table in 0x2000-0x27FF.

 

 

Thanks for the detailed explanation. I always keep forgetting the masking functionality of the non-MSB bits in the pattern and color table location registers, since the datasheet simply says that they need to be all 1's. I'll probably play with this mode for my next project, if/when I finish Alex Kidd :)

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...