VGM Player now works!

Tuesday, 27th September 2005

Lots of fixes...
Download here! (New package includes loading music from Fire Track as a sample)

- Fixed reading of files. I'd used 'char' instead of 'unsigned char'. Files
  that played back as plain silence now play back fully, also play at correct
  speed. What a stupid mistake - it's amazing it worked at all!
  I ended up rewriting the entire PSG emulation thinking it was that that was
  to blame... evidently not!
- Halved frequency of noise channel by only switching output once on 2 clocks.
  It was an octave too high before!
- Fixed odd jumping/incorrect (after loop) seek bar.
- Changed [x] exit button to use 'x' character rather than the cross symbol -
  the cross appeared as a "Pt" sign under Windows 2000.
- Removed display of Japanese tags.
- VGM files that loop back to the exact start of the file are now looped rather
  than ignored.
- Added display of system name for noise mode and very stupid autodetection.
- Sound output is now averaged inside each 44100Hz sample to "antialias" the
  output. Sound output that relies on channels at 0 outputting fully now work.
  Sampled audio still sounds a bit noisy/weird. Sound is now output at 16-bit.
- Option to enable/disable sound channels individually.
- Accelerated seeking considerably.

Scoring

Monday, 26th September 2005

scr_1.png scr_2.png scr_3.png

  • Fixed drunk pilots. New algorithm is about 20 lines shorter, 10 times faster, 5 times simpler. Reason for drunk pilots: drunk coder.
  • Implemented scoring, including:
    • Variable points for shooting enemies.
    • Variable points for shooting objects on the ground.
    • Display of score at top of screen.

  • Updated pause screen, all sprites now remain on-screen, background is less wavy.
  • Trimming of enemy attack times so they follow on from eachother nice and quickly.
  • Numerous minor bugfixes and tweaks.

The score might look nice there, but it really needs to be stuck on a background - any sprites trying to come in are cut off and look really odd popping into existance 8 pixels down from the top of the screen (8 sprite limit, and I have 8 digits in my score). For example, see this:

cropped.png
Look at the top - you can see the nose of a ship appearing, and it looks horribly wrong.

Drawing a black bar might be achieved by swapping name table addresses when I hit a certain scanline, but that's mucky and so far the best result has been 3 or 4 VRAM timing errors per frame and a jumping area of the screen that shows junk. Wonderful!

vgm_player.gif
Download the new build and source.

I also did some more work on my VGM player. It now emulates the PSG correctly! There is one problem still - playback of VGM files that have a specific delay specified. The default timings (1/50th second, 1/60th second) both work beautifully... *sighs* The others play waaaay too fast.
Thankfully, this affects very few VGM files I've tried it with. I also ripped out the tacky visualisations (it's now just a boring console app), improved the seeking code to be time rather than file position based (more accurate) and added support for VGZ files (GZipped-up VGMs) using ZLIB.
If you're in the mood for excellent chiptunes, download the above and the VGM pack to a classic Sega game from SMS Power! - I'm particularly fond of the music from "The Flash". (Ristar's music is also excellent). smile.gif

And now for something completely different

Friday, 23rd September 2005

I felt like a different project for the evening, so started work on a console-based VGM player.

vgm_player.gif
Click to download. [193KB] (Comes with a few sample tunes).

There are a number of (mainly minor) bugs listed in the readme.txt file, but it's not too shabby. It uses SDL to produce the sound (directly writing to the primary buffer). I'd be interested to hear any feedback!

Oh, Fire Track... Well, there's a rip of the BBC Micro version's in-game music (just recorded directly from an emulator, hence the sfx over the top) in the above zip file. Give that a listen!

It works!

Thursday, 22nd September 2005

  • Fire Track II for TI-83 Plus: 31 source files.
  • Fire Track for the Sega Game Gear: 42 source files.
    Based on this information alone, you can deduce that FTGG will be vastly superior. wink.gif

    I just gave FT2 a try in VTI (I don't have any batteries in my calculator) and good grief it's slow. FTGG is much much faster... (though you should see it go when I set the enemy speed to two... I need more accurate control of speed, 1 being medium-ish easy, 2 being nightmarishly impossible!)

    This makes me happy.

    yay.gif
    Things to notice about the above screenshot:

    • Near pixel-perfect parallax star background (you can see some through the bullet holes!)
    • Not one single poorly timed VDP write.

    This has required an enormous amount of code rewriting!
    First to be fixed was the VDP timing. With a few .ifdefs, restructuring of the main loop and addition of an extra function call, all sprite data is now written to a shadow in RAM and then all sent to the VDP at once. This means that in sprite-intensive frames the framerate drops (it is unnoticable!) instead of the VDP going bonkers.

    Next up, the pixel-perfection. I do not know if you know how difficult this is to do on this hardware (or, at least to a hack coder like myself), so I'll do my best to explain.

    On a purely software-driven system, you can create a bitmask of your tiles so that when you manually blend your layers together you can cut out the stars you don't need. Or, you just draw them first then draw the tiles on top.

    On more advanced hardware you can Z-order your polygons, so that's all done for you.

    On the Game Gear, I have two layers - sprites and background. I can set individual background tiles to be on top of sprites - but this would dump a solid 8x8 square on top of everything. In other words, ALL the sprites are drawn under the background tiles marked as being on top. I had toyed with the idea of bizarre palette tricks and messing around with the tiles themselves, thinking sprites would be too slow (I asked about this on the SMS Power! boards - apparantly some games do the sprite trick, so I gained confidence in it).

    What I need to do is this:

    1. Take the (x,y) of my star and convert this into an offset into the VRAM name table.
    2. Look up the value of the tile at this value. If it is 0 (blank tile), draw the star. (Special case to skip expensive stage below)
    3. Look up the tile in a table of sprites marked as transparent. If it isn't listed, don't draw it.
    4. Take the offset into our table of transparent tiles, multiply it by 64, use that as an offset into another table. Find how far into the nearest tile as an (x,y) coordinate we are - that is, x is in the range 0-7 and y is also in the range 0-7 inside the current tile.
    5. Use this coordinate to look up inside our mask whether to draw the sprite or not.

    There was an awful lot to go wrong and it did, often. sad.gif It works pretty well now, so I'm happy with where it is. smile.gif

    The function to calculate the VRAM name table offset based on an X,Y on screen was broken. It needs to take into account the current vertical scroll, you see, to calculate the offset, so was essentially doing this to calculate which 8-pixel-tall row a pixel was in:

    row_offset = (y/8) + (scroll_y/8)

    (where y is the coordinate we pass to the function) - which leads to all sorts of rounding errors! The correct function is, of course:

    row_offset = (y+scroll_y) / 8

    Which, oddly enough, didn't seem to work at all well - at certain times, the values returned were completely off. The reason is simple enough - our scroll_y is a value between 0 and 223, and out y coordinate is anything between 16 and 160. 160+223=383 - you try storing that in an 8-bit register! So I updated the entire function to 16-bit code where needed.

    Z80 ASM gurus - my old code to divide A by 8 was the simple:

        srl a
        srl a
        srl a

    For my divide-hl-by-8 function (srl [reg] is a sort of [reg]>>=1 function) I use this:

        srl h
        rr l
        srl h
        rr l
        srl h
        rr l

    -- is this the fastest I could use? Is there a nice 16-bit shift operation available to me?

    Next I had to generate the transparency data. I edited my tile editor - solid green &00FF00 is taken to mean "transparent!" It dumps a list of any tile with transparency, then an expanded 64-byte table of the mask (1 byte per pixel - horribly big, but much faster than packing it into a 1bpp mask).

    When I say "near pixel-perfect", I have a problem - my stars are 2x2 pixels, and so if they can overlap the borders by a pixel or two from time to time. It doesn't look too bad, and in my defense the original Fire Track displayed stars over ANY black areas on the background at some points...

  • Parallax

    Wednesday, 21st September 2005

    Here's a nice little graphical enhancement...
    stars.jpg
    ...and here's the video for it!
    (I disabled collision detection for that video, so no silly comments, alright? wink.gif)

    Now, there's a little problem with this system - well, a number of problems. The worst is this:
    bugger.gif
    Oh dear. I'm now writing to the sprite table when the display is active, which (understandably) it does not like. On the Game Gear hardware, you can see this in the vertical bar of flickering stars towards the left hand side of the screen. I am not sure how I shall fix this, but I'm hoping that altering the sprite drawing routines to write to a RAM shadow then dumping the entire RAM shadow in the frame is faster than my current method which is to manually draw the sprites in a number of different routines.

    The next problem is the detection of when to show/hide stars. Currently, it only does this based on tile index - so only tiles marked as being 0 are "transparent" and enable the stars (they're being drawn as sprites). This leads to them vanishing a good distance away from the edge of land.

    Finally, there's the even weirder issue where the stars move at almost the same rate as the landscape but are shifted in alternate frames. If a star is on the boundary between tiles, one frame it is over tile 0 so is shown, next it is over tile X so is hidden, and this oscillates. Hopefully by fixing up a pixel-perfect "show/hide" function, I can fix up this problem as showing and hiding would be about 4 pixels away from the boundaries.

    I have also started work on "Segue", a simple music system for Game Gear games. I'll support instruments (they just modulate the amplitude of notes when they are played) that can be bound to the different channels. The song itself will be a list of instructions - "play this tone X on channel Y" (where X is the period of the tone), "delay for X frames", "assign instrument X to channel Y" - that sort of thing.

    EDIT: This journal is now low-res non-horizontal-scrolling friendly. wink.gif

    Page 49 of 53 145 46 47 48 49 50 51 52 53

    Older postsNewer postsLatest posts RSSSearchBrowse by dateIndexTags