Replace all instances of strin A with string B

Started by live2play, June 14, 2010, 08:47:14 PM

Previous topic - Next topic

live2play

Is there an wasy way to replace all instances of unique string A with unique string B in MEM2 without having to make codes that reference each occurance in MEM2?

wiiztec

You could use the F6 codetype in conjunction with the 4E codetype
If there's any code at all that you want to be button activated, or even able to toggle on & off, and I have the game, just PM me and I'll make it happen

live2play

If you can give an example, that would be great.  Do I still have to give individual addresses of string A or is there a way for the code handler to detect the string and replace it on the fly?

Panda On Smack

there are some codes in the animal crossing topic that show how to do this

the code replaces certain references between 2 points with something else


live2play

Panda on Smack, thanks.  I'll have a look.  If you're able to locate the post, I would appreciate it if you could please post it.  Thanks again.

wiiztec

#5
4E000008 00000000
14000000 F6000003
F6000003 90009340
SSSSSSSS SSSSSSSS
SSSSSSSS SSSSSSSS
SSSSSSSS SSSSSSSS
16000000 00000018
RRRRRRRR RRRRRRRR
RRRRRRRR RRRRRRRR
RRRRRRRR RRRRRRRR
E0000000 80008000

S = sample string
R = replacement
If there's any code at all that you want to be button activated, or even able to toggle on & off, and I have the game, just PM me and I'll make it happen

live2play

#6
wiiztec, thanks!  Will this code search for string S and replace with string R in a given memory range?  Also, where in the code is the memory range (e.g. MEM2) specified for the replacements?

dcx2

#7
wiiztec - F6 code searching is slow.  You don't want to do F6 searches over and over and over again.

After an F6 code runs, it will over-write part of itself to indicate success or failure.  A proper code should really make sure that the previous F6 search has succeeded before resetting it to search again.  Then, once all instances of S have been replaced with R, the F6 will not continue searching.

When an F6 code successfully finds its target, it will replace the F6 line with a new line.

F6000003 90009340   # initial F6 line

F6000303 QQQQQQQQ   # F6 search succeeded; Q is a pointer to the beginning of S

F6000103 90009340   # F6 search failed


Therefore, you should add a conditional that makes sure the "reset" line ( 14000000 F6000003 ) only resets the F6 code when it has previously succeeded in finding S.

EDIT:

The memory range is specified by 90009340.  It is of the form XXXXYYYY, where the F6 code will search all addresses starting with XXXX0000 up to but not including YYYY0000.  (i.e. 90000000 through 93400000, or MEM2)

EDIT2: The F6 code replacements for success/failure were off by one hex digit

live2play

#8
dcx2, thanks for the clarification.

What part of the code is the actual memory range to search?  What would the code look like with your checks added?

Also, I'm assuming that I would want to button activate a search/replace code as I don't want it to start/stop before all of the desired data has been loaded into MEM2, right?

dcx2

Oh, right, by the way, when resetting the F6 search, you should also reset the memory range.

i.e.

4E00000C 00000000
14000000 F6000003
14000004 90009340
F6000003 90009340
....

live2play

#10
dcx2, if you can please give me a complete code that would replace 31323334 in MEM2 with 31323335 using the information wiiztec and you provided, I would REALLY appreciate it.  Is the following combination of the information you both provided correct?

(Your code)
4E00000C 00000000
14000000 F6000003
14000004 90009340
F6000003 90009340
(wiiztec's code)
SSSSSSSS SSSSSSSS
SSSSSSSS SSSSSSSS
SSSSSSSS SSSSSSSS
16000000 00000018
RRRRRRRR RRRRRRRR
RRRRRRRR RRRRRRRR
RRRRRRRR RRRRRRRR
E0000000 80008000

S = sample string
R = replacement

dcx2

There aren't any 8-bit ifs, so you'd need to use a 16-bit if-equal, potentially using the bitmask fields.

Also, the F6 code searches for 64-bits at a time.  So you can't just search for 31323334.  I will expand your example to be 31323334 35363738.  I will replace it with 31323335 36373839 3A3B3C3D 3E3F4041.  Note that the replacement does not have to be the same size as the search values.

Here's my attempt.  This might need some fixing (particularly the first if; not sure about that mask...), as I can't really test it...

4E000010 00000000   # get pointer to code line in po
38000000 00FF0300   # if byte of interest == 03, search was successful; reset F6 code
14000000 F6000001
14000004 90009340
E0000000 80008000   # terminator
F6000001 90009340   # searching in range 90000000 to 93400000
31323334 35363738   # For these values.  If the values are found...
16000000 00000010   # do a string write to replace them
31323335 36373839
3A3B3C3D 3E3F4041
E0000000 80008000   # terminator

live2play

Thanks!  So, what if I want to replace a\a with b\b where a\a is followed by text that varies?  It seems that I would have to know the text after a\a in order to replace it with b\b+<original_text>.  Is that correct?

dcx2

The F6 code will search for whatever values you provide it, and put the result in the PO.  So you must carefully tailor your search values so that it finds the right thing.  If something varies, but it comes after the search value, then the F6 code won't care.

Once you get that pointer, you can replace as much as you want from the pointed-at value.  That's why I stressed that the number of S search values has no relation to the number of R replacement values.

live2play

So, back in my original example, what if I only wanted to replace the 31323334 portion of every 64-bit search that was performed?  What would my "S" look like given that I only know for sure that the "31323334" portion will remain constant?