Register | Login
Views: 19364387
Main | Memberlist | Active users | ACS | Commons | Calendar | Online users
Ranks | FAQ | Color Chart | Photo album | IRC Chat
11-02-05 12:59 PM
Acmlm's Board - I2 Archive - - Posts by Kagerato
Pages: 1 2
User Post
Kagerato

Goomba
Level: 9

Posts: 1/25
EXP: 2655
For next: 507

Since: 08-08-04

Since last post: 382 days
Last activity: 29 days
Posted on 08-08-04 09:28 AM, in Megaman 4 Hack Released! Link
Finished playing through the whole game. Well done.

Level design was about equal quality to the original game, on the whole. Overall it was more challenging, sometimes in good ways (made you think a bit), other times in bad ways (ex: falling on spikes that you couldn't possibly avoid if you hadn't gone through the stage before). The wire and balloon were useful a great deal more than in the original levels, especially in the Cossack and Wily stages. In some places you absolutely required them, as far as I could tell. (Which means if you were out of energy, that life was pretty much guaranteed a goner.)

I noticed a number of minor graphical glitches: When the switches on Drill Man's stage activate the new ground necessary to progress, the palette is still red (rather than green). Additionally, there were a bunch of places where the tip of the ladder was unusual (on one stage, the tops of many ladders were undergoing palette-swapping, like the background). Last thing I can remember is that the tiles for the Cossack logo on the first stage were replaced with something else. None of these bothered me significantly, but I couldn't help seeing them.

The only major gameplay glitch I saw was the one the author pointed out personally: the first Cossack boss is very likely to kill you on entering (is it more likely on the first entry? not sure).

It was nice having to use the rush marine for once. It's normally not required in any way, and sometimes even more of a hindrance than a help. These levels actually forced it into good use.

I ran the normal boss sequence (Toad -> Bright -> Pharaoh -> Ring -> Dust -> Skull -> Dive -> Drill) without any problems, but I can see how doing some stages first would be pretty difficult, if not impossible. Dive was the most challenging stage for me.

I thought parts of Dust's stage (where the floor blocks had intermixed colors) looked pretty weird. The last few screens of the stage were consistent and good-looking though, as was the section where the crunching pillars raise and lower the 'dust'.

Skull's stage had a rather sudden change of background (sky) color. While it didn't look particularly ugly in any way, the effect would have been more impressive had it occurred gradually.

An anomaly I'd like to point out in Ring's stage...should you die and restart at the mid-point, the sky will be bright blue again. Then it will suddenly change to black after causing the vertical scroll.

Certain enemies taking more hits was fine, and even welcomed. However, seven hits for one of those weirdo cell-like creatures in Toad's stage is going overboard. Heh.

Overall, good job Schwa. I look forward to future works from you.
Kagerato

Goomba
Level: 9

Posts: 2/25
EXP: 2655
For next: 507

Since: 08-08-04

Since last post: 382 days
Last activity: 29 days
Posted on 08-08-04 11:19 PM, in Is there a program that..... Link
There are quite a few hex editors with advanced, 'resynchronizing' compare functions. At the moment, I can't think of any that are freeware. The one you'll see recommended a lot is Hex Workshop. There are others, just as good or better, but workshop is the most popular as far as I can tell.

The compare functions in these hex editors are rather thorough. Additionally, the interface is usually good enough to quickly jump between the additions/deletions/modifications that you can sum up the differences between most files in less than a minute.

Since you only asked for a way to compare files, I won't bother going into any details about other features of said hex editors.
Kagerato

Goomba
Level: 9

Posts: 3/25
EXP: 2655
For next: 507

Since: 08-08-04

Since last post: 382 days
Last activity: 29 days
Posted on 08-08-04 11:27 PM, in Z3: GoD -> Which sprite sheets are better ? Link
"Hey Ho" and "Break Dancing" would also be quite humorous.

Though I think after playing the game for a while, these kinds of animations would get annoying. Especially if they occur soon after Link becomes idle, and there's no way to turn them off (except moving again).
Kagerato

Goomba
Level: 9

Posts: 4/25
EXP: 2655
For next: 507

Since: 08-08-04

Since last post: 382 days
Last activity: 29 days
Posted on 08-09-04 04:53 AM, in How do u make a ROM level editor? Link

It looks like no one has mentioned Dev-C++. It includes a compiler and an integrated development environment.

I haven't used it much myself, but it seems like a good free piece of software.


The environment itself is excellent, but the debugger (probably the most important component of any programming IDE) is weak. The basis on gdb isn't bad; it's the fact that there aren't any special windows or layers created to increase debugging efficiency.

MinGW Studio has a significantly better debugger. You can hover over local variables to get tooltips of their value, and the watch window is superior to Dev-C++ 5 watch capabilities.

You can hook up Dev-C++ 4, and therefore probably 5 as well, with Insight -- a fairly advanced interface to gdb. It's a bit of a hassle though, and you'll first need to overcome the pre-requisite of obtaining a windows build of Insight. I've never used Insight, but from what I've read and seen concerning it, it seems easily superior to the two previously mentioned debuggers.


(edited by Kagerato on 08-08-04 07:53 PM)
Kagerato

Goomba
Level: 9

Posts: 5/25
EXP: 2655
For next: 507

Since: 08-08-04

Since last post: 382 days
Last activity: 29 days
Posted on 08-09-04 03:36 PM, in Megaman 4 Hack Released! Link
If you thought the first review was intense, watch out. I just finished playing through this excellent hack once again. (Replaying a hack...wow. There are some original games that I would never play more than once. Guess that's the best measure of how much I enjoyed it.)

This time, I took the liberty of being inventive and/or random with my stage selection. The order was: Drill -> Toad -> Dive -> Skull -> Ring -> Pharaoh -> Bright -> Dust .

Other than the part about the red-based colors used for drawing in the new landforms, Drill Man's stage also has another obscure graphical abnormality. When you die and restart at the mid-point, you should see that the graphics of those extremely-annoying shutter enemies has changed to something entirely different. Not very pretty.

I liked Drill's stage more the second playthrough. The greenish rock hues are actually pretty nice, and the level, while deviating somewhat from the original scheme, keeps up the Capcom spirit of 'slightly difficult and unpredictable, but not impossible' (even though I had nothing but rush coil to assist! heh). Find a way to customize the colors used for the ground's fade-in effect, and the whole stage shall come together quite nicely.

The interesting thing about Toad's level is that I died more times than I did on Drill (and I consider Drill a harder stage!). Three lives lost to mostly carelessness on Toad, versus two lives lost mostly to unpreparedness on Drill (had to figure out some things about succeeding in the stage without Skull and other items).

Something I forgot to mention but did notice the first time around on Toad's stage; the second to last umbrella enemy (near the end of the rain section) appears in mid-air. Normally, those guys appear at the top of the screen and float down. I'm thinking this was intentional, and it does make it slightly more difficult to get by that part.

Another thing: after getting past some of those cellular blob enemies, Megaman encounters three sewer rats in a row. The first two seem to be a bit glitchy or even stuck; they don't really come after the player as one would expect from their usual behavior. I think it's due to them being so close to that low ceiling.

This time around I remembered to take written note of the fact that the first snail encounter has a left wall which apparently shares its palette with that of the snail itself. Therefore, when you hit it, the whole wall changes to white as well. Not particularly annoying or anything, but I can't seem to figure out why it would be necessary to have it that way. There is a similar effect by the second snail, but it only affects the section of floor blocks that are directly beneath Megaman.

On the whole, I felt Toad's stage was challenging, but not as much as Drill's. If I had been more careful I could have made it through without losing any lives. But I suppose mistakes are to be expected when you're playing past 2 am.

Next, we have Dive. Oh boy. I hate this stage for one reason and one reason only: it's immensely difficult. It's extremely fortunate that I did Toad before this one, cause I can only nail the necessary jumps 50% or less of the time (and without Rush Marine, there's no other way past).

The very first section pits me against those **** jumping fish-like enemies, which always prove to annoy me. They hurt quite a bit, and in tight places are difficult to react to effectively (generally a charge shot is the only way to prevent a hit when backed in the corner).

There is at least one screen (I found from experience) where if you don't scroll all the way to the right, when you drop to go to the next screen you'll most certainly die (the whole acts as a pit rather than a transition). That fortunately only caught me once (oddly I did not encounter it on the first playthrough). I believe it is after a horizontal section, and I *think* it was right before the screen darkened and the tube animation activated.

Speaking of that sudden palette change, it's rather enjoyable. To see the tubes suddenly a-glow when they weren't before, especially against the darkened BG color, is rather surprising and almost fascinating at first.

Know the place where the second whale appears? The spikes laid at the top of the screen there do a similar white palette swap along with the whale as it gets hit. I haven't found those spikes to be anything resembling a threat...though they look somewhat cool just sitting way up there. Heh.

I could swear that there is a point in Dive's level where you meant to create some sort of secret side-path but then opted out of it. I believe it's directly at the beginning of a horizontal scrolling section (and I think just before that 'pit' which transforms into a next-screen transition only if you scroll far enough right). There are a number of spikes lining the bottom of the horizontal section, and far to the left there is a whole where only Rush Marine could reach. That would have been an interesting place to scroll onto a screen containing the Wire.

There are two pieces to Dive's level that I find massively difficult (unless I get lucky). The first is where there is a hard hat sitting on a platform just beyond one of those weird swooping enemies which drops out of sight. With spikes lining the floor and ceiling, there are two choices: lure the hard hat off the platform, and then make a precise jump to where the hard hat used to be, or get hit somehow [possibly by the green swooping enemy] and do a jump off the spikes. Both are dangerous, and the former takes patience. Of course, the situation assumes that you don't have the rush marine .

Second area is what I can only deem 'the long jump'. Rising and falling water levels (hard to call them tides) along with one of those ultra-annoying won't-suicide-itself-by-jumping-off-screen green swoopers create a rather limited window of opportunity for the jump to a distant platform. But that's not the worst part: if you do actually make the jump, you'll have to contend with a forward-moving (right towards you) enemy which is likely to knock Megaman into the pit unless he jumps immediately after landing. I'll say, it's quite the difficult task. I managed to pull it off twice out of quite a few attempts...Rush Marine am goal.

Also, when moving onto the screen of one of the whales (I think it's the first one), the tile graphics from the previous screen garble as they're replaced in RAM with the ones needed to draw the whale. Not really anything that can be done about this. Changing the level drastically at this point is out of the question.

Near the end of the stage, the spikes that are above water almost look like they're encased in strange blocks because the BG color of the tiles they're drawn in is different. It's not particularly bad or even that strange looking, but I'm curious as to why it occurs.

You can probably guess why I had so many comments on Dive Man's level. I played it many, many times (part of the reason is that I didn't have Skull's weapon and was training myself to take him out with buster only).

OK, on to Skull.

There is still a spot on Skull's stage (it's precisely below the mid-point start location) where you can die because it's a pit and not a screen transition. Even if you use the ladder (I tried just to be absolutely certain), Megaman still dies.

On the last screen of the stage before the gates, four (I counted, four) of those spiked wavering enemies spawn at once. Considering the two skulls also on that screen, I think it's overkill. Especially since the six + megaman all doing something together causes significant slowdown (NES limitation, I would think, more than anything else).

As for Skull himself, I haven't seen him do anything unusual. Yet.

My new overview of Ring's stage is pretty short. I found the stage far, far, far easier when I had both Dive and Drill weapons available; as you probably recall my last order gave me neither of them at that point. The acid rain still proved useful, but it's nothing that couldn't be replaced by Dive.

The spot where the energizer lays has some sort of invisible block to the right of it. I have no clue what it really is, but it's solid and it knocks Megaman back into the wide pit if he tries to jump towards it from the left (making it essentially impossible to get the energizer and survive if you don't have balloon yet).

There's also a glaringly apparent graphical glitch. The hippos are drawn before they normally are in the original game, and only when they actually spawn by 'beaming down' are their noses drawn in. It's rather funny (both odd and humorous).

Ah, Pharaoh. Great stage design; I especially love the three horizontal scrolling parts (and the last one most of all -- keeping the platform from getting too far ahead of you adds a whole new element to that section; especially noteworthy because the original design for that area was just a bunch of easy ups and downs).

Having the quicksand at the beginning of the stage as pitfalls is devious, but not entirely unjustified. Curiosity killed the cat.

The only problem I've encountered on that level is that the boss doors at the end of the stage do not animate. Improper alignment? The sound is fine, and then still function, but they're graphically inert.

I like Bright Man's level even more than Pharaoh's. In fact, I think it's my favorite (I'll explain why when Dust comes around). No significant errors whatsoever on the stage -- only two minor things that no one in their right mind would care about. (If you're real curious: the large red machine-enemy which is on a screen by itself starts by facing the same way [left] as Megaman and therefore has to turn around [but it's AI makes it do that immediately, so no loss]. Secondly, a palette-change occurs a little bit after you've travelled to the right on the last horizontal scrolling section of the level, which results in the spikes turning from normal color to yellowish. Again, nothing significant or even really noteworthy.)

Bright is somewhat difficult on the first time through, but probably the easiest of all the stages (I see why you recommended doing it first). I find myself preferring the stage after obtaining the Balloon; Rush Coil is a bit tedious by comparison. The double energizers is a truly awesome bonus for completing that section of the stage. [This level makes it much faster to fill up on Energizers for the Cossack and Wily fortresses.]

Of course, I may be a bit biased -- Bright's stage also has great music.

Last but certainly not least is Dust. While I still think this stage could use some aesthetic touch-ups, the level design itself is top-notch. In fact, now that I've been able to go through each stage several times, I consider this one the best. It's balanced: straight-forward without lacking diversity, and includes a number of tough but certainly not impossible spots, even without anything but a rush coil. While I'm biased for blue over green in my color preferences, you have managed to do good work with the green tiles as well.

Again, that last one is somewhat leveraged by the fact that I consider Dust's stage to have the best single music track in the game.

Phew...this post is getting enormous, and I haven't even covered the Cossack or Wily stages yet! Fortunately, my remaining comments are lesser in number and a bit more to the point.

Cossack Stage 1 -- The first thing I notice here is your custom background. While a city out there is a welcome change from the complete wilderness we were previously accustomed to, I think it's a bit limited. More colors and an illusion of depth would add to the experience, and make anyone stop and gaze at it for a bit before continuing on.

After the second vertical rise, there's a screen with an open section to the left. I'm wondering if you meant some secret to be there (in fact, I haven't thoroughly investigated it for that). There's also a slight graphical irregularity on this screen: part of several tiles which are clearly background are actually drawn in the foreground. That way they tend to cover Megaman's legs. I could have sworn I saw this behavior somewhere else as well, perhaps on an entirely different stage, but definitely did not see it again this time around (was it fixed in the update? possibly).

Near the beginning of the second horizontal scrolling section, there are two small and funny-looking tiles. No idea myself. Are these sample tiles from the background, overwritten from the originals?

I found it somewhat odd myself that after I had continued on this Cossack Level #1, when I returned to meet the boss it did not kill me immediately, even though it was the first entry. What changed when I continued? I don't get it.

Of course, I already mentioned the Cossack logo is replaced with something else. It looks almost like a part of sky, or maybe fire?

Cossack Stage 2 -- I scoured this stage pretty well for oddities, but found exactly zero. Excellent job on this one. I know the background snow already existed here, but you expanded on its use in good ways.

Stage 2 is also a very welcome breather from that hell known as Cossack Stage 1. The difference in challenge is tangible. A good refill stage -- I spent so much time skilling skulls this go-around that I had nine lives before leaving the level. Of course, such circumstance resulted in the 1-up at the end of the stage being overkill.

Cossack Stage 3 and 4 -- Nothing unusual to report. Good levels, and challenging precisely because you must ration your abilities' energy: otherwise you may have to die just to get usage of one back.

Wily Stage 1 -- My advice: just don't play this one when you're about to fall over in your chair. Mistaking the Rush Coil for the Rush Marine is very, very bad. (I jumped directly into the spikes, and there was absolutely no avoiding it after I stepped on rush. lol)

If there's any improvement to be made here, I think it would have to be in customizing the pop blocks pattern (further? I think it's the same as the original, though I could be mistaken).

Wily Stages 2 and 3 -- Can't remember much to say about these. I was getting pretty groggy by this point. Stage 3, which revisits the robot masters, is pretty short and rather to the point as to be expected. It's a bit too similar to the original in that respect, perhaps.

Final 'Stage' -- Not really much of a level because of the length. I like what you did to the graphical design, it totally knocks off the old patterns.

Can't really do much to make Wily more difficult. Making him take more hits would just be annoying. And customizing his AI into something reasonably challenging for an experienced player of this game (the only type that would ask for such a thing) would have a rather low work-to-benefit ratio.

Quite a post this became. If you can believe it, most of this information is just rephrasing stuff I wrote on yellow Post-Its while playing through.

Great hack, and at this date and time I would even put it at #1 (best hack) for my 'played-and-completed' hacks list.

I look forward to seeing future megaman works, or even new level designs for any game, from you. Perhaps you'll even come back to make another excellent megaman 4 hack, when you've finished with some other projects?


(edited by Kagerato on 08-09-04 06:36 AM)
Kagerato

Goomba
Level: 9

Posts: 6/25
EXP: 2655
For next: 507

Since: 08-08-04

Since last post: 382 days
Last activity: 29 days
Posted on 08-10-04 01:37 AM, in Megaman 4 Hack Released! Link
I may have some information which would be useful in fixing the Drill Man glow-in landforms.

The NES, being a surprisingly limited machine, cannot change its own physical palette (simply put, the actual colors themselves are hardcoded). Which explains why *.pal files are necessary to acquire a new palette in emulators; they're cheating by emulating a different palette than the one the NES has.

The PPU [picture processing unit; by analogy it's the video card of the NES] has an area of RAM often referred to just as the "palettes", but more specifically, it's two palettes: one for 'images' and one for sprites. The image palette begins at $3F00 and the sprite palette begins at $3F10 (addresses in PPU RAM, of course). As you can see, each palette is $10 (16 decimal) bytes long, and a byte is used for each color. Therefore there are 16 colors in each palette, for a total of 32 colors. However, $3F00 (the first color of the image palette) and $3F10 (the first color of the sprite palette) will always be the same, so in actuality there are only 31 colors to work with.

As I mentioned earlier, it's impossible to re-define the original 64-color palette on the NES (except by method of false emulation). So what purpose does the palette data in RAM on the PPU serve? The function of the image+sprite palettes in the PPU's RAM is to define which of the 64 colors in the total NES palette are selected for actual use. In other words, the bytes there are indexes, not actual color (RGB) definitions.

Now, how does this help you? Well, this information lets us track down where the palette indexes are originally selected in the ROM.

Whenever an NES game (program) wants to change the colors available to draw on-screen, it has to write to that section of PPU RAM to define new indexes. PPU RAM, completely separate from regular NES work ram, can only be accessed by the program through registers (pre-determined addresses physically mapped by the hardware to perform a particular task -- the PPU registers are located in a section of the CPU memory map that would never normally be read or written to).

Therefore, it is quite likely that a game such as Megaman 4 writes new indexes to PPU RAM for every stage (so that it can make use of whatever colors the developer felt like). The register for reading or writing to any part of of VRAM (synonymous with the PPU's onboard RAM) is $2007 [we don't need to worry about $2005 or $2006, which specify the address to read/write to/from, because we're not changing the location at all].

Now we're getting somewhere. Fortunately for us, wiser souls have already programmed tools called 'debuggers' -- essentially an emulator (or sometimes pseudo-emulator) which allows you to run through the program code (of say, Megaman 4) and see updates to memory and processor registers (such as A, X, and Y) as each instruction executes (commonly known as 'stepping through' or 'stepping into' a procedure). The best debugger currently available for NES, IMO, is FCEUd: http://desnet.fobby.net/index.php?page=utilities&id=18.

And here's the good part: the greatest of these debuggers even let you specify breakpoints; particular addresses which, when read or written (or both), you want the debugger to stop running the code normally and let you see what's going on. By setting a write breakpoint on $2007, a person can quickly jump to the next point where PPU RAM is written. If we narrow such a search by only setting a write breakpoint just before Drill Man's stage is loaded, the likelihood of stopping on the very procedure that writes the palette indexes for his stage is high.

Once the debugger is stopped by the breakpoint at the start of that procedure, we can see where exactly from PRG-ROM the new indexes are being loaded from. There will be a load operation, very likely a load into the accumulator (LDA). FCEUd tells you next to that instruction, with an @ sign, the address that the load ends up actually taking data from.

Since the data being loaded must be in PRG-ROM at the time this procedure is executed, we can immediately go take a look at that address by the @ sign and see what's at it (use the Seek To capability of FCEUd). By writing down enough bytes from that address and immediately beyond it in sequence (essentially we are copying a short section of one of the PRG-ROM banks), it is possible to get a unique-enough string of data which will only occur once in the entire ROM. Usually ten or twelve bytes is enough, but to be on the safe side I'd go as far as eighteen or twenty.

Once that data is available, it is a simple matter to do a find operation using a hex editor loaded on the ROM for the obtained string. If the string of bytes was unique enough (long enough), the results will list only one address. There's the palette indexes for the stage.

When we know where the necessary data is, it's a pretty simple matter to modify it. Even trial and error will succeed within a short period of time. Essentially, it would just be figuring out which colors the fade-in of the cliffsides use to do their work, and replacing their indexes with the equivalent indexes for green colors.

I'm sure all of that is quite confusing if you've never been introduced to it before. Feel free to ask me any questions. Also, rest assured -- the method I just described is actually several times, to tens of times, faster than any other methods once you understand how to do it. It would only take an experienced user of a 6502 debugger and a hex editor three or four minutes to locate the appropriate data. The fact of the matter is that modifying it sometimes takes longer than finding it (quite humorous, if you think about the relative simplicity of changing the data as compared to all that I had to describe just to find it).

BTW, much of what I wrote here is just an extension or elaboration on things listed in TFG's short-and-useful tutorial: http://tfg.panicus.org/files/docs/nes_pal_fast.html. I used it as a reference (one of several) while writing this. Yoshi's NES comprehensive doc is also quite valuable.


(edited by Kagerato on 08-09-04 04:40 PM)
(edited by Kagerato on 08-09-04 04:43 PM)
(edited by Kagerato on 08-09-04 04:44 PM)
Kagerato

Goomba
Level: 9

Posts: 7/25
EXP: 2655
For next: 507

Since: 08-08-04

Since last post: 382 days
Last activity: 29 days
Posted on 08-10-04 05:38 AM, in Megaman 4 Hack Released! Link
That part about Proto Man scared me. I had just been thinking of precisely the same idea (though applied to any Megaman game) just yesterday.

Yes, you could change Megaman's colors with the given method. The sprite palettes (technically each palette is four colors) are right after the 'image' palettes (which cover just about everything else) in PPU RAM. $3F00 versus $3F10. However, I suggest you pick up yoshi's great doc from zophar and read all the sections concerning palettes (might want to look at the PPU registers too). There's some tricky stuff, for example: when you write to the 'image' palette, the changes automatically mirror inside the sprite palette. So in order to customize the sprite palette, you absolutely must write to it after the image palette. Which I suppose is logical thinking anyway, considering their order in PPU RAM.

The sprite palette indexes don't need to be reloaded every time you change weapons as long as all the used indexes are available in the sprite palette. If that's the case, it is possible to switch colors on a sprite by manipulating another area of PPU RAM -- Sprite RAM (SPR-RAM). Sprite RAM is actually a subsection of the pattern tables, which themselves are of course also in PPU RAM. There's two bits in SPR-RAM which are used to form the full 4-bit color index. With only four possible variations there, this means that Megaman 4 likely does it a different way (either what you originally said, or by an entirely diffent kind of change).
Kagerato

Goomba
Level: 9

Posts: 8/25
EXP: 2655
For next: 507

Since: 08-08-04

Since last post: 382 days
Last activity: 29 days
Posted on 08-11-04 03:30 AM, in EggVine - Yoshi's Island Editor Link
Here's an idea then: don't use it.

Squash will implement graphics approximately "when he damn well feels like it". I'm sure he wishes it were a very simple matter to draw entirely using graphics ripped from the ROM. Unfortunately, those graphics may be compressed (which adds an additional step: decompression), and they always have to be converted to an RGB-style format before they can be effectively drawn on screen (our systems are based on the concept of each pixel is given a precise RGB-defined color, very unlike the tile-based system on the SNES). Let's not even get into sprite assembly, and the massive number of variations a sprite can be represented as in the ROM itself.
Kagerato

Goomba
Level: 9

Posts: 9/25
EXP: 2655
For next: 507

Since: 08-08-04

Since last post: 382 days
Last activity: 29 days
Posted on 08-11-04 03:38 AM, in Megaman 4 Hack Released! Link
Potentially. However, I do not think simple hex editing alone would be enough.

Games like megaman are designed to use variable size sprites in their engines. However, those are always enemies, not the player. Enemies do not follow nearly the same rules or receive nearly the same kind and variety of inputs, so the code that handles them is entirely different.

Example: collision detection. Many enemies in megaman do not even move, or move in very predictable, simple patterns. And some enemies have no collision detection at all! (if they're meant to harm Megaman, it is enough to detect when he collides with their location and entirely unnecessary to do the reverse)

When you change the size of our player (whatever his name), the collision detection is going to have to change to some degree as well; proportional to the amount of size change.

Other considerations...if the new player is taller and the cannon is positioned at a different height, the game needs a new shot procedure in order to spawn the bullets at the correct height.

The routines that physically draw megaman should not be too different, if at all different, from the ones that draw enemies. Therefore, such a routine is already adapted to variable-sized sprites and shouldn't cause nearly as much a hassle as the rest. We hope.
Kagerato

Goomba
Level: 9

Posts: 10/25
EXP: 2655
For next: 507

Since: 08-08-04

Since last post: 382 days
Last activity: 29 days
Posted on 08-12-04 12:23 AM, in Megaman 4 Hack Released! Link
For ZIP, RAR, 7Z, TAR, and some other formats, I recommend 7-Zip. It's free and it's functional.

http://www.7-zip.org/

As for the idea, it's all right. I think it would be a bit weird to play megaman 2 and then 3 in sequence, if that were the case in the original game.

Anyway, I'm not one to put down a decent idea without having a much better one, so I'll leave it at that.

Remember that long post describing the method of finding the palette indexes just a little while back? I decided to test it out for fun. And for the benefit of all, I recorded the actual process steps.

-- BEGIN --

The first significant thing I did after loading Megaman 4 was open the PPU Viewer window. It's a very useful add-on that's only present in FCE Ultra debug, not the original FCEU.

My most immediate discovery, and one that could likely be figured out by anyone who sat down for a moment to think about it, is that all the fancy color shifts in the intro, along with those vertical-travelling horizontal bars of color, and right down to Megaman's green charge glow, are all accomplished by changing the PPU's palette indexes [the indexes are at the bottom of the PPU Viewer window; hover the mouse over one to get its actual byte value]. After all, it would be too much work (and too much space) to have separate tiles for all the variations.

FCE Ultra debug also has a nifty little feature which allows you to not only set breakpoints on CPU addresses, but also PPU addresses. I set a PPU write breakpoint on $3F00 after selecting Drill Man's stage but before the fancy color cycling was finished. That led me to...

The main loop that does the palette writing to the PPU image and sprite palettes (via $2007), located at $7C0A0 in the ROM itself (very close to the beginning of the last PRG bank; this bank is probably left loaded by the game at all times since the procedure was not mirrored anywhere else). To find it, I just wrote down the bytes that make up the routine in sequential order and queried the ROM using a find function in a hex editor. Though note that this loop is only a section of the whole procedure.


$C09F: BD 00 06 LDA $0600,X
$C0A2: 8D 07 20 STA $2007
$C0A5: E8 INX
$C0A6: 88 DEY
$C0A7: D0 F6 BNE $C09F


As you can see, basically all this loop does is load the palette indexes from a section of ram (if I hadn't known what $0600 referred to in the CPU memory map, I would have looked it up [yoshi's doc]), specifically the one that begins at $0600. The loop exits when Y reaches zero (that would cause the Z processor flag to become set, and the branch if not equal instruction only branches when Z is unset). The Y index is setup in an earlier part of the procedure (before the loop, not shown) to be #$20 [32 decimal]. That way the loop can write all 32 indexes, 16 for the image palette and 16 for the sprite palette (even though at least two, and possibly more, of those indexes will be the same). Since it writes image before sprite, there's no need to worry about the mirroring.

What's this all mean? Well, the most important conclusion to draw is that this is not the procedure we want, nor the loop we want. If this procedure is loading the palette indexes from RAM, they've already been taken from ROM beforehand. We want the procedure that executed beforehand, loading the indexes from ROM and sticking them into $0600 and the addresses directly following.

So, how do we track that one down? If new breakpoint came to mind, good job.

For the next step, I set a write CPU breakpoint on the address $0600. We want to know where $0600 is being written; where are these values stored in $0600 and beyond coming from?

Since this new information essentially makes us look for something completely new, I went ahead and exited the debugger, closed the game, and restarted from RESET.

After getting back to the select screen, picking Drill Man, and then setting the $0600 CPU write breakpoint just before the bars-of-color palette animation is finished, the debugger stops on a new procedure.

The relevant part of it looks like this:


$C462: A0 1F LDY #$1F
$C464: B9 20 06 LDA $0620,Y @ $0620 = #$0F
$C467: 99 00 06 STA $0600,Y @ $0600 = #$0F
$C46A: 88 DEY
$C46B: 10 F7 BPL $C464


A short look at this tells us that the values being stored at $0600 [CPU] (and therefore being used to write $3F00 [PPU]) are being taken directly from $0620. The accumulator loads the value from $0620 and then immediately dumps it into place #$20 bytes earlier.

Seems like a wild goose chase, huh? Where will it end? Even I don't know (though by the time this is posted, I will .

New breakpoint. Catch writes on CPU $0620, and let's take it from the top.

We need to continue to be careful with our breakpoints. We know that the game is using completely different palette indexes for doing its animations, including the one just before the stage is drawn. We might catch the wrong procedure if we set the breakpoint too early.

A recommendation: Have the debugger window open beforehand. Play to right where you want to be (in this case, just before the stage is actually drawn and just before the fadeout finishes). As activity continues in the background, you can hit 'Step Into' with the right timing to nail the precise position. This will freeze the gameplay and allow you to set the breakpoint with much higher accuracy. Once the breakpoint is in place, go ahead and hit run to execute all the way to where the breakpoint fires.

Whee, yet another new procedure. After using our arrows to look up at the section of the procedure which already executed, the majority of the procedure comes into view:


$C611: AA TAX
$C612: A0 00 LDY #$00
$C614: BD 90 B5 LDA $B590,X @ $B590 = #$0F
$C617: 99 20 06 STA $0620,Y @ $0620 = #$0F
$C61A: C0 04 CPY #$04
$C61C: B0 0E BCS $C62C
$C61E: BD A0 B5 LDA $B5A0,X @ $B5A0 = #$00
$C621: 99 F0 06 STA $06F0,Y @ $06F0 = #$00
$C624: A9 00 LDA #$00
$C626: 99 F4 06 STA $06F4,Y @ $06F4 = #$00
$C629: 99 F8 06 STA $06F8,Y @ $06F8 = #$00
$C62C: C0 08 CPY #$08
$C62E: B0 06 BCS $C636
$C630: B9 53 C8 LDA $C853,Y @ $C853 = #$0F
$C633: 99 30 06 STA $0630,Y @ $0630 = #$0F
$C636: E8 INX
$C637: C8 INY


In short, $B590 is where the values at $0620, and therefore $0600 and $3F00 [PPU] are coming from for the stage. $BF90 [CPU] is not a RAM address, register, or reserved/expansion space. Judging by our CPU memory map, we know this is a ROM address. It's quite far into the first loaded PRG ROM bank.

What's with all the other stuff? Well, Megaman 4 apparently creates the logical separation of image and sprite palettes in the ROM. Therefore, it has to load them from two separate addresses as well. Not only that, but it divides the sprite palettes into two eight-byte chunks (grand total: three addresses). It's starting to get too complicated for the scope of this tutorial. Therefore, I think it's best if I just list my findings: the ROM addresses of where the palette indexes used on Drill Man's stage are originally loaded from.

$455A0 - all 16 bytes of the image indexes for Drill Man's stage
$7C863 - the first eight bytes of the sprite indexes
$51932 - the last eight bytes of the sprite indexes

For those interested in the full explanation of how I got these, though:

I traced the code as I demonstrated until I finally came to a dead end where the data is directly loaded from ROM and saved temporarily into the appropriate $06xx RAM location, like the one you see in the procedure. Then I used FCEU's "Seek To" function to go to the memory position where the indexes were loaded. (After all, the data has to be in the memory map currently if it's being loaded by the CPU.) This location is in one of possibly many PRG banks in the ROM. To find out which one, I copied out a good long string of bytes [24 seemed to work well enough], and then searched for that same string in the ROM. I had to do this three times to get all three addresses; and I varied the breakpoint a bit each time. For the first address, I was watching writes to $0620; for the second, $0630-$0637; for the third; $0638-$063F.

Note that this seemingly-enormous debugging method was necessary in order to get completely unique addresses. We could have just used the PPU Viewer to write down the indexes from Drill Man's stage. However, if we searched all 32 indexes at once, we would have gotten 0 results (due to the segmentation of the storage). If we had searched just the image indexes, 2 results would have come up. But then trial and error modification would be necessary to find which one belongs to Drill Man's stage. And we wouldn't know where the sprite indexes had been loaded from, either.

In games where the same palette indexes are stored in the ROM many times, using the debugger ends up being much faster than individually doing trial and error on every last instance.

Also, keep in mind that Megaman 4 is a relatively sane game. Some games could store their palette indexes in the ROM as unknown formats -- using compression is highly unlikely but not impossible. Then the only way to track down the data would be to trace to the procedure that translates the ROM data into the actual indexes. Using the PPU Viewer could not work because you wouldn't have any idea of what the format was ahead of time (unless you already had done thorough tracing/debugging on the game).

A little bit more info on those ROM addresses, and some screenshots follows.

The image palette indexes seem to be used entirely for the stage/level itself. More significantly, they're independent of other stages. Which means by changing Drill Man's indexes, you don't affect Dive, Toad, etc. Good news there.



The second address, is common and applies to all stages. The second offset partly (entirely?) controls megaman's face, body, and energy bar colors. Some of these colors are also used for enemies, I believe (but only some enemies). If you change megaman's body color, it will only hold for as long as you don't charge his shot. The routine that does the funny glow for the charge shot will overwrite your changes.





The third offset is, fortunately, stage-specific like the first. It controls colors used for some (I believe most) enemies.



-- END --

Have fun


(edited by Kagerato on 08-11-04 03:24 PM)
Kagerato

Goomba
Level: 9

Posts: 11/25
EXP: 2655
For next: 507

Since: 08-08-04

Since last post: 382 days
Last activity: 29 days
Posted on 08-13-04 03:38 AM, in Megaman 4 Hack Released! Link
-- introduction --

After working with the broader view for a while, I decided to go ahead and track down the exact problem for the fade-in animation on Drill Man's stage.

Using the PPU Viewer and playing through the stage, it became obvious that only three of the sixteen image indexes were being changed for the animation. I noted their position and then, using my earlier findings, equated them to the RAM addresses $0629, $062A, and $062B.

After setting a write CPU breakpoint on this range, I quickly found the procedure that does the animation. The animation is gradual in four steps. Each time a different set of indexes is written to the PPU's palette indexes.

-- first change --
$0629-$062B are written with the bytes from $B94E-$B950 [CPU memory].

This data is at $B94E and the subsequent addresses during the time the first set of writes occur:

#$07, #$0F, #$0F, #$29, #$21, #$25, #$30, #$32, #$0F, #$39, #$25, #$21, #$16, #$07, #$0F, #$26

This first sequence of bytes is located only at $4195E in the ROM.

-- second change --
$0629-$062B are written with the bytes from $B95A-$B95C [CPU memory].

This data is at $B95A and the subsequent addresses during the time the second set of writes occur:

#$16, #$07, #$0F, #$26, #$16, #$06, #$37, #$26, #$16, #$11, #$01, #$17, #$11, #$01, #$18

This second sequence of bytes is located only at $4196A in the ROM.

-- third change --
$0629-$062B are written with the bytes from $B95D-$B95F [CPU memory].

This data is at $B95D and the subsequent addresses during the time the third set of writes occur:

#$26, #$16, #$06, #$37, #$26, #$16, #$11, #$01, #$17, #$11, #$01, #$18, #$11, #$01, #$27

This third sequence of bytes is located only at $4196D in the ROM.

-- fourth change --
$0629-$062B are written with the bytes from $B960-$B962 [CPU memory].

This data is at $B960 and the subsequent addresses during the time fourth set of writes occur:

#$37, #$26, #$16, #$11, #$01, #$17, #$11, #$01, #$18, #$11, #$01, #$27, #$11, #$01, #$28

This sequence of bytes is located only at $41970 in the ROM.

-- conclusion --

To correct the fade-in animation for the rock faces in Drill Man's stage, these ROM addresses must be given new values (palette indexes):

$4195E-$41960
$4196A-$4196C
$4196D-$4196F
$41970-$41972

The first range is the only odd one. The last three all follow directly after one another.

Choose your indexes using an image which displays the NES palette as a table of indexes, such as the one on TFG's page. (http://tfg.panicus.org/files/docs/nes_pal_fast.html)
Kagerato

Goomba
Level: 9

Posts: 12/25
EXP: 2655
For next: 507

Since: 08-08-04

Since last post: 382 days
Last activity: 29 days
Posted on 08-15-04 03:38 PM, in Megaman 4 Hack Released! Link
It's exactly the same theory. That's why I went through the whole process with Megaman 4; to demonstrate how it's possible to debug using very little information and get precisely what is needed out of it.

Recall that all I knew when I began with the fourth game is where PPU RAM holds the palette indexes ($3F00 - $3F1F). I placed a PPU breakpoint on the first index and started from there. That lead me back through the code, following writes to the RAM addresses I saw until I stumbled upon the initial load instructions from the ROM.

I've already explained in great detail the physical method, and now the theory as well (which is fortunately much shorter). You'll have to clarify if you want something else.

As for 'freezing' the emulator, you're not being specific enough. Breakpoints are supposed to freeze the emulator; that's their exact purpose. A breakpoint stops execution of code based on one or more factors. In FCEUd, the factor is generally that a CPU or PPU address has been read or written (or is about to be read or written).

If you set a breakpoint while the game is running and that breakpoint is about to fire, or is continously firing, according to what the game is doing, then it will stop execution immediately. That is to be expected -- breakpoints are tools, they're not perfect. It's up to the programmer to use them effectively. You've got to use new methods to out-think the problem.

For example, various palette animations you see on stages are caused by writing new palette indexes to particular sets of colors in the image palette. The palette indexes can only be correctly (properly) written during VBLANK -- the time between the electron gun completing a frame and beginning to draw the next (it has to reset from the bottom scanline to the top scanline, which takes relatively much longer than HBLANK). Otherwise, much garbage would be drawn to the screen.

If the animations are continuous (and therefore never-ending), the palette index writing procedure is firing on every VBLANK that occurs while the stage (and/or appropriate screens) are loaded. VBLANK is a non-maskable interrupt (you cannot disable it; it always interrupts the running program code under any circumstances) and it also happens sixty times per second on an NTSC NES (60 full frames need to be drawn for every second).

Now let's complicate the situation. Say that we really couldn't give a **** about that flashy palette animation. What we want to know is when and how some enemies are given new colors (or, perhaps, new enemies appear and have different colors) during the stage's lifetime. There are two ways to solve the problem.

One, we change our breakpoint to better match the scenario. $3F00 is the first image index; the range $3F00 to $3F0F represents the set of indexes which may potentially be written by our flashy palette animation that's always happening. $3F10 to $3F1F , on the other hand, represents the potential range for changing sprite colors. By shifting the breakpoint's range, we may be able to avoid the constant palette animation entirely.

Unfortunately, there is some more complexity to the matter. Remember the palette mirroring? When the image indexes are written, the corresponding sprite indexes are going to adopt their colors. In order to get everything correct before VBLANK is finished, the palette animation's procedure is very likely going to write all the sprite indexes with their proper values as well. It makes for cleaner code and much less likelihood of error (after all, they shall not be written outside of VBLANK -- that's heresy).

So, does changing the breakpoint really help? It might help slightly, especially if the sprite indexes are written in a separate procedure running inside VBLANK. But all you will be able to find out from that procedure is the RAM address which they are copied over from -- it's not going to load them straight from the ROM (imagine how many ROM reads per second that would be, ugh). From there, it is possible to continue tracing by using the newfound RAM address.

There is a second method, as I mentioned earlier. It simplifies things a good deal by taking the irrelevant information out of the picture. You can probably guess what it is: use another stage, one that doesn't have any flashy palette animations. This will very likely eliminate your massive number of palette index writes, and sometimes eliminate them entirely (if there's nothing; no enemies, no megaman effects, no background nothing on screen to be palette animated). By vastly reducing the number of writes, the necessary precision becomes much reduced and you generally end up weeding through less code.

Well, I can only hope that will infuse a bit of different, new thinking. For your sake and mine, please make all further questions as specific as possible. It helps a lot to tell exactly what you've tried, the steps you've taken, et cetera as well.
Kagerato

Goomba
Level: 9

Posts: 13/25
EXP: 2655
For next: 507

Since: 08-08-04

Since last post: 382 days
Last activity: 29 days
Posted on 08-15-04 11:33 PM, in Megaman 4 Hack Released! Link
visine is a rather powerful editor. Not too suprising that it already has the internal palette addresses, and the ability to modify them.

Come to think of it, you sure MegaFLE doesn't have a similar feature?

In any case, I hope all those posts I wrote don't go entirely to waste.
Kagerato

Goomba
Level: 9

Posts: 14/25
EXP: 2655
For next: 507

Since: 08-08-04

Since last post: 382 days
Last activity: 29 days
Posted on 08-17-04 05:01 AM, in Megaman 4 Hack Released! Link
Your situation gives some good insight into how I feel a good deal of the time, Schwa.

Always do what you think is best. If your thinking proved to be flawed, at least you will have learned something.

If you like Megaman III and have enthusiasm for the game, that's what you should work with. You may find later on that your feelings become muddled; that's the way our minds work. Try to reconcile what you feel you should do with what you logically reason you should do. A very difficult task, in any case.
Kagerato

Goomba
Level: 9

Posts: 15/25
EXP: 2655
For next: 507

Since: 08-08-04

Since last post: 382 days
Last activity: 29 days
Posted on 08-20-04 02:27 AM, in Update to Metroid Zero Mission(includes level data format) Link
I'm really, really tired of your worthless feature requests for any and all romhacking tools. Likewise with data.

If you want it, do the work yourself!

It's as if you think you gain something (or even worse, that you help someone) by making a moronic suggestion everytime someone posts their findings or accomplishments. You discredit everyone else by acting like they can't figure out what is left to be done.
Kagerato

Goomba
Level: 9

Posts: 16/25
EXP: 2655
For next: 507

Since: 08-08-04

Since last post: 382 days
Last activity: 29 days
Posted on 09-02-04 04:14 PM, in Question about working with Super metroid sprites Link
The SNES, unlike the NES, does not have a fixed palette.

Comparison:

NES : Fixed 64-color palette. Some colors are identical, and quite a few are also unused. The PPU has a section of its RAM devoted to selecting 32 of the 64 colors. That area can be split into 16 image palette indexes and 16 sprite indexes. The data there is simply references to the overall palette.

The only way to change the NES palette is to cheat, essentially. Certain NES emulators are capable of loading modified palettes (generally *.pal files) and using their data in place of the internal, NES-accurate palette.

SNES : Variable 256 color palette. Each color is represented by 15 bits in a BGR (yes, it's backwards) format. The colors are packed inside a 16-bit value (a standard SNES word) with the most significant bit left off/zero and then are stored inside CGRAM [a section of the PPU's RAM].

Most of the time, the latter 128 colors are used for sprites and the former 128 colors are used for background and foreground tiles making up the levels, overlays, et cetera. However, the SNES has different display modes which can provide tiles (not sprites) with access to all 256 colors (if the programmer should so choose to use such a mode).

SNES sprites and tiles are often stored in a 4 bpp (bit per pixel) format. The maximum number of colors, therefore, used per tile is often 16. It can be less, but super metroid uses 4 bpp for the majority of the graphics where such a bit depth is useful.

The ugly-ass rainbow samus you have devised is fairly feasible, but would require a good deal of toying around with both samus' tile definitions and the section of the sprite palette used for samus.
Kagerato

Goomba
Level: 9

Posts: 17/25
EXP: 2655
For next: 507

Since: 08-08-04

Since last post: 382 days
Last activity: 29 days
Posted on 09-03-04 11:23 PM, in Question about working with Super metroid sprites Link
It's an extremely poor idea to insult people who are even attempting to help you.

My opinion of your work is irrelevant. I can state it or not state it, and it should have no effect on anything else you do. If it does, you need to reconsider what you're doing.

People who interpret hard feelings towards their creations as harsh feelings towards themselves are shallow and limited. It is entirely possible to hate someone's creation and be indifferent towards the person.

Additionally, I neither implied nor stated that you were an expert in color choice or sprite creation. If I implied anything, it would have to be quite the opposite.

Neither did I state or imply that I had a better set of colors available, even though it would not take me long to procure such a palette. Whether I do, unfortunately, is still entirely irrelevant. Criticism does not require the critic to provide better work in place of the criticized piece. There is never a need or justification for that when numerous examples of superior work exist.

When you quote someone, please do it correctly. Otherwise they are forced to figure out where your post begins and where it ends.

Samus' sprites are entirely uncompressed in the ROM. Any and all tile editors (there are plenty) which modify 4 bpp are capable of changing the indexes which determine the colors selected for samus. As mentioned, the 4 bpp format has the limitation of 16 colors. The whole sprite, split into numerous pieces, is stored in the format. Therefore the sprite uses only 16 colors as a whole.

Editing the sprite palette is preferable. I am not aware of the location of the sprite palettes. If they're used in similar form to the background/foreground tile palettes, they will be compressed. The compression used can be reversed using Lunar Compress. Likewise, the same library will be needed for compressing the data before returning it to the ROM (if indeed the sprite palettes are compressed).

Beware. If any of samus' colors are used for other sprites, they will be equally affected by any change.
Kagerato

Goomba
Level: 9

Posts: 18/25
EXP: 2655
For next: 507

Since: 08-08-04

Since last post: 382 days
Last activity: 29 days
Posted on 09-05-04 04:50 PM, in ...Ive got a cunning idea about the GBA Link
PocketNES doesn't seem to be released under any sort of restrictive license (i.e. cannot be used for commercial enterprise, or such garbage).

Regardless of what license the emulator is or is not released under, it's legal if Nintendo acquired permission from the author. And who would turn down such a request?
Kagerato

Goomba
Level: 9

Posts: 19/25
EXP: 2655
For next: 507

Since: 08-08-04

Since last post: 382 days
Last activity: 29 days
Posted on 09-06-04 06:42 PM, in ...Ive got a cunning idea about the GBA Link
Yeah, that seems accurate, jonwil.


Excerpt from GPL:


2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:

b.) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License.




and also...


Excerpt from GPL:


These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.


Kagerato

Goomba
Level: 9

Posts: 20/25
EXP: 2655
For next: 507

Since: 08-08-04

Since last post: 382 days
Last activity: 29 days
Posted on 09-06-04 07:22 PM, in .NET or not to dot net? Link
There are two advantages to utilizing a runtime instead of standalone executables: smaller executable size and the possibility of portability. Whether Microsoft will support the .NET runtime as it becomes (widely) available on other platforms is yet to be seen; my guess is no.

The obvious disadvantage to runtimes is that they're a large download. .NET is about 22.5 mbyte. The Windows GTK binaries compact into 6.7 mbyte; when you decompress them, they occupy about the same space.

Personally I believe it was a mistake to jump into .NET so soon, before the major platform (XP) provided the runtime natively. However, Longhorn and future versions of Windows will definitely have .NET available, integrated with the system (simply because a lot of the code on the next-generation operating systems will be for the .NET platform).

I'm not sure how many people have noticed, but Borland (developer of a lot of high quality programming tools for numerous languages and environments) is moving to .NET as well. Delphi 8 is for .NET, and the company has also introduced a C#Builder for the platform.

At first, all this jumping to a foreign new environment scared and infuriated me. However, I've now accepted it as just another stage of development.

Interpreted languages (or rather, languages which require an interpreter of some kind), and platforms dependent on a central runtime, are slowly but surely beginning to dominate the programming sector. Java was/is the popular pioneer. But there is also Python and Perl. The Internet has rejected traditional languages, and is now almost consumed with numerous implementations of never-compiled scripts.

If you don't like this course, I suggest moving over to a unix-like system. Several Linux/GNU distributions I've tried are still heavily tied down in compiled languages (99.9% C/C++), and there are no signs of that changing in the near future.
Pages: 1 2
Acmlm's Board - I2 Archive - - Posts by Kagerato


ABII


AcmlmBoard vl.ol (11-01-05)
© 2000-2005 Acmlm, Emuz, et al



Page rendered in 0.038 seconds.