Go Back   Project64 Forums > Public Version > Project 64 - v2.x - Cheats

Reply
 
Thread Tools Display Modes
  #201  
Old 20th March 2014, 02:55 AM
HatCat's Avatar
HatCat HatCat is offline
Alpha Tester
Project Supporter
Senior Member
 
Join Date: Feb 2007
Location: In my hat.
Posts: 16,260
Default

Quote:
Originally Posted by RPGMaster View Post
I totally understand the concept of bitstrings. I just happen to have a bad memory so I just thought of ways where I could generate the desired values for the bitstrings.

The point of my previous post was to line up the 0's and 1's, then copy them after vertically highlighting them, then pasting them and highlight the pasted values, then using control-f to replace \r\n with nothing, so it erases the newline characters so that it combines the 1's and 0's into 1 string of numbers.

Lol looking back on it, I could probably just read each thing. I was just being silly. I remember taking a while to come up with the desired bit string values for the songs I wanted.
Since you mentioned vertically highlighting them I take it you were talking about how to do it in a graphical user interface, not a GUI-free console like the way I'm doing. I did try to think of other ways to take in the cheat flags besides making the user type in a string of bits, but I couldn't think of anything more...convenient. If you have a bad memory then yes, having checkboxes with the names of the cheats next to them is best. (Then again you lose sight of the low-level of how the cheat bits are stored in the EEPROM, so a GUI sacrifices some information that can only be seen when working on the console level, too...it's not all one-sided.)

Btw sorry for spamming your thread again retroben.

Quote:
Originally Posted by RPGMaster View Post
For save editor, I'm mostly interested in OOT and Majora's mask.
Ah, I don't believe anyone's ever contributed a save editor for Zelda OOT yet.
I prefer Majora's Mask as a game so ended up doing my flashram editor there.

Still, with OOT, you have to understand the 32-bit CRC it does. I'm not very good at CRC polynomials or data encryption stuff, but you said you were interested in algorithms so I suppose it could be an interesting test to you.

Zelda MM only uses a simple, additive 16-bit checksum. (I just had to add up all the bytes up to a certain point.) Nothing too challenging about checksum algorithms there.
Reply With Quote
  #202  
Old 20th March 2014, 03:08 AM
retroben's Avatar
retroben retroben is offline
Alpha Tester
Project Supporter
Senior Member
 
Join Date: Jul 2013
Posts: 681
Default

If it is Banjo related,then its not spamming.

I asked for that Banjo-Tooie save editor anyway.

I can't think clearly because of the dizzy headaches I have been frequently getting lately.
Reply With Quote
  #203  
Old 20th March 2014, 03:50 AM
RPGMaster's Avatar
RPGMaster RPGMaster is offline
Alpha Tester
Project Supporter
Super Moderator
 
Join Date: Dec 2013
Posts: 2,014
Default

The highlighting suggestion was for writing down the 1's and 0's in notepad. I was just being silly, thinking it was a hassle to write a few 1's and 0's since I wouldn't memorize what each digit represents. I could just read through a list when writing the 0's and 1's so that whole copy paste thing is not needed ;/. Since you already worked on MM, I'll probably do that one before I do OOT. With Nemu, would I be able to see the checksum algorithm for the save data?

Again I might make a GUI for even Banjo-Tooie. I'd like some suggestions on what features to put in it. Nothing too fancy though.

My biggest problem with a GUI is that if you want a full fledged save editor, there's just too much stuff to put in lol. BatCat, is your MM save editor open source? I could make a GUI for it.
Reply With Quote
  #204  
Old 20th March 2014, 04:05 AM
HatCat's Avatar
HatCat HatCat is offline
Alpha Tester
Project Supporter
Senior Member
 
Join Date: Feb 2007
Location: In my hat.
Posts: 16,260
Default

First off, to try and stay on-topic to retroben's thread, I just added another option to make sure all the shortcut silos are opened up throughout the Isle O' Hags.
Code:
--------------------------------------------------------------------------------
Option:  -s
Syntax:  b7 %filepath% -s <flags>
Effect:  access to Jamjar's silo shortcut tunnels

<flags> -- A little-endian string of eight binary digits, signifying whether
           each of Jamjars' silos is accessible to Banjo.
00000001:  JINJO VILLAGE
00000010:  WOODED HOLLOW
00000100:  PLATEAU
00001000:  PINE GROVE
00010000:  CLIFF TOP
00100000:  WASTELAND
01000000:  QUAGMIRE
10000000:  just whether or not Jamjars has introduced this feature to Banjo yet
--------------------------------------------------------------------------------
That last bit there may seem fairly useless, but it was bunched together with the other 7 bits, so the most organized thing to do seemed to be adding it in as a feature.


Heh, RPGMaster I'd feel kinda bad about making people type in 0s and 1s all the time if I never documented in the manual what the flags do.

If you do make a GUI for a save editor, I think the only real goal is just ease of use, clarity, things like that. I have no idea how you would tab the things out though...maybe have one tab for all the global game settings, another for game progress settings, ...idk. Creative thinking works best here.

Quote:
With Nemu, would I be able to see the checksum algorithm for the save data?
That was how I found the checksum algorithm for Banjo-Tooie, so yes I'm sure you could use Nemu64 to set breakpoints and step through the MIPS machine code instructions, register changes, etc. However like I said, I know next to nothing about checksums, encryption, CRCs ... I didn't understand a damn thing about what Banjo-Tooie's custom checksum algorithm was doing other than a lot of 64-bit bit-wise math, so I just literally implemented it in assembly-language-style C code based on what I learned from Nemu64:

Code:
u64 calculate_Banjo_checksum(unsigned int block, int size)
{
    __W64 ret_slot;
    int branch, half_done;
    u32 fake_stack[0x60 / 4] = {
        0x00000000, 0x80082130, 0x80079B78, 0x80082154,
        0x00000001, 0x00000003, 0x00000000, 0x801922F0,
        0x800456E8, 0x00000002, 0xFFFFFFFF, 0x801929C8,
        0x00000002, 0xFFFFFFFF, 0x801927F0, 0x80088708,
        0x80081F3C, 0xC0000000, 0x8F809F47, 0x3108B3C1,
        0x00000000, 0x00000000, 0x801922F0, 0x00000080
    };

    half_done = 0;
/*
 * Fake the RDRAM offsets to target buffered EEPROM.
 */
    GPR[SP].W = (u32)(fake_stack);
    GPR[S0].W = (u32)(EEPROM) + 8*block;
    GPR[S5].W = GPR[S0].W + size;
/*
 * MIPS "re-assembly" of the checksum algorithm:
 */
    or     (S1, ZERO, ZERO);
 /* ... */
    or     (S3, ZERO, ZERO);
    or     (S4, ZERO, ZERO);
 /* ... */
    addiu  (S2, SP, 0x0048);
block_1: /* USA offset:  0x1928A4 */
    lbu    (T8, S0, 0x0000);
    lw     (T5, SP, 0x004C);
    andi   (T9, S1, 0x000F);
    sllv   (T0, T8, T9);
    lw     (T4, SP, 0x0048);
    addu   (T7, T0, T5);
    sra    (T2, T0, 31);
    sltu   (AT, T7, T5);
    addu   (T6, AT, T2);
    addu   (T6, T6, T4);
    sw     (T6, SP, 0x0048);
    sw     (T7, SP, 0x004C);
    jal    (&branch);
    or     (A0, S2, ZERO);
    if (branch != 0)
        goto block_2;
 /* who cares (unconditional jump) */
block_2: /* USA offset:  0x1168AC */
    ld     (A3, A0, 0x0000);
    dsll32 (A2, A3, 31);
    dsll   (A1, A3, 31);
    dsrl   (A2, A2, 31);
    dsrl32 (A1, A1, 0);
    dsll32 (A3, A3, 12);
    or     (A2, A2, A1);
    dsrl32 (A3, A3, 0);
    xor    (A2, A2, A3);
    dsrl   (A3, A2, 20);
    andi   (A3, A3, 0x0FFF);
    xor    (A3, A3, A2);
    dsll32 (V0, A3, 0);
    sd     (A3, A0, 0x0000);
    jr     (&branch);
    dsra32 (V0, V0, 0);
    if (branch != 0)
    {
        if (half_done == 0)
            goto block_3;
        else
            goto block_6;
    }
 /* who cares (unconditional jump) */
block_3: /* USA offset:  0x1928DC */
    addiu  (S0, S0, 0x0001);
    addiu  (S1, S1, 0x0007);
    bne    (&branch, S0, S5);
    xor    (S3, S3, V0);
    if (branch != 0)
        goto block_1;
    half_done = 1;
#ifndef REAL_N64_RDRAM_STATE
    GPR[S0].W = (u32)(EEPROM) + 8*block;
    sw     (S0, SP, 0x0058);
#endif
    lw     (A3, SP, 0x0058);
    addiu  (S0, S5, 0xFFFF);
    sltu   (AT, S0, A3);
    bnez   (&branch, AT);
    addiu  (S2, SP, 0x0048);
    if (branch != 0) /* This should never happen. */
        goto block_5;
    addiu  (S5, A3, 0xFFFF);
block_4: /* USA offset:  0x192904 */
    lbu    (T1, S0, 0x0000);
    lw     (T3, SP, 0x004C);
    andi   (T8, S1, 0x000F);
    sllv   (T9, T1, T8);
    lw     (T2, SP, 0x0048);
    addu   (T5, T9, T3);
    sra    (T0, T9, 31);
    sltu   (AT, T5, T3);
    addu   (T4, AT, T0);
    addu   (T4, T4, T2);
    sw     (T4, SP, 0x0048);
    sw     (T5, SP, 0x004C);
    jal    (&branch);
    or     (A0, S2, ZERO);
    if (branch != 0)
        goto block_2;
 /* who cares (unconditional jump) */
block_6: /* USA offset:  0x19293C */
    addiu  (S0, S0, 0xFFFF);
    addiu  (S1, S1, 0x0003);
    bne    (&branch, S0, S5);
    xor    (S4, S4, V0);
    if (branch != 0)
        goto block_4;
    ret_slot.HW[1] = GPR[S3].HW[0];
    ret_slot.HW[0] = GPR[S4].HW[0];
    return (ret_slot.UW);
block_5:
    return (GPR[S3].W & 0x00000000FFFFFFFF);
}
However, you really shouldn't have to resort to this.

If Zelda OOT's CRC-32 is the standard, well-documented and very-well-heard-of CRC algorithm I'm thinking of, you shouldn't need to use Nemu64 to disassemble the ROM and hack out the algorithm. There's probably some C standard header file that includes its own CRC-32 function that will completely do the work for you for something that widespread and well-documented.

Quote:
BatCat, is your MM save editor open source? I could make a GUI for it.
Yes it is open-source and on my GitHub online repository which I prefer to refrain from linking to in public.

Still, I released that software in binary and source form in this thread:
http://forum.pj64-emu.com/showthread.php?t=4132
... so you should be able to get it there.


Wow, 738 views and 56 downloads??
I never thought it'd achieve that kind of popularity...I thought everyone would give me shit about it needing a GUI, and making people read the manual and do file byte-swapping themselves...but I guess loads of people were so desperate for a Zelda MM save editor they didn't complain.
Reply With Quote
  #205  
Old 20th March 2014, 07:08 AM
RPGMaster's Avatar
RPGMaster RPGMaster is offline
Alpha Tester
Project Supporter
Super Moderator
 
Join Date: Dec 2013
Posts: 2,014
Default

I don't see the source code in the link you provided. I just need it for helping me with file i/o. I've never really read a file then updated the file. I also don't know the addresses for each variable.

I've decided to work on a GUI this week. I'm thinkin I'll start with MM first, because the banjo one is incomplete. I don't have enough time to do much in-game testing, so I have to rely on you guys for the addresses for variables.
Reply With Quote
  #206  
Old 20th March 2014, 09:19 AM
retroben's Avatar
retroben retroben is offline
Alpha Tester
Project Supporter
Senior Member
 
Join Date: Jul 2013
Posts: 681
Default

Retroben with the kewl codes.
Hatcat makes the save editors.
RPGMaster builds the GUIs for them.

The equivalent of the IT Crowd...

We are the PJ Crowd!
Reply With Quote
  #207  
Old 20th March 2014, 02:40 PM
HatCat's Avatar
HatCat HatCat is offline
Alpha Tester
Project Supporter
Senior Member
 
Join Date: Feb 2007
Location: In my hat.
Posts: 16,260
Default

Quote:
Originally Posted by retroben View Post
Retroben with the kewl codes.
Hatcat makes the save editors.
RPGMaster builds the GUIs for them.

The equivalent of the IT Crowd...

We are the PJ Crowd!
lol, is that right? What's the IT Crowd?

Quote:
Originally Posted by RPGMaster View Post
I don't see the source code in the link you provided. I just need it for helping me with file i/o. I've never really read a file then updated the file. I also don't know the addresses for each variable.
OMG you're right!
Well that was dumb of me...shit. I don't have a clue why I didn't bundle src.

I guess I was so pushed into uploading the software by a couple Zelda freaks that I was reluctant and hesitant enough about organizing it to begin with, so I felt like doing a minimalist upload just to shut people up.

Well, if I'd known it'd attract that much attention, I'd have thrown in source code with it. ...I think? Then again, it does have a lot of swear words in it XD. Some things I did in the source then, I would not have done now.... Perhaps I just need to maintain it again.

Quote:
Originally Posted by RPGMaster
I've decided to work on a GUI this week. I'm thinkin I'll start with MM first, because the banjo one is incomplete. I don't have enough time to do much in-game testing, so I have to rely on you guys for the addresses for variables.
You shouldn't need to know the FLASHRAM addresses to make a GUI frontend.

All you'd really need to know is basic string manipulation I guess. Like, if the user checks the 4 boxes in your GUI saying, "Have boss masks: Odolwa, Goht, Gyrog, Twinmold", then you would create a 4-digit bitstring "1111" and pass that as the argument. You'd probably use the system() function in C stdlib, as: system("zs flashram_input.fla 0 --boss-masks 1111"); and, without knowing the flashram addresses in my C source, your frontend would successfully call my core executable to do the job.

Now, if you're trying to re-do a save editor as a GUI application, without it being a front-end extension to an existing console application I wrote, then you would need source code...hm. Well at any rate if it makes you feel more comfortable I'll see if I can dig up exactly what mess of C I used to compile the bin I attached to that thread. Now that you mention it I remember having to go back to an old tree of my repository back when the program still worked. XD
Reply With Quote
  #208  
Old 20th March 2014, 03:04 PM
HatCat's Avatar
HatCat HatCat is offline
Alpha Tester
Project Supporter
Senior Member
 
Join Date: Feb 2007
Location: In my hat.
Posts: 16,260
Default

You mentioned needing help with practical file stream usage in C.

A basic FLASHRAM save file loader in C should go like this:

Code:
#include <stdio.h>

#define FLASH_SIZE      0x00020000

unsigned char FLASHRAM[FLASH_SIZE];

int main(int argc, char* argv[])
{
    FILE* stream;
    register int i;

    if (argc < 2) /* argv[1] does not exist. */
        stream = fopen("ZELDA MAJORA'S MASK.fla", "rb");
    else
        stream = fopen(argv[1], "rb");

    if (stream == NULL)
    {
        fputs("Failed to import FLASHRAM.\n", stderr);
        return 1;
    }
    fclose(stream); /* with all binary imported, we needn't this anymore */

    for (i = 0; i < FLASH_SIZE; i++)
    {
        const int test = fgetc(stream);

        if (test == EOF) /* defined in <stdio.h> */
            break;
        else
            FLASHRAM[i] = (unsigned char)(test);
    }

    FLASHRAM[0x10000] = 0x11; /* just a test change :P */

/* now to write up-to-date FLASHRAM array back to a file... */
    if (argc < 2)
        stream = fopen("ZELDA MAJORA'S MASK.fla", "wb");
    else
        stream = fopen(argv[1], "wb");

    for (i = 0; i < FLASH_SIZE; i++)
        fputc(FLASHRAM[i], stream); /* writes each byte to the file */
    return 0;
}
Obv there are plenty of things in that code which would be done differently (such as using fread instead of my massive, compatibility fgetc loop, same thing for writing the file back onto your hard disk drive), but at least it should make sense at any rate.
Reply With Quote
  #209  
Old 20th March 2014, 04:26 PM
HatCat's Avatar
HatCat HatCat is offline
Alpha Tester
Project Supporter
Senior Member
 
Join Date: Feb 2007
Location: In my hat.
Posts: 16,260
Default

Heh, that jiggy in Mayahem Temple where you "have to" get the wading boots to go across the quicksand to get it?

Guess Rare didn't put enough thought into the bypasses for that one. With the SUPERBANJO cheat entered, Mumbo Jumbo had enough speed to just keep jumping across the man-eating shit and get the jiggy without the wading boots.

Also, I had no idea that SUPERBANJO cheat would make Golden Goliath move faster too
Reply With Quote
  #210  
Old 20th March 2014, 07:05 PM
RPGMaster's Avatar
RPGMaster RPGMaster is offline
Alpha Tester
Project Supporter
Super Moderator
 
Join Date: Dec 2013
Posts: 2,014
Default

Lol ok, so I had the right idea with using a large buffer to read the fla data. Idk why people are so against global variables. Ya I generally used fread. I forgot what I did to count the number of bytes in the file lol. I'll have to go back and look at some of my previous programs. I love how I can totally forget how to do something and quickly relearn it since I can just refer to previous thing's I've either written or read.

I suppose making a front end GUI would be easier for me. All I'd have to do is be able to generate commands .

Eventually I'd like to have the flashram addresses, because I like collecting data . I should probably beat the game before I add stuff to the save editors for Zelda though.

Edit: I've never tried that system("") other than system("PAUSE") in school. I'm going to see how that works now .

Last edited by RPGMaster; 20th March 2014 at 08:16 PM.
Reply With Quote
Reply

Tags
banjo-tooie, gameshark

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump


All times are GMT. The time now is 07:01 PM.


Powered by vBulletin® Version 3.7.3
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.