XML Overload

Tuesday, 8th November 2005

Everything in the new version of Latenite is XML-based - the project files, the help files, the error logs... Never mind, it seems to work well.

latenite_small_2.jpg
Click for massive.

So far, the only thing that's useful (complete and working) is the 8XP Linker - linker is a bit of a fancy name for it, as all it really does is wrap a number of .bin COM files up into a single .8x? or 83? file for the TI-83(+). It's a Win32 app, which should help some people stuck with the old DOS apps who can't get them to run under WinNT.

The Build menu seems to work; all Build scripts are now based around the project (rather than the old method of a number of fixed ones). After all, a "Build→Sega Game Gear" option is a bit useless to a TI-8X app. Any .cmd file in your project's Build folder should appear on the menu for you to run.

There are still a few issues - remembering which files were opened when you close the project, remembering which the default build script is, search in entire project (so far only current file and all open files are supported), jump to line, jump to previous instance of selected word, open file at cursor... I also need to complete the Z80 instruction set help file, add a WLA-DX help file... Lots for me to be getting on with!

Latenite, VS 2005 and two screens.

Monday, 31st October 2005

Long time no update...
I haven't done any more work on FireTrack, that is now officially a dead project. sad.gif

Rearranged PC

I spent some part of this weekend rearranging my PC so I could take advantage of my DVI port. With a DVI→VGA adapter I could connect up the other 17" monitor that was currently going unused on my PS2. I also had a new second-hand (new to me, that is) VCR to throw into the mix - here are the results! (Hover for notes).

dual_screens.jpgshow_tv.jpg
show_ps2.jpgAn image
wiring_mess.jpgps2_printer_vcr.jpg

Once again, I'm astounded as to how expensive cables are on the high street (last time it was a USB cable that threw me - £14 in Dixons, I ended up getting it for 99p on eBay). To connect the VCR to the VGA box I needed to convert the only output it gave me, SCART, to something usable - S-Video or composite. The only cable Dixons sold that converted SCART to composite out cost a whopping £39.99... no thanks! Maplin wasn't so bad, a two-way (switchable) SCART→S-Video/composite was only a tenner. Only thing left for me to get is a new VGA cable from my PC to the VGA box - my current cable is thinner than most serial cables I have! (In the photo of the VGA box, it's the one on the left) Needless to say, the image is very fuzzy and there is serious ghosting.

Visual Studio 2005

I recently received the Beta 2 in the post, and I'm (generally) highly impressed. However, I've run into a number of oddities along the way, not to mention some infuriating bugs. The worst is the image resource editor for adding images to menus and the like. Add a couple of images, set the image on a menu item and watch as it erases all your menus, adds them all back again before crashing with the error message:
vs_error.gif
...at which point the IDE closes.
Another oddity is that after such a crash my program started crashing when it closed. The error was in this code (added by the form designer);

protected override void Dispose(bool disposing) {
	if (disposing && (components != null)) {
		components.Dispose();
	}
	base.Dispose(disposing);
}

base.Dispose(disposing); was causing the error "Cannot access a disposed object. Object name: 'SplitterPanel'." I have no idea what would cause that, or which object "SplitterPanel" is at all. Changing the problematic line to this.Dispose(disposing); fixed the problem, but if anyone could shed light onto why this code was failing I'd be very grateful!

My only other major beef with VS2005 is that while most of the visual style bugs have been ironed out, some still remain. The worst one for me is the TabControl, as aligning the tab buttons to anything other than top results in some very odd results. Are MS ever going to decide on a consistent theme? rolleyes.gif

Latenite

Latenite is back in redevelopment - hopefully this version will be released! I have completely rewritten it from scratch in C# (previously in VB.NET) - for one weekend's work, it's not looking too shabby.

latenite_small.jpg
Click for bigger.

Yes, it looks like a direct rip-off of VS, but is geared towards Z80 editing. I'm sticking to making it look/work like a simplified VS, as that seems to be the best way for things to work (after all, most image editing apps feel like variations on a theme of Photoshop). Some new features:

  • Fully XML-based help system makes help files considerably more manageable. HTML-based help viewer (rather than RTF) allows for better presentation and slicker (working!) hyperlinks.
  • Error logs are also returned as XML for neatness.
  • Compilation is now based around a bunch of sensible environment variables (the old system used a cryptic set of command-line arguments - %1 to %5). For example, this is the script for generic TI compilation:
    CD %SOURCE_DIR%
    SET PATH=%PATH%;"%COMPILE_DIR%\ti"
    TASM -80 -i -b "%SOURCE_PATH%" "%SOURCE_FILE_NOEXT%.bin" | TASMERR > "%ERROR_LOG%"
    devpac8%1 "%SOURCE_FILE_NOEXT%"
    DEL "%SOURCE_FILE_NOEXT%.bin"
  • Ability to undo more than one edit and redo again! - This is a big one! (A new class that just adds to the )
  • Sexy icon laden menus. If you create a compile script and save a PNG in the same folder with the same filename (so ZX Spectrum.cmd with a picture of a speccy as ZX Spectrum.png) it appears on the build menu.
  • Faster and more accurate line selection.

There is still a lot (of very dull stuff, no less) to do - project organisation, settings saving/loading, text search... Bah. One day!

Useful script?

Thursday, 6th October 2005

If you have a website of your own, you might want to have your journal on it. (I do wink.gif).
This script can be used to generate a simple HTML document (such as this one!) containing a brief description of your recent entries, a title and a link to the item itself.

<?php
# UPDATE_JOURNAL.PHP
# Ben Ryves 2005.

# CONFIG:
$journal_id = 273102;           # ID number of your journal.
$items      = 8;                # How many recent journal entries do you want?
$saved_page = 'journal.htm';    # Which page do you want to save the journal to?
$password   = 'password';       # What's the password required to fire off an update?


if (isset($_POST['submit'])) {
    if ($_POST['password']==$password) {
        # Run the update script:
        $url='http://www.gamedev.net/community/forums/lib/rss.asp?mode=journal&jn='.$journal_id;
        $handle = fopen($url,'r');
        $writer = fopen($saved_page,'w');
        if (!$handle) {
        	echo "<p>The RSS feed is not available at the moment - sorry.</p>";
        } else {
        	global $cur_pos, $buffer;
        	$buffer = ';
        	while (!feof ($handle)) {
        		$buffer .= fgets($handle, 4096);
        	}
        	fclose($handle);
        	$cur_pos = strpos($buffer,"<item>");
        	for ($i=0; $i<$items; ++$i) {
        		$title = get_between_text("<title>","</title>");
        		if ($title===false) break;
        		$link = get_between_text("<link>","</link>");
        		$description = html_entity_decode(preg_replace("#&lt;(.*?)&gt;#i","",get_between_text("<description>","</description>")),ENT_QUOTES);
        		$description = preg_replace("#<(.*)#i","...",$description);
        		fwrite($writer,"<p><b><a href=\"$link\" target=\"_blank\">$title</a></b><br /><small>$description</small></p>");
        	}
        	fclose($writer);
        	echo "<p>$saved_page has been updated!</p>";
        	return;
        }
    } else {
        echo "<p>Invalid password: sorry!</p>";
        unset($_POST['submit']);
    }
}

?>
<form method="post">
<p>Please enter your password:
<input type="password" name="password" />
<input type="submit" value="Go!" name="submit" />
</p>
</form>
<?php


function get_between_text($before, $after) {
   global $buffer, $cur_pos;
   $cur_pos = strpos($buffer, $before, $cur_pos);
   if ($cur_pos===false) {
      return false;
   } else {
      $cur_pos+=strlen($before);
      $e = strpos($buffer, $after, $cur_pos);
      return substr($buffer, $cur_pos, $e-$cur_pos);
   }
}

?>

You need to set a password just to stop people from running the script (it's a pretty basic system). You'll also need to set the correct ID number. It's a very quick-and-dirty script, so if you have any problems with it give me a shout!

Scripted attacks

Monday, 3rd October 2005

Attack patterns can now be simply scripted as a list of 4-byte chunks, covering which enemy to use, the delay between adding them, how many of them to add, the delay between them and a delay after adding the last one.
For example, this:
.db $04,16,8,100
...would add 8 enemies of type $04, adding one every 16 game ticks and then pausing for 100 game ticks after adding the last one then progressing to the next scripted enemy.
To support this, I've added some new per-level parameters, covering:

  • Attack type (random or 'scripted') with delay between enemies or a pointer to script to follow.
  • Speed of enemies.
  • Speed of landscape scrolling (used very little - bonus levels with no enemies/mines scroll past extra-quickly).
  • Maximum number of mines.

Using all the above, I can easily configure each level's attack patterns quite simply.
Doing this has identified a number of bugs (mostly where new enemies were being initialised without clearing out a particular byte, which means that certain sequences would start in odd places) which have now been ironed out.

I have also picked up work again on my music system for the game. I have a very bad 12-bar-blues demo running with it - I need to find a decent pitch-to-period table as the one I calculated in Excel sounds slightly wrong. There are also some minor-ish reset bugs (the first time in-game a note is played the instrument is full volume for one frame plus some minor synch issues). Looks like I'll have to write the music in Notepad, though - who'd have thought that getting low-level access to the sound card was so bloody difficult in anything other than C (and I'm damned if I'm going to have to write a GUI system for the Windows console, and Win32 is too mucky to deal with for such as simple application). This is great fun, as you can imagine - take, for example, this: (the 12-bar-blues demo for the testbed for the music system)

; Demo tune

demo_tune:

; Instrument table:

.db 2		; Number of instruments
.dw simple
.dw vib

; Sequence table:

.db 6		; Number of sequences
.dw run_c
.dw run_f
.dw run_g
.dw bass_c
.dw bass_f
.dw bass_g

; Tune!

.db %00000000, %00000000
.db %00000011, %00000001
.db %10000000, %10001000

.db %00000000, %00000000
.db %10000000, %10001000

.db %00000001, %00000000
.db %00000100, %00000001
.db %10000000, %10001000

.db %00000000, %00000000
.db %00000011, %00000001
.db %10000000, %10001000

.db %00000010, %00000000
.db %00000101, %00000001
.db %10000000, %10001000

.db %00000001, %00000000
.db %00000100, %00000001
.db %10000000, %10001000

.db %00000000, %00000000
.db %00000011, %00000001
.db %10000000, %10001000

.db %00000000, %00000000
.db %10000000, %10001000

.db %11111111

; Sequences:

run_c:
	.db 1

	.db (144>>8)+%01000000
	.db (144&%11111111)
	.db $10

	.db (112>>8)+%01000000
	.db (112&%11111111)
	.db $10

	.db (93>>8)+%01000000
	.db (93&%11111111)
	.db $10

	.db (82>>8)+%01000000
	.db (82&%11111111)
	.db $10

	.db (77>>8)+%01000000
	.db (77&%11111111)
	.db $10

	.db (82>>8)+%01000000
	.db (82&%11111111)
	.db $10

	.db (93>>8)+%01000000
	.db (93&%11111111)
	.db $10

	.db (112>>8)+%01000000
	.db (112&%11111111)
	.db $10

	.db %11000000

run_f:
	.db 1

	.db (105>>8)+%01000000
	.db (105&%11111111)
	.db $10

	.db (82>>8)+%01000000
	.db (82&%11111111)
	.db $10

	.db (68>>8)+%01000000
	.db (68&%11111111)
	.db $10

	.db (60>>8)+%01000000
	.db (60&%11111111)
	.db $10

	.db (56>>8)+%01000000
	.db (56&%11111111)
	.db $10

	.db (60>>8)+%01000000
	.db (60&%11111111)
	.db $10

	.db (68>>8)+%01000000
	.db (68&%11111111)
	.db $10

	.db (82>>8)+%01000000
	.db (82&%11111111)
	.db $10

	.db %11000000

run_g:

	.db 1

	.db (93>>8)+%01000000
	.db (93&%11111111)
	.db $10

	.db (72>>8)+%01000000
	.db (72&%11111111)
	.db $10

	.db (60>>8)+%01000000
	.db (60&%11111111)
	.db $10

	.db (53>>8)+%01000000
	.db (53&%11111111)
	.db $10

	.db (49>>8)+%01000000
	.db (49&%11111111)
	.db $10

	.db (53>>8)+%01000000
	.db (53&%11111111)
	.db $10

	.db (60>>8)+%01000000
	.db (60&%11111111)
	.db $10

	.db (72>>8)+%01000000
	.db (72&%11111111)
	.db $10

	.db %11000000


bass_c:
	.db 0
	.db (307>>8)+%01000000
	.db (307&%11111111)
	.db 8
	.db (144>>8)+%01000000
	.db (144&%11111111)
	.db 8
	.db %11111111

bass_f:
	.db 0
	.db (224>>8)+%01000000
	.db (224&%11111111)
	.db 8
	.db (105>>8)+%01000000
	.db (105&%11111111)
	.db 8
	.db %11111111

bass_g:
	.db 0
	.db (198>>8)+%01000000
	.db (198&%11111111)
	.db 8
	.db (93>>8)+%01000000
	.db (93&%11111111)
	.db 8
	.db %11111111

; Instruments:

simple:
.db 4	; Length
.db 255
.db -64

.db 8
.db 0
.db 32

.db 1
.db 255
.db 0

.db 0

vib:

.db 2
.db 128
.db 50
.db 2
.db 128
.db -50
.db 2
.db 128
.db 50
.db 1
.db 128
.db -50
.db 1
.db 128
.db 50
.db 3
.db 128
.db -50

.db 10
.db 128
.db 14
.db 0

Thankfully, the assembler can handle me sticking sums in rather than hard-coded values in places making things a lot simpler... but it's still a bit mucky. Ah well. There is no noise channel set up, either, so no krch-krch-krch style beats from the white-noise generator as such.

Enemies Galore

Friday, 30th September 2005

I completely rewrote every single attack pattern from scratch (pretty much - the precalculated paths were left intact) last night. The result of having the ability to start any enemy attack pattern at any time (within reason - I only provide 8 enemy slots!) results in nothing short of sheer mayhem. Yes, collision detection was disabled for the video. I'm looking at you, evolutional... razz.gif

video.jpg
Is that enough enemies, do you think? [AVI/MPEG-4/1.62MB]

The small blobs that drift towards me are the aforementioned mines. The attack frequency, number of enemies on-screen and number of mines is far in excess of anything that you'd encounter in the game - this was just a test to add as much to the game as possible.

Another plus-point of the rewrite is that the game now runs correctly inside MEKA, another widely-used Sega Master System emulator. It had issues with certain attacks keeping their sprites way off screen as they ran in, which worked fine on hardware and in Emukon, but not in Meka for some bizarre reason.

One particular running bug that has been very difficult to trace was an annoying flicker in the sprites. Every so often, some of the sprites would disappear for a single frame. Normally it would be a couple, but sometimes ALL the sprites would vanish.

What could it be? Video timing issues? No, Emukon (the emulator I'm using) pops up incorrectly timed VDP writes in a handy window. Enemy drawing code that was accessing another sprite's data, switching it off? In a similar vein, had I miscounted pointer increments in one particular chunk of code for handling enemies, so in certain conditions it would offset all further array writes by a byte, writing incorrect data into the "enemy disable" byte? After much painful analysis, it appears the routines were pretty watertight... Not PUSHing/POPping registers to the stack before calling a destructive routine?

Well, after much pulling out of hair I have found the problem.

The VDP (the graphics chip I'm controlling) has a certain amount of VRAM. One area in that VRAM is dedicated to a sprite table. First you have a list of Y-coordinates, then a list of X-coordinates followed by sprite index numbers. There is a "magic" Y coordinate, $D0. When the VDP hits this particular Y coordinate, it stops drawing sprites! You can (and I do) use this as a stop byte on the sprite table to tell the VDP when you've finished adding sprites (as each frame has a variable number of sprites on it - I'm trying to keep the game nice and dynamic).

So, what's the problem with that? It turns out that SOMETHING - star code, explosion code, bullet code, enemy attack code, I'm not sure which - is trying to draw sprites with a Y coordinate of $D0! Adding this block of code into my sprite drawing routines (I have two - one for 8x16 sprites, such as the stars, bullets and score digits and another that pairs them up for 16x16 sprites, the size of everything else) fixed the rare flicker bug.

	cp $D0
	jr nz,+
	inc a
+:

Nice and simple, but it does the trick. smile.gif

scr_1.png scr_2.png scr_3.png scr_4.png

Page 44 of 48 140 41 42 43 44 45 46 47 48

Older postsNewer postsLatest posts RSSSearchBrowse by dateIndexTags