Dienstag, 3. Juli 2018

Bug fixes


Hey there, since some of you (rightly) claimed that there are some bugs / faulty maps in the latest version, I think I will do some bug fixes to make release 0.5 more stable before I move on to new features (event editor).

I will concentrate my bug fixes on the following topics:
  • Map editor
  • Display of maps/sprites
  • Open/Close project
Additional wishes/suggestions for futher bug fixes are always welcome ;)

 I already fixed the display of some maps after the map table gets written.
As an example, the world map is displayed correctly now and can be fully edited:



28 Kommentare:

  1. "MANAFREAKS CASTLE"

    Very cool! =D

    AntwortenLöschen
  2. Also, if you (or any of your lovely readers) want me to investigate some other part of the code, I'll gladly do so. Currently working on the special attacks -- though recently I've been delayed considerably by the work load at my real job.

    AntwortenLöschen
    Antworten
    1. A neat little idea would be if we somehow could edit the movement on the map (especially since the rotation is slooooow sometimes and could use some tweaking).
      But, I think, this is something you should talk with manafreak if he plans to actually implement something like this in the near future (because implementing in a user friendly visualization would take a looot of work/trial and error). And I know from my own experience that everything that has to do with Mode 7 is very annoying to dig through.

      In other news: I hope that I find the time to play around again with the editor to find some more bugs for this current bug collecting spree, but you should better not wait for me, I'm terribly busy, currently.

      Löschen
    2. Anything to do with graphics/rendering already frightens me. Mode 7 sounds like a whole new level of horror on top of that. It's a minor miracle I was able to find the Dark Friar animation's palette table without my brain exploding from confusion and frustration. :)

      Löschen
    3. Movement on the map is controlled by 4-byte tuples, with one set of tuples for each possible origin and destination. Tuples are read sequentially as "steps" along the trajectory, and the trajectory stops (you have reached your destination) when a tuple is followed by an FF byte (or FE, for some reason). The bytes encode the map's (1) west/east move speed, (2) north/south move speed, (3) clockwise/counterclockwise rotation speed, and (4) duration of the current movement step.

      The map has an "internal" west/north coordinate system, which rotates with the map itself. If you, say, move the map east for 120 frames, the camera will end up at the same new position no matter what "angle" the map was set at before. In other words, you could take all of the rotation steps out of every map script in the game, and Will would still correctly find his way to every destination -- but he would be walking sideways a lot of the time...

      What do I mean by that? Well, Will always looks at the top of the screen, no matter what the map is doing. Apparently the purpose of the rotations is to turn the map so that it looks like Will is walking forward, or in other words, to have the map always moving toward the camera. If you want it to look like Will is walking northeast on the map, you have to (1) rotate the map 45 degrees counterclockwise, so that "northeast" on the map is at the top of the screen; then (2) displace the map west and south, with the same speed in both directions. If you omit step (1), Will still appears to move northeast on the map, but from the player's perspective he's moving diagonally.

      Quiz time! On the path from Natives' Village to An(g)kor Wat, Will, originally facing north, turns to his right by 22.5 degrees. He then "walks forward" a short distance. To make it look like he's walking forward, what must be the ratio of the map's speeds in its west and south directions? Answer: tangent(22.5 degrees) = 0.41, but the game uses 0.5 instead. Close enough!

      So, to address your original concern, it's actually pretty easy to make Will rotate faster on the map -- you just have to increase the "rotation speed" byte in the map movement scripts, and decrease the "duration" byte proportionally.

      Here's a presumptuous suggestion for how map adjustments could be implemented in a user-friendly way. The "waypoints" in each path could be shown on the world map in the editor, and could be dragged around to change Will's path. There are a total of 10 possible speeds. If I have the coordinates of two waypoints and a desired speed for moving between them, that gives me bytes #1 (x-speed), #2 (y-speed), and #4 (time = distance / speed). Byte #3 would usually be 0, since we usually don't want to rotate while Will is in motion (though for some reason it is possible to do so...).

      For "pure rotational" waypoints (A-->B, rotate at B, B-->C), you can also auto-determine the rotation time required. There are 10 rotational speeds, and the total angle that you need to sweep is angle ABC, so time = sweepangle / speed. Of course it would be nice if we could override the automatic suggestion, too.

      I'll probably start my own blog and write a fuller description later, so as to cease spamming manafreak's comments with my essays. I'm just happy to help -- this is probably the closest I'll ever come to fulfilling my childhood dream of actually making a video game. :)

      Löschen
    4. Wow, this sounds amazing! Thank you very much for the investigation. Can you tell me where I can find the corresponding data set in the ROM?
      This would be a nice feature to add to the next feature release ;)

      Löschen
    5. The data set for map movement is around $03b080, but the tuples don't seem to be in any particular order. $03b080 for instance describes the movement from Natives' Village to Euro.

      There's a related table around $03b950 containing several 16-byte tuples, that begin with "02 67 00". There is one tuple for each origin-destination pair, and these tuples include the index of the map-movement-script (byte 4), the index of the destination room (byte 7), the x- and y- coordinates of Will's spawn point in the destination room (bytes 8-11), and some more information I haven't deciphered yet. This data also appears to be in no particular order.

      What I'm working on right now is finding out which entries in the two tables correspond to which origin-destination pairs.

      Löschen
    6. Whoa, you actually did it! Big thanks! *_*
      Can't wait for that next version, and can't wait for the bugfix!

      Löschen
  3. BTW, since it is about half a year since the last release - do you have some estimated date when you plan to publicly release the next version?

    AntwortenLöschen
  4. I think the bug fix for version 0.5 shouldn' take too long, August is quite possible ;)
    The next feature release could happen in the autumn/early winter.

    AntwortenLöschen
  5. So, update: I've learned enough about overworld map movement that I think you can make some interesting additions to later versions of GtC, if you wanted to.

    Some of what I've found is indexed by GtC already, but without any editable properties, most notably under the World Map tab. I wish I knew where that data came from -- it might have saved a bit of time!

    Anyway, the map processing code is extensive, with (by my count) at least four layers of pointers involved in getting Will onto the world map at all. I'm making a write-up right now, which I will post here as soon as it's presentable. You cool cats, unfortunately, won't get to see the visual aids that I'm making for myself, because I can't post images in these comments. Oh well. :)

    AntwortenLöschen
  6. Has anyone considered an Illusion of Gaia development wiki? Lytron, is that something you'd be interested in contributing to?

    AntwortenLöschen
  7. Well, currently I refrain from such commitments, because I hate that I don't pull stuff through. But, I think I could offer some help whenever real life allows it.

    I propose that we don't re-invent the wheel, but could use the wiki from romhacking.net. It's free of charge, it's free of ads and it already has some rudimentary info about IoG:

    http://datacrystal.romhacking.net/wiki/Illusion_of_Gaia:ROM_map

    I bet there would be no problem if we put some big chunks of commented code online, like I did with my "baby", Tactics Ogre:

    http://datacrystal.romhacking.net/wiki/Tactics_Ogre:ROM_map#Bank_.2480

    If someone of you wants to, you could start and put a chunk of (currently relevant) code online there and I'll join in editing/commenting. But we should make sure that we use the same ROM. Either Japanese 1.0 or US 1.0. What do you think, guys?

    AntwortenLöschen
    Antworten
    1. I can't read Japanese, which is why I use the US ROM and obviously favor that one :) but if the prevailing opinion is that the Japanese ROM is better for hacking, I'm sure I can adapt. I think the differences are mostly cosmetic, the most important exceptions, afaik, being Castoth's head and the Mummy Queen's vulnerability to the Earthquaker.

      I didn't know romhacking.net had a wiki! I love what you've done with the Tactics Ogre page. I'll try to do something similar to the Gaia page.

      Löschen
    2. I actually don't care which one we take it, we just should agree on one beforehand, so we don't get problems later. The differencies could also be different offsets (like, the first subroutine on one bank has one byte more because of a minor bugfix, and so all addresses there are off by one byte).

      If we ever get really far in this wiki stuff, we can point out the differencies between the ROMs, especially regarding bugfixes or so. Something than is more than just a different address table because of different text lengths.

      BTW Another difference is that you can hit the first boss's head directly and don't have to beat his hands first. So the first boss fight in the Japanese version has a length of about 3.7 seconds.

      Löschen
    3. If you don't care, then I suggest the US, but perhaps manafreak should weigh in too, since he's our other resident expert. If he agrees, then I will start editing in what I know once I have an extended block of time in which to do so.

      I assumed that the differences would mostly be offsets, except in the handful of cases where the two games actually do different things. The first boss's head, btw, is what I was referring to in my post. Supposedly its name is Castoth.

      Löschen
  8. Part 1 - Movement on the map screen.

    Once an origin and a destination are set on the world map, a script is called that moves Will around. I talked about these scripts up there ^^^, but left out some details that I didn't know yet.

    There are 37 scripts, indexed #$01 to #$25. In the US ROM their addresses are at $03ad77 + 2 * index, and the high byte is always $03. So the first movescript, #$01, is found at $03adc3:

    00020030 00000240 01020030 00000140 00020010 ff

    This is used to move Will from Cape to Edward's. The 37 movescript indexes, addresses, and intended uses are:

    01 - adc3 - Cape-Edwards
    02 - add8 - Edwards-Cape
    03 - adf1 - Cape-Itory
    04 - ae06 - Itory-Cape
    05 - ae23 - Itory-Moon
    06 - ae38 - Moon-Larai
    07 - ae5d - Itory-Inca
    08 - ae76 - Inca-Itory
    09 - ae9b - Coast-Freejia
    0a - aea0 - Freejia-Mine
    0b - aebd - Mine-Freejia
    0c - aeda - Freejia-Neil's
    0d - aeeb - Neil's-Nazca
    0e - af10 - Unused; Nazca-Freejia?
    0f - af2d - Unused; Freejia-Nazca?
    10 - af42 - Unused; Nazca-Mine?
    11 - af5f - Angel-Watermia
    12 - af9c - Watermia-Angel
    13 - afbd - Watermia-Wall
    14 - afce - Wall-Watermia
    15 - afeb - Watermia-Euro
    16 - b00c - Euro-Watermia
    17 - b02d - Euro-Kress
    18 - b046 - Kress-Euro
    19 - b063 - Euro-Natives'
    1a - b080 - Natives'-Euro
    1b - b09d - Natives'-Ankor
    1c - b0ae - Ankor-Natives'
    1d - b0c7 - Natives'-Dao
    1e - b0e0 - Dao-Pyramid
    1f - b0f5 - Pyramid-Dao
    20 - b10e - Dao-Natives'
    21 - b12f - Dao-Babel
    22 - b154 - Unused; Mu-Inca?
    23 - b17d - Unused; Inca-Mu?
    24 - b19e - Unused; Euro-Freejia?
    25 - b1bf - Unused; Freejia-Euro?

    Silly aside: I'm more than a little curious about the seven perfectly functional unused movescripts. It's impossible to know where they were supposed to start or even if they were ever more than placeholders, but it IS possible to make some inferences.

    #$0e, #$0f, and #$10 are easy to speculate about. They happen to appear right after the scripts involving Freejia, and before Angel Village. By altering Will's origin on the map, one can see where these scripts would go from different origins. #$0f draws a perfect path from Freejia to Nazca, and #$0e draws the reverse, Nazca to Freejia. #$10 looks like a path from Nazca to the Mine. These scripts could imply that Nazca was meant to be a larger part of the adventure rather than a one-stop plot hop.

    #$22 through #$25 are more enigmatic. #$23 is the reverse of #$22, and #$25 is the reverse of #$24, so I don't think they're random junk or placeholders. #$22 and #$23 are huge paths that cover over a quarter of the map southwest/northeast, meaning they have to connect a place in the northeast quadrant (Watermia or Mu?) with one in the southwest (South Cape or Inca?). #$24 and #$25 also span a full quadrant, in a south-southeast/north-northwest path, and the distance is about right for this path to connect Euro to Freejia. These are the last scripts, coming after the ones involving the Tower of Babel. It may be that these huge late-game scripts were meant to let you re-visit the first two continents.

    Anyway...

    The first two bytes of each 4-tuple in the movescript control west/east and north/south speed. There are ten possible speeds. Odd values are west or north movement of the map, even values are east or south movement.

    00 - no movement this direction
    01/02 - base speed (1x)
    03/04 - 2x
    05/06 - 3x
    07/08 - 4x
    09/0a - 5x
    0b/0c - 6x
    0d/0e - 7x
    0f/10 - 8x
    11/12 - 0.5x
    13/14 - 0.25x

    The fourth byte of each 4-tuple is the duration of the step. A speed of 1x for a duration of #$80 covers the distance between Diamond Coast and Freejia.

    Rotation is controlled by the third byte, which is odd for clockwise rotation of the map, even for counterclockwise rotation. There are ten possible speeds, numbered exactly like the displacement speeds: 01/02 for the base speed 1x, and so on. 1x speed for a duration of #$80 carves an angle of 90 degrees.

    It's possible to have Will turning and moving at the same time, but this is probably pointless. (Maybe you could use it to simulate a spiraling plane?)

    AntwortenLöschen
    Antworten
    1. Part 2a - Event-driven map movement

      There are 12 places where the plot takes you to the map screen. manafreak, I don't know anything about events yet, but I assume these are room-based events, since they appear in the ROM next to some other room-specific code that looks like events. Feel free to correct my ignorance.

      The way this works is that every room in which a map transition can be triggered is hard-coded with information about that transition. Since these transitions are room-specific and hard-coded, there's no indexing, and the addresses of their data follow no pattern. With that in mind, here they are:

      04cfb2 - Edward's to Cape
      04a707 - Cape to Itory
      04e5cb - Itory to Moon Tribe
      04f515 - Moon Tribe to Larai
      05aab6 - Coast to Freejia
      05cb5a - Freejia to Neil's
      05e1aa - Neil's to Nazca
      06c090 - Angel's to Watermia
      07a1e6 - Watermia to Euro
      07d9cf - Euro to Natives
      08959e - Natives' to Dao
      08a5fe - Dao to Babel

      The format of the code is at least somewhat standardized. Looking at the specific case of Will's escape from Edward's castle ($04cfb2):

      a9 00 00 8d 60 0d a9 01 00 8d 62 0d a9 02 04 8d 4a 06 02 65 04 01 34 03 00 02 02 26 06 58 00 c0 01 00 10 21 02 c1 6b

      It's a whirlwind of mixed instructions and data, easier to understand if it's annotated:

      a9 00 00 8d 60 0d a9 01 00 8d 62 0d a9 02 04 8d 4a 06 - "lda #$0000; sta $0d60; lda #$0001; sta $0d62; lda #$0402; sta $064a"
      02 65 - "cop #$65"
      04 01 34 03 00 02 - data 1
      02 26 - "cop #$26"
      06 58 00 c0 01 00 10 21 - data 2
      02 c1 6b - "cop #$c1; rtl"

      The lda/sta bundle is free-form, and essentially optional. It loads character sprite indexes into RAM. The format is one to six instances of "lda #$00jj; sta $0d6k", where "jj" is the index of a sprite (see below), and "k" is 0 for the first character, 2 the second, 4 the third, 6 the fourth, 8 the fifth, and A the sixth. The escape from Edward's has Will in the first slot and Kara in the second, hence "lda #$0000; sta $0d60; lda #$0001; sta $0d62".

      The possible characters on the world map are:

      00 - Will, first slot only;
      01 - Kara
      02 - Lilly
      03 - Lance
      04 - Erik
      05 - Neil
      06 - Hamlet
      07 - Will on kruk
      08 - Erik on kruk
      09 - Neil on kruk
      0a - Kara on kruk
      0b - Neil's plane
      0c - Neil's plane laden with passengers
      0d - Will carried aloft by birds (yes, really)

      #$0d is never used in the base game, nor is Will really known for his association with animals. It would be much more at home in Terranigma, where the protagonist actually is carried by birds a few times.

      Index 00 is only valid in $0d60. 00 in any other slot stops the processing. This means Will can only walk in the first slot, but it also means you can't fill the slots out of order. Two characters have to occupy slots $0d60 and $0d62. A third character has to go in $0d64, and so on. The game intelligently arranges the sprites based on how many there are.

      The first slot is occupied by Will 10 times, by Will-on-kruk (#$07) once, and by Neil's plane (#$0b) once.

      Finally, there is "lda #$0402; sta $064a". The two bytes #$02 and #$04 are the screen fade-out and fade-in times. A value of #$00 is not instantaneous, just very fast.

      Löschen
    2. Part 2b - Because I am incapable of writing tersely about event-driven map movement.

      The "data 1" group is always six bytes that describe where Will and/or his companions should appear on the world map. The first two bytes give his x-offset, the next two his y-offset, with respect to the northwest corner of the map. The Tower of Babel is the "center" of the map, situated at #$0200 by #$0200. Edward's Castle is a bit southwest of there, at #$0104 by #$0334.

      The fifth byte is, as far as I can tell, unused. It's copied into RAM, specifically to $0d5e, but from there neither the data nor its copy in RAM are read from again.

      The sixth byte contains the index of the movescript that Will and/or his companions will follow once. This is one of the 37 indexes from above. The scripted move from Edward's Castle to South Cape uses #$02, which is not-so-coincidentally the same script that's used if you exit Edward's Castle normally and walk to South Cape.

      The "data 2" group is always eight bytes that describe where the player will regain control once the map movement is finished.

      The first byte is the index of the destination room. Destination rooms are thankfully indexed normally, i.e. they're numbered the same here as they are in Gaia the Creator. Will appears in the target room, and any events attached to his usual appearance in that room (such as dialogue boxes) play normally. The destination room during the escape from Edward's Castle is Will's house, index #$06.

      One minor caveat is that not every room is a valid destination. The game crashes if you try to map-travel into a room that doesn't have an overworld name. (Will's house has an overworld name: it's "South Cape".) As best as I can tell, the only reason for the crash is that the game gets into an infinite loop trying to find the name of the room; everything works perfectly if you manually exit this loop. That means it's probably possible to patch out this behavior so that any room can safely be selected as a map movement destination, but I'm not sufficiently interested right now to write the patch for it.

      Anyway, after the room index come four bytes describing Will's spawn point in the room: the first two for x, the second two for y. Will spawns at position #$0058 by #$01c0 in his house for this event. The next byte controls the initial orientation of Will's sprite: setting it to 00 has him facing up, 07 right, 06 left, and 03 down.

      Bytes 7 and 8 restrict the movement of the camera (and Will) in the destination room, preventing them from seeing or using part of the room. You probably already know how this works, since in normal gameplay this effect is widely used inside buildings, in order to prevent the player from seeing the floors above or below the current level. The upper nibble (4 bits) of byte 7 determines the camera's top boundary in the y-direction, the lower nibble its left boundary in the x-direction. Likewise, the upper nibble of byte 8 determines the bottom boundary, the lower nibble its right boundary. All nibbles are multiplied by 16, and the boundary is set to that number of blocks away from the side of the screen.

      Only two overworld destinations in the game restrict the camera's movement, both of them indoors. Apparently everyone in the world uses the same contractor, from the wealthiest of kings to the meekest of paupers, because every indoor floor has a height of 16 (#$10) blocks. With Will's house as a destination, byte 7 is set to #$10, which cuts off the top floor. With Edward's Castle as a destination, byte 7 is set to #$20 to cut off the top two floors, and byte 8 is set to #$34 to cut off the bottom floor.

      I can't tell what the purpose of the "cop #$c1" is -- perhaps it's part of the event. But the "rtl" is the true end of the script movement.

      Since these are hard-coded and attached to rooms, it should be safe to add, delete, or modify as many as you want.

      Löschen
    3. Part 3a - Player-driven map movement

      This happens when you exit a room and are presented with the prompt "Where do you go?". The selectable options depend on plot flags in RAM. I believe, manafreak, that the process of setting and reading these flags is a room event, which you probably know about and which I will have to learn at some point. :)

      Anyway, there are 27 world map dialogues, and which one you get is controlled by the current room ID and the current plot flags. These, I assume, are controlled by an event.

      To get one of the 27 world map dialogues we go through several layers of indirection. The first one is the master script, at addresses:

      Script - From - Destinations are…
      00cae1 - Cape - Edward's
      00caf1 - Cape - Itory
      00cb01 - Cape - Nowhere
      00cb1a - Edward's - Cape
      00cb3f - Itory - Cape
      00cb4f - Itory - Inca + Cape
      00cb68 - Inca - Itory
      00cb87 - Freejia - Nowhere
      00cb97 - Freejia - Mine
      00cbb0 - Mine - Freejia
      00cbcf - Angel - Nowhere
      00cbdf - Angel - Watermia
      00cc04 - Watermia - Angels
      00cc14 - Watermia - Angels + Wall
      00cc24 - Watermia - Angels + Wall + Euro
      00cc62 - Euro - Watermia
      00cc72 - Euro - Watermia + Kress
      00cc82 - Euro - Watermia + Kress + Natives'
      00cc3d - Great Wall - Watermia
      00cc9b - Mt. Temple - Euro
      00ccc0 - Natives - Euro
      00ccd0 - Natives - Euro + Ankor
      00cce0 - Natives - Euro + Ankor + Dao
      00ccf9 - Ankor - Natives'
      00cd18 - Dao - Natives'
      00cd28 - Dao - Natives' + Pyramid
      00cd49 - Pyramid - Dao

      (It's going to be a long night, isn't it.)

      Using the specific example of Watermia, if you haven't read Lance's letter you get code path $00cc04 when you try to exit. This is:

      a9 00 00 8d 60 0d - "lda #$0000; sta $0d60"
      02 66 - "cop #$66"
      d4 02 a4 01 0b - data
      4c c1 ca - "jmp $cac1"

      The lda/sta bytes act just like in plot-driven movement, writing sprite indexes to RAM. One thing that might not be obvious, since this possibility is never used in the base game, is that you can have multiple characters accompany you during normal map movement. You just have to add new "lda/sta" pairs to fill $0d62, $0d64, $0d66, $0d68, and $0d6a.

      In the data section, the first four bytes are the x- and y-position of Will's spawn point on the world map, as usual. The fifth byte is yet another index. This one points into a "map options table" that does the dirty work of presenting us with destinations and text. For Watermia, map options index $0b is going to present us with "Quit" and "Angel Village".

      The "jmp $cac1" is, I believe, the standard way to end these scripts.

      There are 38 map options indexes, but 11 of them are unused and don't do anything (other than take up space), which leaves us with the 27 possible dialogues in the base game. The indexes lead to addresses stored at $03b401 + 2 * index, and the high byte of those addresses is $03. Specifically:

      Option index - Address - From - Destinations are...
      01 - b451 - Cape - Edward's
      02 - b47d - Cape - Itory
      03 - b4a8 - Edward's - Cape
      04 - b4cc - Itory - Cape
      05 - b4f0 - Inca - Itory
      06 - b51a - Itory - Inca + Cape
      07 - b53f - Freejia - Mine
      08 - b563 - Mine - Freejia
      09 - b587 - Freejia - Nowhere
      0a - b5a1 - Angel - Watermia
      0b - b5c7 - Watermia - Angels
      0c - b5f2 - Watermia - Angels + Wall
      0d - b52a - Great Wall - Watermia
      0e - b650 - Watermia - Angels + Wall + Euro
      0f - b697 - Euro - Watermia
      10 - b6bd - Euro - Watermia + Kress
      11 - b6f3 - Mt. Temple - Euro
      12 - b719 - Natives - Euro
      13 - b73f - Natives - Euro + Ankor
      14 - b787 - Ankor - Natives'
      15 - b7a5 - Angel - Nowhere
      16 - b7b5 - Dao - Natives'
      17 - b7e2 - Dao - Natives' + Pyramid
      18 - b81a - Pyramid - Dao
      19 - b843 - Natives - Euro + Ankor + Dao
      1a - b88c - Euro - Watermia + Kress + Natives'
      1b - b8d6 - Cape - Nowhere

      Our exit from Watermia uses map options index #$0b, address $03b5c7. The code is:

      02 bf d9 b5 02 be 02 01 d3 b5 02 c5 d9 b9 d9 b9 e5 b9 c2 11 d2 00 ac 61 a5 88 a4 cb ac 40 8d 86 84 8b ac 66 88 8b 8b 80 86 84 ca

      Löschen
    4. Part 3b - Almost done...

      Split into meaningful chunks, $03b5c7 is:

      02 bf - "cop #$bf"
      d9 b5 - data 1
      02 be - "cop #$be"
      02 01 d3 b5 - data 2
      02 c5 - "cop #$c5"
      d9 b9 d9 b9 e5 b9 - data 3
      c2 11 ... ca - data 4

      "Data 1" must point to the first byte of "data 4".

      In "data 2", the first byte's low nibble sets the number of selectable options in the left half of the text box. If the high nibble is greater, then the difference between the two sets the number of selectable options in the right side of the box. That means that values of 02, 12, and 22 all have the same effect of two options in the left side of the box.

      The second byte sets the vertical position of the cursor inside the text box. This should be set to 01 for normal behavior, but could be changed by an ambitious hack that overhauls the map system. The third and fourth bytes must point to the first byte of "data 3".

      "Data 3" starts with two dead bytes, and following those are two bytes for every selectable destination. These pairs of bytes are--wait for it...--ANOTHER layer of indirection. They're the address of the code that's executed when you select a destination in the list. Leaving Watermia we have two options, "Quit" and "Angel Village", in that order. Data 3 has the first option executing $03b9d9, and the second option executing $03b9e5.

      "Data 4" is the actual text of the text box. The first two bytes, "c2 11", are a shorthand used by the dialogue system that draws the box on the screen and puts the words "Where do you go?" in it. The terminal byte, "ca", ends the text box. Everything in between consists of handwritten, hard-coded text. The text must be hand-justified, and since the cursor is drawn over it by a separate procedure, you do have to remember to put spaces in the spots where the cursor can appear.

      In case it's not obvious from the above, the words that appear in the text box are completely unrelated to the actual destinations.

      When you make a selection, the corresponding address from "data 3" is executed. Selecting the Angel Village destination from Watermia jumps to $03b9e5, which is a 16-byte tuple:

      02 67 - "cop #$67"
      00 12 - data 1
      02 26 - "cop #$26"
      69 a0 02 c0 00 00 00 13 - data 2
      02 c5 - "cop #$c5"

      "Data 2" looks suspiciously like the "data 2" group in plot-driven map movement, because they are, in fact, the same format with the same purpose.

      The first byte of "data 1" is always set to 00, and doesn't seem to serve any purpose. The second byte contains the index of the movement script that Will and/or his companions will follow after your selection is made.

      But wait! There's more. Two more things, actually.

      What about the "Quit" option? Actually, "Quit" is handled mostly like a normal movement. In the case of Watermia, "Quit" goes to $03b9d9:

      02 26 - "cop #$26"
      78 78 02 90 03 00 00 45 - data 2???
      02 c5 - "cop #$c5"

      It's just a normal "destination" script for Watermia. In fact, it's the destination script for Watermia if you're coming from Angel Village. But since we jump in at the "cop #$26" rather than at the preceding "cop #$67", the movescript is never set, so it remains 00. The game treats movescript 00 as an instantaneous teleportation.

      One other thing. Will is supposed to ride a kruk if he wants to go to Euro, but earlier at $00cc04 we did:

      a9 00 00 8d 60 0d

      which sets the overworld sprite as Will's. If Euro is selected as a destination, the destination selection code ($03ba15) includes:

      a9 07 00 8d 60 0d - "lda #$0007; sta $0d60"
      02 67 - "cop #$67"
      [etc...]

      Rather than starting with "cop #$67", we manually rewrite the overworld sprite to be #$07. After that we "cop #$67", and things are back to normal again.

      Simple, right?

      Löschen
    5. Raeven0 -- this is incredible work! I've been working on an IoG randomizer, and I knew that unlocking the code behind overworld movement was going to be pivotal. I'm going to have a lot of fun playing around with this new knowledge!

      Löschen
    6. There's a typo in my "map options index" table description. It's unlikely that this will ever affect anyone, and even less likely that anyone so affected will read this far down, but here's the correction for completeness.

      For
      "0d - b52a - Great Wall - Watermia"
      read instead
      "0d - b62a - Great Wall - Watermia"
      and all is well.

      Löschen
  9. My second message to that whole wiki thing is up there, by the way, it just gets a bit lost in this whole structure, here. ^^;

    AntwortenLöschen
    Antworten
    1. No Problem! ;)

      I'll just answer down here.

      @manafreak: Would you be OK to set the US 1.0 ROM as standard for our collaborative research?

      @Raeven0: Yeah, sorry, Castoth *is* that first boss, you're right. I just read "someone's head" and thought that you meant the sky garden's bird's head, which is a different graphic in the Japanese version (i. e. he has a regular bird head).

      In case manafreak is a while absent, you can start working with the US 1.0 ROM, I think he'll be able to adapt. ;) Especially since the code you two exchanged here was surely from that ROM. ;)

      Löschen
  10. Hey guys,

    sorry for the absence, I had some well deserved vacation :)
    I totally agree with you in the usage of the US Rom 1.0 since This is the Rom I always used ;)
    Raeven0, thank you once again for your effort, This is a huge help for me :)
    Since I still have some days off I'm able to spend some time with the editor and can Start adding your findings to the World Map Tab :)

    AntwortenLöschen
    Antworten
    1. Welcome back! :)

      That's great, so I'll wait until someone throws me a bone on the romhacking wiki. ;)
      Another idea: An import/export function for Graphics into BMP and PNG would be nice. I got that idea when I mentioned that Bird boss, and thought about what would be the easiest and most convenient way to exchange those. But that would be something that should be push way, waaay to the back end of the to-do list. Everything else is more important.

      Speaking of which, maybe you can make a few bug-fixing versions instead of one big? I mean like: You put the next version out, we concentrate on finding bugs and list them asap, you fix them, put out a new test version, and we go on checking, until everything you have implemented so far works? I don't know how much this would mean additional effort for you, but I think it could fasten the whole process.

      Löschen