# Romhacking.net

## Romhacking => ROM Hacking Discussion => Topic started by: Pingouin7 on October 20, 2011, 09:58:59 pm

Title: Question whose answer may seem obvious to you
Post by: Pingouin7 on October 20, 2011, 09:58:59 pm
I'm trying to edit the sprites of Pokémon in Blue version.
Bulbapedia says "The full offset to a sprite is then (bank << 14) + (pointer & 0x3fff)."

What would << and & stand for in that equation?

I tried searching but couldn't find anything about that.
Title: Re: Question whose answer may seem obvious to you
Post by: Klarth on October 20, 2011, 10:10:42 pm
Those are bitwise math operators.  Check wikipedia/google for a more thorough explanation than what I'll give.

So "<<" is left shift.  Which means bank is shifted 14 bits to the left.  This usually means bank * 2^14 (any bits that move "past" the register's max size are cut off)

& is bitwise AND.  \$3FFF is 0011 1111 1111 1111 in binary.  You convert pointer to a value like so (say the pointer is \$63F8) and do the following operation (only when both bits is 1, the result is 1...otherwise result is 0):
0011 1111 1111 1111 &
0110 0011 1111 1000 =
0010 0011 1111 1000 which is \$23F8

& is basically a way to zero certain bits you don't want.

Windows Calculator can do these operations for you.  In Win7, change to Programmer mode.  (Vista might be the same...XP it was in scientific mode)

PS: Next time stick around in IRC for longer than a minute to give people a chance to answer your question.  The room may have many people, but most are idle.
Title: Re: Question whose answer may seem obvious to you
Post by: Pingouin7 on October 20, 2011, 10:12:29 pm
Spoiler:
Gotcha, thanks for the help.
(Sorry about what happened in the chatroom.)

So, in a nutshell, if I were to do this with Bulbasaur's sprite pointer, which according to bulbapedia is at bank 0x0D (pointer is 0040), Bulbasaur's sprite would be at D00040, correct?
Wait, I think I messed up.

What I did was:

(0D * 2^14) + (0040 & 0x3fff).

0000 0000 0100 0000 &
0011 1111 1111 1111
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
0000 0000 0100 0000

0D * 2^14 =D00000

D00000 + 0040 = D00040, but that obviously is wrong.

Someone on another forum just explained it to me. I'll post the explanation here so that others who are stuck about that may know the answer:

Quote from: stag019
First, flip the byte order (0x4000 instead of 0x0040).
Second, go to windows calculator and in hex mode, type 4000 click the "and" button, and type 3FFF. The result is, in this case, 0 (Bulbasaur start the bank).
Third, the bank is 0x0D, according to the Bulbapedia article, for Bulbasaur, whose id is 0x99.
0x0D left shift 14 (0x0E) means multiply 0x0D * 2 ^ 0x0E which is 0x34000. Add the result of the first part (0) to get 0x34000 as the address he's located at.
Title: Re: Question whose answer may seem obvious to you
Post by: Vehek on October 20, 2011, 10:29:33 pm
0x0D shifted left 14 bits is 0x34000. And the pointer is 0x4000. You tried reading the pointer in "big-endian" order instead of "little-endian" order.

I think since you were in hexadecimal mode, the "14" was interpreted by the calculator as 0x14 (20 in decimal) instead of a decimal 14 (0x0E in hexadecimal).
Title: Re: Question whose answer may seem obvious to you
Post by: Pingouin7 on October 20, 2011, 10:31:24 pm
Yup, thanks for the help.
I'll make sure to credit you guys too once I'm done editing the sprites.
Title: Re: Question whose answer may seem obvious to you
Post by: Trax on October 20, 2011, 10:35:30 pm
Both are bitwise operators. They are an essential notion in ROM Hacking and programming in general. You use them to manipulate binary values in various ways. You should get familiar with these operators as a first step in ROM Hacking, along with hexadecimal notation. Wikipedia has a good page about them: http://en.wikipedia.org/wiki/Bitwise_operation.

The << means shift bits to the left. Mathematically speaking, it effectively multiplies your value by 2.
The & means bitwise AND. Used to keep (or "mask") specific bits. Not to be confused with &&, which is the logical AND, used in boolean logic.

In your specific case, the value of "bank" is shifted 14 times to the left, then added to the value of "pointer" with the 2 most significant bits masked (set to 0).
Let's say "bank" = 3, and "pointer" = ABCD.

0003 in binary -> 0000 0000 0000 0011
ABCD in binary -> 1010 1011 1100 1101
3FFF in binary -> 0011 1111 1111 1111

0003 <<  14 = 1100 0000 0000 0000 = C000
ABCD & 3FFF = 0010 1011 1100 1101 = 2BCD
C000 + 2BCD = EBCD

So your final pointer value is EBCD. You may have to add an arbitrary value (like 0x10) to account for the ROM header, if there is one...
Title: Re: Question whose answer may seem obvious to you
Post by: Pingouin7 on October 20, 2011, 11:24:54 pm
Thanks to everyone.