My work at converting the dialogue system to sectors instead of records is complete! Now all incidental text for a given set of mobs is stored with the mobs themselves, and transaction text is with the transaction codes.
Effectively, you only need three pieces of data and a sizable buffer space to do variable-length records in a sector system: The base sector to start in, an offset value in that first sector to start your data at, and a number of sectors to read. In my case, my VDP file buffer has a maximum size of 4K, which is 16 sectors. More than adequate for my needs, it fits neatly in a single page of AMS memory, and I can bit-pack the sector count as a nybble (4-bits) and use a single word to store both a base sector and sector count.
I tested it on the hardware tonight and it was VERY fast… loading a map or transaction takes a few seconds, but after that it doesn’t have to refer to the disk at all and pretty much generates the text instantly.
Onward with the bug fixing… At this point, I don’t think I’ll have combat ready in time for Fest West. But I think I can get most of travel and management done. We’ll see…
Speaking of bugs, I’m in the middle of programming the Dungeon exploration portion of the game where I render a 3D frontal view of the maze in front of the player.
I’m debugging this issue where the program is stuck in an infinite loop where I swear there should be none. Sometimes I’m convinced that I just discovered a bug or loophole in 6502 machine language while I bang my head. But usually, if I remove myself for a few hours and come back to it, I can see where the bug is and wonder how I could have not seen it. But it’s at junctures like these where I think that I’ll never get my game done and be stuck there forever 🙂
Congratulations on solving the disk access issue for NPC interactions. As retro devlopers, we should always keep in mind that emulators on the PCs that we work on tend to have much faster disk access than the real hardware.
To respond to a post you made a while ago regarding Ultima VS Wizardry:
“Ultima, hands-down. Mainly because I found Wizardry to be ludicrously difficult. Ultima made me feel like I was in another world, Wizardry felt like you were playing a 3D dungeon run by a sadistic DM.”
Heh. That’s kind of a good summation. I recently watched a video of Richard Garriott discussing his view of computer RPG design and how he’s always wanted to simulate the social aspects of D&D. And he’s always insisted that his games allow players to fully interact with the world around them.
My first forays into D&D as a teenager were several sessions with very strict DMs who had no qualms about following the rules and killing off player characters if the dice results went that way. So when I first started to play Wizardry, nothing really fazed me as my real life DMs were actually much worse!
Yeah, I know what you mean about bugs and stepping away… A LOT of the time, a simple code review with a fresh perspective will find the problems.
With TMS9900 assembly, by far the most common bug is word vs. byte operations. It’s a 16-bit assembly, so it has both word and byte versions of many operations. However, the catch is that words MUST fall on even-byte boundaries, because the internal address line is only 15-bits. So this causes headaches at times when you forget that and suddenly you’re grabbing data from the wrong place because it went to the even boundary.
It’s getting to the point that I KNOW the problem just observing the screen. If my video goes crazy, I know I got an overwrite operation going on somewhere that’s wiping out VDP memory. Stepping through on the debugger (Classic99 is SO useful in this regard) helps me hunt down where the issue occurred, it’s just time-consuming at times to clean everything up!
Yeah, Richard Garriott’s philosophies were always my favorite… I feel like after he sold the company to EA, though, he was just going through the motions. He was completely caught off guard by the negative reaction to Ultima VIII and he was second-guessing himself after that. They’d had a pretty decent original plan for Ultima’s 7-9 originally; #9 was supposed to take place on the Guardian’s homeworld and end with the Avatar defeating him there.
Shroud of the Avatar is finally out, I probably should go patch up and check it out now that it’s in release…
I think I found the bug. Some context: my heart of my game engine is a 20K “core” that contains commonly used routines that are shared by the various modules (Castle, Land, City, Dungeon, etc). The core has routines like getting inventory data, looking up race and class table data, etc. What happened is that I wanted to reuse a routine that was only accessible from within the core in the dungeon, so I had to make it accessible. But even though I recompiled it, I kept loading the emulator from a memory state that had the old core without the new change (I do this to save time — instead of reloading the game from the start). And so, when I went from that memory state and proceeded to enter a dungeon (and thus the game loads the Dungeon module from disk), the program kept jumping to and referencing the new memory locations in the old build of the core.
And that’s why my game was doing weird stuff and I couldn’t figure out what was going on.
I’ll make note of loading the game from scratch whenever stuff like this happens next time.
How embarassing!
Ahhh yeah, that’s an easy mistake to make! I re-compile and load the game every time at the moment, it helps that in my emulator the load time is pretty quick. Otherwise I’d have the same issue. Turn-around, as you know, is critical to good design.
Another crazy error type with TMS9900 is context-switching. So unlike other processors, the registers (16 of them) are actually located in memory somewhere; you have a pointer to where. This gives you great flexibility with switching to a whole new register set quickly, without having to push stuff to a stack, but sacrifices speed since the CPU doesn’t have “next door” memory registers to use. Typically most 99’ers put their workspaces in the scratch-pad, a 256 byte memory area that’s the only true 16-bit memory in the system.
So, when you context switch (the command is branch and load workspace pointer, or BLWP), you have to be careful that you don’t accidentally switch to a set of registers you may have already been in. Or it wipes out your return path and your game will pretty much get lost in RAM somewhere.