Internal Link
(opens in same window)
External Link
(opens in new window)
Broken Link
(likely 404 error)
|
July-September 2004 (oldest-to-newest)
My programming time lately consists of 30-45 minutes in
the morning between when I finish breakfast and when I need
to get Gavin ready for day care, and up to an hour at night
after he's gone to bed before I need to do the same. Of
course this varies depending on our activities for the day,
but I'm happy to have a modicum of regular programming
time.
Game Progress
Fixed one more bug. This time it was the incorrect colors
I mentioned in the last sentence of the June 28th post.
This was another of those bugs that existed on the Yaroze
as well. I have a suspicion about why I didn't see the
problem back then. I think the PSX hardware behaves a bit
differently than what my YarLib library assumes.
Regardless, it's fixed.
Next up I need to fix the alignment of the minimap
objects so that they correspond to the actual object
locations a bit better.
|
Game Progress
Made some awesome progress this weekend. I fixed the
alignment problem with the shop-to-level transition.
It's not ideal, but works. Maybe I'll go back and put in
the better fix later.
I fixed the screen for when you're recalling stored
items in your ship. FYI, your ship only has six "extra"
slots for which to populate items like missiles, rockets,
and other ship enhancments. This isn't that big a deal
since there aren't even six items that you'd want to
carry at once. It would have come more into play had I
implemented the other 80% of the game as planned. Anyway,
to make room for more items you can store an extra in your
ship's cargo hold. While you're at a shop you can
store/recall items to configure your ship how you like.
To get back to my point, the screen that lets you recall
systems is now fixed. It needed updating to handle triple
buffering.
I also fixed the level select from within the shop.
You can go back to previous levels to try to get money
that you left behind or get more bonuses (which also gives
you money).
Right now I'm fighting a particularly nasty bug that's
causing random crashes on the level after the shop. It
doesn't leave any trace as to why it crashed, which as you
can imagine is quite annoying.
|
Game Progress
This crashing bug is driving me nuts. Thankfully I've
found a way to reproduce it somewhat repeatedly. It seems
to be one of those weird cache problems because stepping
through the code works, but running it normally does
not. Hopefully I'll have some time this weekend to look
into it more.
|
Game Progress
Dumb luck allowed me to fix that annoying bug. The root
cause turned out to be an uninitialized index into an
array. Now normally accessing a bad address causes the
system to throw an exception. Exceptions are nice since
they give info about what caused it. However this bug was
just causing the game to crash - no exception.
Until yesterday morning. Who knows what changed. The
state of the system at boot is undefined. Maybe that
uninitialized variable had a different value than before.
Regardless, I got a nice shiny exception message and was
able to track it down rather easily.
It seems lately I've been finding a lot of bugs in the
Decaying Orbit code rather than the Yaroze library. This
is a good thing as it means the lib is getting pretty
robust. There can't be too many more in the game code
since, you know, the game works on the Yaroze.
So that fixed the level after the shop (level 5,
counting the shop as a level). Proceeding on the very
next level caused a crash. The good news was that it was a
very nicely thrown exception. The bad news was that the
exception was in the sprite library, which is more
difficult to debug than game's C code.
Turns out the game was trying to use a non-existent
sprite renderer, which caused the sprite lib to overwrite
part of itself. Guess that means I need to write a new
renderer to cover that case. In the meantime I forced the
game to use a slower, but functional renderer.
The next problem that I hit late last night involved
one of the planets being drawn as all black. This
shouldn't take long to debug.
On a positive note, I was rather impressed with how
the game was able to maintain almost 30 fps on that level.
It has lots of nebulas, which with their transparency make
them the most time consuming object to draw. This bodes
well for the speed on future levels.
|
Game Progress
  |
The next problem that I hit late last night involved
one of the planets being drawn as all black. This
shouldn't take long to debug.
|
  |
I should have known better than to tempt Murphy's Law
like that. The problem is actually a tricky one. It's
not that the sprite is being drawn as all black. It's not
being drawn at all. I traced it to the sprite
library where the sprite in question is being trivially
rejected for some reason.
Sucky thing is the problem is in the part of the code
that I don't quite understand. It involves calculating
the optimum tile size to be read each loop. The main
problem I have is not knowing the algorithm that's being
used. Damn you Minter!
I may post a topic in the forums
later asking for help.
Update: I've been struggling with how to describe
the algorithm in a forum message. It's rather complicated.
I think I'm slowly getting a handle on it on my own.
Update2: Okay, the thread is up. Any math whizzes out there?
|
Game Progress
This is a long one so I'm using headers
Sprite Lib bug
I worked through the algorithm by talking to myself in the forums. Sometimes it helps to just
talk it out. Anyway, it was a bug in the sprite lib
that's been there from the very beginning when I got the
code. The reason it could slip past for so long is that
the incorrect calculations did not make the lib crash.
Rather it just made the lib less efficient, causing slower
rendering. The only reason I found it is that I hit the
magic combination of sprite rotation and scale that caused
the sprite to not be drawn at all.
Memory allocation problem
With that fixed the game works remarkably well. So
much that I was able to play up to the second shop before
crashing. And I think that was due to memory allocation
problems. You can tell performance degrades the longer
you play the game. There seems to be some problem with
all the allocation/deallocation that happens.
Tranlucent rectangles
I changed the game to start on the level that crashed so
that I could play from there. I was able to get to the
final level and got creamed by the boss. Of course I
didn't have the proper powerups that I would have had I
played the game from the beginning. However, the worst
problem was that when the boss' bombs explode they cause
the screen to go white for a short time. On the Yaroze the
white is translucent and slowly fades out. On NUON it
stays totally opaque until the fade out time expires.
Obviously this makes seeing anything very difficult and
fighting the boss next to impossible.
The problem is that I have not implemented translucent
rectangles yet. I will do so to see what happens, but
I suspect drawing a full-screen rectangle will slow things
down too much. I may have to be creative if I want the
effect to be ported correctly (and I do).
Overlay alpha channel
I started adding proper translucency to the sprites
such that the background now shows through. You'll
remember that the background uses the main video channel
while all the sprites are drawn on the overlay channel.
While the lib could handle translucency between sprites
on the same channel, it didn't allow the main channel to
be seen through the overlay. Now I use the pixel alpha
values to properly control translucency. It's not
perfect since it's essentially applying translucency
twice - once in software to combine with other sprites
on the same channel, and once in hardware using the
overlay alpha channel. I think it's good enough.
Future
If I can fix the memory allocation problem and a couple
other minor problems then I think the game will be fully
playable, if a bit slow in places. Once I get to that
point I will work on optimizing things to remove
bottlenecks. It may not be 30fps throughout, but I'll get
it as close as I can.
I'll also be making changes to the gameplay itself to
address a few things. First, many people have complained
the game is too hard - even on the Yaroze. Some of that
is just learning the controls and how to use the planet's
gravity to your advantage rather than fighting it. However,
I do see how it's a tad difficult so I'll take steps to fix
that.
I'll finally fix the controls so that they fit with the
NUON game pad. Getting it working with both the Logitech
and the Stealth is a bit of a pain. The trigger button on
the Stealth acts as an alternate to the A button. This
means the user does not have access to the L button when
using the analog stick. The Logitech (and Warrior) can use
all the buttons at the same time.
The rest of the changes will be things that bugged me
about the original Yaroze version. It'll be nice to
finally get those cleaned up.
|
Food poisoning had my wife and I slammed for a couple
days. Yech. Not fun. We're much better now (and thankful
it's not a more long-term illness like the flu).
Game Progress
I think I found the latest bug by inspection. I won't
know for sure until I can try it tonight. I'm 99% sure
it's the problem, though. If it's not it still needs
fixing. Basically some of the nebulas were showing up
with incorrect colors, but only on a couple frames in the
animation.
A nebula is generating an image with the RGB brightness
values "baked in", allowing me to use a faster renderer in
the sprite lib. However, I think a subsequent nebula
is using the same address for its image due to a memory
allocation bug. It is baking in different RGB values.
This means both nebulas point to the same image even though
they should have different colors. Duh.
|
Game Progress
That wasn't it. @$#(*&!!!
|
Game Progress
I take that back. The fix did work, but I also introduced
a bug at the same time. Funny how it would cause almost
the exact same behavior. Fixing that eliminated the
problem.
Now I'm seeing some of the sprites go haywire after I
leave the game sitting on a level for a while. Humph.
Never ends does it?
|
Game Progress
With the large bugs out of the way I knocked out fixes
for several smaller issues yesterday. I haven't seen that
sprite corruption again. I'm hoping it got fixed along
the way, but it scares me when a bug just stops happening.
It's bound to reoccur.
Here's what I fixed off the top of my head.
- Player messages no longer scroll. They just get
printed immediately. Scrolling took too much time. This
wasn't a bug - just an optimization.
- Added alpha channel support for the rest of the sprite
lib renderers. This fixes an issue I saw with the shadow
sprites.
- Fixed the beacon glow sprite when they get activated.
They now pulsate correctly, although they're still off
center sometimes.
- The energy bar was spiking up to the top of the screen.
Turns out your amount of stored energy could go negative,
which isn't supposed to happen. That's fixed.
- Fixed the background so it no longer disappears when
you die.
|
Game Progress
I played through Decaying Orbit from beginning to end last
night, making note of the remaining issues. I really need
to burn it to disc and make sure it works the same on the
501. I'd hate to find some crashing bug that only happens
on a real system. Debugging that would be a nightmare
*shudder*. Still no sign of the sprite corruption.
I didn't hit all the levels since there are multiple
ways to get to the final boss. It plays a bit slow in
places, but usually stays around 28-30 fps. Speed is one
of those issues that's going to dog me until the end.
I'm now looking into a problem with the level select
feature in the shop. For some reason the map is not
properly aligned, although it was before.
|
Game Progress
The game does crash on the 501. As Kev pointed out to me a
while back, it happens when you destroy an enemy, but not
always. I disabled some sprites I thought might be causing
it. I could play for longer, but it still hung eventually.
This is *not* going to be fun to debug...
|
Game Progress
Thankfully the crash is on one of the rendering MPEs.
The main MPE (MPE3) is still running. It's just sitting
in a loop waiting for all the rendering MPEs to finish,
which obviously won't happen when one of them crashes.
The nice thing is I can print stuff on the screen from
inside this loop. So I can dump registers and memory of
the crashed MPE to see what went wrong. It's a slow
process, but I'll take it. I haven't seen anything
obvious thus far, but it's still early.
It's nice that I'm learning all these things now so
that when I write my next engine I can include debug hooks
to handle crashes more elegantly.
|
Game Progress
The bug is fixed! Wohoo! Here's the debug screens that
I added. When the sprite library detects that one of the
MPEs has crashed it displays this info. It flips between
the two pages automatically so I can snap a pic with my
digital camera and take it back to my PC. It's been a
while since I've posted any screenshots. Mostly because
my screen grabber does not work since I started using the
overlay channel. Gotta fix that some day.
The problem was a simple data address exception. One
of the renderers was trying to load a pixel from outside
the dtram space. This pixel would never be used because
the loop is on its way to fall through, but the pixel gets
loaded before this is known. Loading pixels early
speeds up the renderers, but you do get one bogus read at
the end of each loop. Normally this bogus read is still
within the pixel buffer. Even if it's just beyond the
buffer it still works since it's still within dtram space.
However, for sprites that are scaled way down the
incremental step between pixels can be quite large. So it
actually tries to load a pixel from an invalid address.
My fix is somewhat of a hack, but should work. I
moved the pixel buffer to be in the middle of dtram rather
than at the end. Thus it's less likely that a load that
steps outside the buffer will also step outside of the
entire dtram. I can't guarantee that this works all the
time, but it was the easiest solution. I don't want to
modify the renderers since that would make them slower.
I'll play the game a bunch and make sure I don't see any
crashes. And hey, if it crashes for anyone else then they
can give me the output of the crash dump so I can track it
down more easily!
The reason I don't see the crash on my dev system and
my 504 is that both are Aries3 systems, which has more
dtram per MPE. The exception would never happen because
it's still accessing a valid address. Too bad I can't
put Aries3 chips into a virtual Aries2 mode to mimic
these kinds of failures.
So once again yay! Kev, I fixed your bug. About time too.
|
Interested in Decaying Orbit? You'll want to head over
to NUONica check out the latest
NUON Notes.
|
Game Progress
I found and fixed a major source of slow down. The library
I wrote translates the 4-bit Yaroze sprites into 32-bit
sprites that NUON likes. It's not fast, but it usually
happens only the first time an image is used. However,
whenever part of the sprite gets overwritten in Yaroze-land
the 32-bit image must be regenerated. It turns out that the
library was regenerating images regardless of whether or not
they were actually used during that frame.
The problem really shows after exiting a shop to start
the next level. The time counter at the top of the
screen uses the same image space as the shop's minimap.
Thus the minimap was regenerated quite often even though it's
no longer used. This is a 256x256 image so you can guess why
it was slowing down.
I changed the lib to only regenerate images that are
used in the current frame. Speed is much improved.
|
Game Progress
I retrofitted the 4-bit image generation routine to work
with 8-bit sprites as well. To my surprise it worked the
first time (and didn't even break 4-bit sprites in the
process). That doesn't happen too often.
Also forgot to mention that I fixed how the bonuses
don't bounce off the top edge of the screen correctly. I
found a bug in the original code. Kind of silly I didn't
find that back in the Yaroze days, but I probably didn't
bother looking since it kind of worked anyway.
Hmm, not too many fixes to go.
|
Game Progress
I'm in the midst of changing references of the Playstation
buttons to their NUON equivalents. Unfortunately this
isn't as easy as updating the graphics files. The graphics
for the R1, R2, L1, and L2 buttons are larger than the rest
due to having to fit two characters.
Then there's the matter of changing the instructions
that are accessible from the main menu. Not only do they
reference PSX controls, but they also have two different
sets depending on whether the player uses a dual shock or
a regular digital pad. Thankfully the NUON controls are
the same for both. Although it is a shame to forfeit the
second analog stick as it made thrusting more precise.
|
Game Progress
I believe I have all the references to Playstation buttons
changed to NUON. Next on my list is to fix the screen
flash that happens when the boss bombs explode.
On the Yaroze I simply draw a translucent rectangle over
the entire screen, altering it's brightness to control the
flash fade. This would take too long on NUON, though. So
I'm creating new sprite renderers that allow me to add a
constant RGB value to every sprite pixel as it is rendered.
That way I can brighten all the sprites without drawing any
extra pixels.
|
Game Progress
I recently had reason to finally get my screen shot routine
working again. As it turns out I had most of it already
written. I don't remember doing that, but I'm glad I did
since it saved me tons of time.
The goal is to be able to plug the screen shot module in
to any NUON application and take shots with minimal code
changes. It works by patching the BIOS jump table with my
own video routines. I keep track of the screen buffer
address and dimensions by intercepting calls to VidConfig,
VidSetup, and VidChangeBase. I also replace VidSync and
check for the designated buttons that tell to grab a shot.
Of course all these routines call their normal BIOS
equivalents after doing their thing. Eventually I want it
to work with any combination of main & overlay channels.
So far I only have the bare minimum implemented to work
with Decaying Orbit. But that's what matters eh?
I had to adjust the gamma on these images so that the
nebulas are visible. The images as captured are way too
dark. That seems odd since the game is quite bright
enough when I play it on the TV.
I also completed my changes for the screen flashing as
mentioned last time. It looks great - I like it even
better than the old brute-force implementation of drawing
a rectangle over the whole screen.
There's a few remaining items in this thread. I have a bunch more on my own list, but none of them are a ton of work.
|
Game Progress
Super awesome progress this weekend. At least it felt
really productive. Sitting here trying to recall
everything I did it doesn't seem like much. Maybe I'm
forgetting something.
I fixed a long standing bug in my sprite renderers. It
was due to my misunderstanding how the "sat" instruction
works. The effect was that some colors had their RGB
components clamped to 127 rather than 255.
The money that emerges from a destroyed enemy is now
color coded depending on the amount. That should make it
easier to prioritize which ones to go after. I need to
tweak it a little more since they can blend in with the
explosion debris if they happens to be the same color.
I added a feature that I wish I had in the Yaroze
version. The game now remembers the state of your system
priorities when you start a level and will restore them
should you die (rather than reseting them all to
medium).
I drew a new beacon image and made the glow much nicer.
It's all aligned properly now.
The control config in the pause menu works now. The
sprites weren't showing up before.
Something more subtle. To get the player speed to feel
right in the Yaroze version I actually only moved the player
every third frame. I changed that so the sprite moves
every frame, but only a third as much. That makes player
movement a tad smoother.
Finally, I fixed a bug left over from the original
version. If you collected a bonus system after destroying
an enemy and then died, that bonus would disappear forever.
The state of your ship is supposed to reset back to what it
was at the beginning of the level, but the system is also
supposed to be reset back in the enemy so you could collect
it again. The latter wasn't happening.
|
Game Progress
I fixed the bug causing the energy bar to spike to the top
of the screen. It was related to my changes that fix the
framerate at 30fps.
I also did some work on the cheat menu. I changed the
buttons that enter the codes to use the NUON C-buttons. I
still have to choose new cheat codes so that people can't
just use the Yaroze codes to blow through the game. In the
process of all this I discovered that the latest demo has
all the cheats available for use despite my desire to
remove them. Ah well, at least it's not the full game.
I have eleven items left on my to-do list, and only one
of them should take more than a half hour.
|
Game Progress
Added one more to the list (Arethius'
comment
about slow turning rate) and knocked off three. So we're
down to nine items remaining. Hard to believe this f'ing
thing will finally be done!
|
Work has had me slammed the last week or so. Leaving
work after midnight and getting up at 7am the next day
ain't fun. Do it three days straight (and looking at a
fourth) is very draining. Things will settle down in a
few days. Maybe I can get something done on the game this
weekend. Assuming I don't have to go into work...
|
Work has eased off somewhat. I no longer need to stay
super late, but I still have to go in at 8-9pm to finish
up some stuff. Thankfully that should stop in the next
couple days.
Game Progress
Got a bit of work done on the game over the weekend. I'm
adding some hints that pop up at the start of some levels.
They give bits of info about new gameplay elements.
Hopefully that will ease people into the game much better
than before.
|
First my son caught a stomach bug from day care. Then
he passed it on to my wife and me. This weekend was not
the best. We still feel a bit off today, but thankfully
we're not hurling any more. Too much info?
Got Gradius V last week and
played through it quite a bit over the weekend, when able.
Shmups are not my favorite genre, but this one is very
tasty. It's been a while since I've played a game that
tested hand-eye coordination so much.
I've gotten up to level four after changing the number
of starting lives to 5, lowering the points for an extra
life to the minimum, and receiving an extra credit (you
start with three credits, but gain more the longer you
play). I just earned a fifth credit so I should be able
to get further still. I'm playing it on Normal difficulty.
I can't bring myself to play on Very Easy as that seems
too much like cheating. Er...
No game progress I'm afraid. I hate these long lapses
especially when it's so close to being done. If no one
gives my son the flu any time soon then I can finally get
it out the door.
|
I won a copy of the UK Official Playstation Magazine
#108 off of eBay. This is the final issue and has a big
Yaroze blowout on the cover disc, including Decaying
Orbit.
Click image for larger version
Not a bad write up. Thanks to OPSM for putting the game
out one more time. I especially like the "Good God, this
could have made for a proper release". Also, you gotta
love that British wit "The music could be the best music
on any PSone game ever". (There is no built-in music -
background music is provided by any audio CD you
insert.)
Unlike last time I've yet to hear from anyone that's
played it, but I'm sure it got partially drowned out due
to the number of games on the disc.
I have resolved not to play Gradius
V until Decaying Orbit is complete. Plays take
30-45 minutes each - time better spent programming.
|
Game Progress
So this weekend I finished fixing all known bugs in the
game. I burned a disc and planned to play the game for
a while on the 501 with notepad at hand to write down any
further issues. Put in the disc, the game crashes on the
very first sprite drawn. *sigh*
I'm tired of this crap. There aren't *that* many
differences between Aries 2 & 3. Why the hell does the
dev system behave differently than a real player?
Thankfully I have both an Aries 2 and Aries 3 dev
system board. I swapped to the Aries 2 and breathed a
sigh of relief that it fails the same way as the 501.
Meaning I can debug it on there rather than the burn-try
cycle.
From now on I will be developing on the Aries 2 dev
system. Only at the end when I want to put in Aries 3-specific features will I swap to the other board.
|
Game Progress
I had every intention of releasing the game this weekend,
but this latest bug is a doozy. The problem is in the
sprite library due to some changes I made for the screen
flash. I added a field to the sprite structure, but it
seems that reading in one more scalar breaks things for
reasons I have yet to determine. The failure is not
consistent. Some times it's a data address error. Some
times it gets caught in a DMA wait loop.
It's good that I exposed a bug like this before release,
but damn if it doesn't put a crimp in my schedule.
|
Game Progress
Tricky one that bug was. The gist of it is that when
storing data in instruction ram you must always store a
vector at a time. If you store less than that then the
unused scalars will be corrupted. I knew about this for
general store instructions, but evidentally it applies to
DMAs as well. The sprite library was reading in the
renderer and the buffer wasn't vector aligned. So it
corrupted the instructions just before, causing various
forms of mayhem.
My first clue last night, and the reason why it works
on Aries 3, was that I saw the data address error was
caused by the stack pointer incrementing past the end of
DTRAM. Since Aries 3 has more RAM than Aries 2 this didn't
trigger an error, although it likely would have caused
weirdness anyway.
The stack pointer getting out of whack was caused by
the sprite lib executing a pop instruction without a
corresponding push. Debugging that showed me that the
sprite rendering loop was being called when it should not
have been. Turns out that the routine just before the
renderer ends with a branch, but that branch was getting
wiped out by the corruption mentioned above. So after
finishing that routine it just kept executing merrily
along.
Oh, and I have yet to determine how all of this is
related to my post from yesterday about reading in one
extra scalar. I'll do some experiments tonight to figure
that one out.
[UPDATE] I think I know the reason, but
need to confirm it. The working case DMAs 15 scalars,
while the failing case reads 16. This value is put into
a register via the mv_s instruction. The assembler uses
a 16-bit instruction encoding for immediates between -16
and 15 inclusive. Using a larger value bumps it up to
the 32-bit encoding. This likely pushed the renderer
buffer off of a vector boundary. However, I also tried
reducing it to 14 and it failed for that too. So I still
need to do some investigating.
I don't know if I'll get the game out this weekend. I
want to spend a bunch of time playing it. Hopefully
some time next week.
|
This web page and all other pages on this site are
© 1999-2007 Scott Cartier
|