I thought you knew how to do that, since you said you removed the menu from the title screen.
EDIT:
Never mind, I think I got it. There is another global variable that holds the controller status, at 0x926E, and is used by the intro/title screen function (0x227BC) and the stage selection screen function (0x17C4E).
-
This reply was modified 13 years, 3 months ago by
HorvatM.
OK, I spent the last 5 hours making a primitive control scheme selection screen.
To use it, press Select + R during gameplay. Right now, you can choose between the original BPS scheme (selected by default) and my scheme.
While you are on the selection screen, the timer will appear to stop but will actually still be counting down. I don’t know how to fix this. I also haven’t tested it on hardware.
Attachments:
thunderstruck wrote:
Pretty cool. Do you plan more changes?
Not really. I’d like to remove some of the limitations on movement and add a control scheme selection screen, but it looks like everybody is fine with patching the ROM to change the controls.
I have no idea. I guess we’ll never know.
EDIT:
The details about the passwords are on the previous page, in case anyone thinks this is my reply to Benjamin’s original question about them.
I was going to try to find that out some day, but, since you asked, I felt obliged to start doing that immediately.
I already knew from previous attempts at hacking the game that the password (note: I’ll call it the password even though I haven’t told you whether it’s a password yet), unlike in eg. Insmouse, does not get stored anywhere into the WRAM, probably because there is nowhere to enter it. So I had to find the function that displays it. That was easy, and fortunately it was a separate function, while most of the gameplay code is in one huge function.
I assumed that the function only displayed the password and was not responsible for calculating it, so I thought I had to go somewhere else to find the calculating function. Common sense dictated that the call to the calculating function had to be close to the call to the displaying function. Well, there is only one place in the code where the displaying function is called and I noticed it was being passed two values. One of them was the current level, the other one was unknown to me. But it was a dead giveaway that the function was not only responsible for displaying the password, but for calculating it as well.
Virtual Lab code is very hard to follow and completely unlike the code in Insmouse: the functions are long, full of redundant instructions, and everything seems to be as complicated as possible; apparently the code was compiled without any optimizations. Since the password function contained both the code to calculate the password and to display it and was very long (much longer than you’d think, considering what it does), I really didn’t want to figure out how it works.
Instead, I decided to play with the two values passed to it. They were both global variables (so I don’t know why they decided to pass them as parameters, but at least it made reverse engineering much easier) and I knew one of them was the level. It shouldn’t be too hard to figure out what the other is, right? It turned out to be the “MAX” value. Amusingly, the game has two MAX-related variables, both of them global: one is incremented each time the on-screen MAX display is incremented, and the other is calculated before the incrementing begins.
Now that I knew what both values were, it was time to try out different combinations of them to see how they influence the generated password. Here are some of them:
Level 1, MAX 0: 0000000
Level 1, MAX 1: 0000016
Level 2, MAX 0: 0032000
Level 2, MAX 1: 0032016
A pattern emerges. We can see that to get the password of a given level and MAX value, we simply use the formula
P = L * 32000 + M * 16
where L is the completed level, starting with 0 for level 1, and M is MAX, which may be no higher than 62, although that value is impossible to get during gameplay. Let me also point out that, according to this formula, some of the passwords listed on this site are invalid because they are odd, while the formula only produces even numbers. All others are valid. I will speak about this later.
This formula works only for values of L up to 7. If you use it for L = 8, you will get 0256xxx, “xxx” depending on MAX. The game, however, gives you 1256xxx for completing level 9. Well, if you look at the password list on this site, you will see that the passwords for L values of 0 to 7 begin with a 0, 8 to 15 with a 1, 16 to 23 with a 0, 24 to 31 with a 1, and so on. So, in programming terms, if the bitwise AND of the level and 8 is nonzero, the password starts with a 1, otherwise it starts with a 0. This extra step appears to exist only to make reverse engineering the passwords slightly harder, as you will see later.
But even that only works up to L = 15. Starting with 16, things get weird. If you use the formula with 16, you get 0512000, but the game says 0002xxx. Long story short, if you look at the password list, you will see that, if you ignore the first digit, the passwords don’t just keep getting higher, but “roll over” to a smaller value periodically.
It was midnight (it was already 7:31 PM for me when you asked the question) and I was tired, so I went to sleep and continued the research in the morning before going to school (it starts at 8:40 AM on certain days). I discovered that the correct encoding algorithm (but not necessarily the one used in the game) is this (presented in an obscure programming language called NewtonScript, which is my favorite programming language and has a syntax similar to Pascal):
P := (L * 32000 + M * 16) mod 510000;
if BAnd(L, 8) <> 0 then P := P + 1000000;
Note: “mod” is the modulo operator, which here is effectively the remainder of division and is responsible for “rolling over” the number. “BAnd” is the bitwise AND function.
As you can see, L = 16 now gives us 0002000, which is a valid password. Now I only had to find a way to decode the level and MAX from any given password. My previous method was
P := P mod 1000000; // ignore the first digit
M := P mod 1000;
L := (P – M) div 32000; // get level
M := M div 16; // get MAX
but that only worked for values of L lower than 16. (Note: “div” represents division whose result is rounded towards zero.)
My classmate Sebastian Čolić (got to give credit where credit is due!) figured out the rest during history class.
For example, if you have the password 0034000, you will see my decoding algorithm fail. 34000 div 32000 is 1, but the correct level is 17. It turns out you have to pay attention to the remainder too. 34000 mod 32000 is 2000. Divide 2000 by 2000, multiply the result by 16, add 1, and you get 17. The correct algorithm, which I then tested against all the passwords listed on this site, except the odd ones, is this:
P := P mod 1000000; // ignore the first digit
M := P mod 1000;
P := P – M; // get rid of the last three digits
M := M div 16; // get MAX
Q := P div 32000;
R := P mod 32000;
L := R div 2000 * 16 + Q; // get level
Here are the rules for determining whether a given password is valid (there may be more):
* If the bitwise AND of the 0-based level and 8 is nonzero, the first digit of the password must be 1, otherwise it is 0.
* The last three digits, taken as a number, must be divisible by 16 and must not be higher than 832, because 52 is the highest possible MAX value (I think).
* The 0-based level must not be higher than 99.
Here is one more interesting fact about the game, which is not related to passwords: the game indeed ends and repeats on level 100, but since the level display is only two digits wide, the number 100 doesn’t display correctly. The programmer[s] accidentally checked for level 99, forgetting that it will be displayed as 100, while they should have checked for 98 instead.
The 17-year old mystery has finally been solved.
-
This reply was modified 13 years, 4 months ago by
HorvatM.
New version of my control scheme patch. This one modifies the controls like this:
Left D-pad: strafe and move forward/backward
Right D-pad: turn
L: hold down to run
Other controls are the same as before.
Attachments:
vb-fan wrote:
Hey — if you do hack the Rom, maybe it’s possible to replace the Japanese with English??? That’d be kewl-er!!!
According to Google Translate, the Japanese text in all cases says pretty much the same thing as the English text above it.
Yes, that’s an annoying flaw in the game. I’ve thought about hacking the ROM to fix this, but the code is such a mess that I can’t promise anything.
EDIT:
If it bothers you that much, play on the lowest speed. The scoring rules are the same anyway.
-
This reply was modified 13 years, 4 months ago by
HorvatM.
My guess is that it’s trying to start a program but can’t find it, since CreateProcess is a Windows API function for starting a program.
Here’s a patch that lets you to strafe with the left D-pad while turning with the right D-pad, allowing you to circlestrafe. However, you can’t also walk at the same time, but you can still walk and strafe without turning.
If there’s enough demand, I can try to improve this control scheme or even add support for multiple schemes in the game.
This patch should work with thunderstruck’s additions, but I have not verified that.
Attachments:
A look through the disassembly of Virtual Lab shows no GameLink code at all – that is, the relevant hardware registers are never touched.
If you remember my demo with GameHero and Fishbone joined, it is possible, but Benjamin Stevens said that didn’t run correctly on hardware and I didn’t bother to look into the issue. You might need a bigger flash memory chip for this, or special hardware in the cartridge altogether to avoid the problems that come with ROM hacking.
But why would you want unfinished demos? If there’s going to be a multicart at all, it should have finished games on it.
decayedmatter wrote:
Or perhaps is there a user on here who offers repair service for this issue?
If you are in Europe, I can recommend TheForce81. He’s from the Netherlands and will repair your VB for 30 EUR (plus shipping costs). I sent him mine in September, he repaired it very quickly and it has worked perfectly since. PM him for details.
This is great. I hope you make a full game out of this.
I doubt there will ever be a VB Pokémon game, simply because of copyright and trademark issues and because it’s more fun to work on original ideas rather than someone else’s intellectual property. Same goes for Mario, Zelda, Metroid, etc.
This works great. Thank you very much.
I measured a difference of about 3K between optimized and unoptimized ROM images, probably because of unused libgccvb functions.
Please, please learn how to structure code properly and how to use arrays.
Again, you only need to call PlaySound to start playing a sound, not to keep playing it. The music is great though.
There is a bug where you can go through the walls near the lower left dot, but it’s hard to reproduce. I found it the first time I ran the previous version though.
Also, why does the title screen say 2011?
Not that difficult.
Just press Select once. Works on both versions.
Attachments:
Guy Perfect wrote:
vb-fan wrote:
I see it now — a new release of the VB with backwards-compatibility (old games work!), and a new line of games! Wait — print not a linear array but a 3×4 grid, and no bulky console with mirrors but a lightweight pair of glasses and a belt-mounted box with a game-cart slot!
We could design one. A Planet Virtual Boy production. Even without the original components, we have better computing stuff nowadays, so we could make a miniature Virtual Boy that runs on some other, better hardware with emulator software.
I’ve thought about that too. But am I the only one who likes the VB as it is? The only design flaw I can find with it (not counting defects like glitchy screens and cracked stands) is that the stand only tilts instead of moving up and down, forcing you to sit in a weird position while playing it.
And I’d really like to see the V810 live on. It’s the best architecture I’ve worked with (speaking as a programmer). Too bad it’s not being produced any more. Can the V850 run V810 code? How would we implement VB-specific instructions?With the illegal opcode exception? Sure, that would make them slower but their timings aren’t documented anyway and it’s not like anyone uses REV, XB, or XH.
Still getting the same error. Yes, I did run crt0_make.bat.