Skeetendo

’Cause all games were better on the GBC

You are not logged in.

#1 1970-01-01 00:33:30

~Red
Member
Registered: 2010-10-16
Post 1/276

Pokemon Red Sprite Decompression and Scripts

I have found next to no information about how the Sprite Decompression works in Red, nor how to add Decompressed sprites like Brown.

I also would like to know if anyone has tried changing the scripts in Red (such as movement, being given items, Yes No boxes, given Pokemon)

Offline

#2 1970-01-01 00:33:30

Cartmic
Member
Registered: 2010-10-16
Post 14/156

Re: Pokemon Red Sprite Decompression and Scripts

What MeanMrMustard did in brown was if I remember correctly is write a new picture display routine and point to uncompressed graphics.

I came up with a theory years ago that the graphics were stored as instructions which when passed through the "decompression" routine are drawn to the screen on the fly. A while later Tauwasser did some separate research into it and produced some documentation.

The events stuff is written in Assembly Language.

Offline

#3 1970-01-01 00:33:30

~Red
Member
Registered: 2010-10-16
Post 2/276

Re: Pokemon Red Sprite Decompression and Scripts

Could you (potentially) write a program that edits scripts in Red? I have attempted to learn ASM before but it went straight over my head.

Offline

#4 1970-01-01 00:33:30

Mateo
Member
From: The Sims 4
Registered: 2009-11-25
Post 74/3,578

Re: Pokemon Red Sprite Decompression and Scripts

Since the scripts are written in asm, you will still have to learn asm. A script editor for red would basically just be an asm compiler.

Offline

#5 1970-01-01 00:33:30

~Red
Member
Registered: 2010-10-16
Post 3/276

Re: Pokemon Red Sprite Decompression and Scripts

The only thing I never really understood about ASM is what you write it in. People say a HEX Editor but others say a Decompiler? I don't get it.

Offline

#6 1970-01-01 00:33:30

Mateo
Member
From: The Sims 4
Registered: 2009-11-25
Post 75/3,578

Re: Pokemon Red Sprite Decompression and Scripts

You can do it either way. If you know what the opcodes are in hex, you can write it directly in hex. However, you can also use a compiler, and type it in english and then it will translate it into hex for you. It's just like I script for gold in a hex editor, but some people use PKSV.

Also, I have only a minimal understanding of ASM as it is. I'm just starting out with learning it, so I can't answer a lot of questions about it. iimarkus knows more about ASM though

Offline

#7 1970-01-01 00:33:30

8/703

Re: Pokemon Red Sprite Decompression and Scripts

Pokémon RBY sprite decompression in C
There are no compressors that I know of. Cartmic is correct in saying that Meanmrmustard rerouted the display routine to not use compression.


The only thing I never really understood about ASM is what you write it in. People say a HEX Editor but others say a Decompiler? I don't get it.

It can be done in a hex editor but this is slow and error-prone. Typically the quickest solution for simple ROM hacking.

Major hacks or outright homebrew are nominally written in any text editor (like Notepad), then run through an "assembler" which spits out a complete ROM file. The most widely-used Game Boy assembler is probably RGBDS. Using an assembler is much, much, much nicer than hex editing because you can use labels instead of manually calculating pointers, define your own constants and macros, and put comments in the source file; none of these can be done in a hex editor. Most, if not all, Game Boy games were written with an assembler.

I have a disassembly of Red in progress (haven't worked on it in a few months, but it's still on my to-do list). I need to move it to source control -- think Wikipedia's history/compare feature -- but I'll get around to it later.

#8 1970-01-01 00:33:30

~Red
Member
Registered: 2010-10-16
Post 4/276

Re: Pokemon Red Sprite Decompression and Scripts

Ok. I think I understand now. I will try and plough through ASM School.

Offline

#9 1970-01-01 00:33:30

~Red
Member
Registered: 2010-10-16
Post 9/276

Re: Pokemon Red Sprite Decompression and Scripts

Sorry for double post but I have to ask something. The thing that keeps bugging me about ASM is registers. ASM School doesn't really cover what they are or do. Are they kind of like Variables that hold data? I'm really confused. Also, do I have to learn how each and every register operates?

Offline

#10 1970-01-01 00:33:30

10/703

Re: Pokemon Red Sprite Decompression and Scripts

~Red wrote:

Sorry for double post but I have to ask something. The thing that keeps bugging me about ASM is registers. ASM School doesn't really cover what they are or do. Are they kind of like Variables that hold data? I'm really confused. Also, do I have to learn how each and every register operates?

I remember understanding registers being a real epiphany for me.

You know about memory. It's a collection of contiguous values. RAM location $0000 can hold a one-byte value (0 to 255; $00 to $FF if you prefer). Location $0001 can hold a different one-byte value, and so on all the way to $FFFF.

A CPU register can also hold a one-byte value. Instead of referring to these with numbers (memory locations), we refer to them with letters. These are the CPU registers in the Game Boy:
a b c d e f h l s p

ASM opcodes usually manipulate values in these registers. E.g.,

ld a,$11 ; puts the value $11 into register a
ld c,a ; puts the value of a ($11) into register c, so c now holds $11

The registers in the Game Boy CPU are 8-bit (0 to 255). You can simulate 16-bit registers by combining two 8-bit registers. For instance, there is an ASM opcode

ld hl,$2000 ; puts $20 into h and $00 into l

An easy way to remember which is which: h is the high byte and l is the low byte.

Only some registers can be paired:
af bc de hl sp
sp is always paired. You will never refer to s or p separately.

Most of the registers simply hold a value: a, b, c, d, e, h, and l each simply hold a value. Of these, a (often called the "accumulator") is the most versatile: there is a “ld a,$xx” instruction but no “ld c,$xx” instruction, so to put a value in c you have to do “ld a,$xx” and “ld c,a” in succession.

f (the "flags" register) is special. You cannot write values to f. Instead four bits will change depending on what happened during the last instruction. The two major flags are z (zero) and c (carry). z is set (becomes 1) if the result of the last instruction is 0, and reset (becomes 0) otherwise. c is set if there is an overflow or reset otherwise. E.g.,

ld a,$FF
inc a ; increments a

After this a will hold $00 and the carry flag will be set, because it overflowed.

The stack pointer (sp) is more complicated and I'm not sure I can give a sufficiently simple explanation. Just know that when you “call,” the current execution location is pushed onto the stack and when you “ret” it is popped off.

#11 1970-01-01 00:33:30

Hyde~
Member
Registered: 2010-10-16
Post 3/47

Re: Pokemon Red Sprite Decompression and Scripts

I DIDNT UNDERSTAND  :P

Offline

#12 1970-01-01 00:33:30

~Red
Member
Registered: 2010-10-16
Post 11/276

Re: Pokemon Red Sprite Decompression and Scripts

And can I take data from an address in the ram and put it in a register? Can I even take something from the rom into the ram with asm?

Offline

#13 1970-01-01 00:33:30

11/703

Re: Pokemon Red Sprite Decompression and Scripts

FYI: a hex/ASM equivalent table
description of each opcode

And can I take data from an address in the ram and put it in a register?

Yes. E.g., “ld a,[$XXYY]” will copy the value from memory location $XXYY to a.

Note the brackets. $XXYY refers to the 16-bit value $XXYY; [$XXYY] refers to the 8-bit value located at $XXYY. You will also sometimes see [hl] or similar, meaning the 8-bit value at the location pointed to by hl.

As usual, the accumulator is more versatile: there is a ld a,[$XXYY] instruction but no ld b,[$XXYY] etc. instruction.

Can I even take something from the rom into the ram with asm?

It appears you don't know the RAM layout of the Game Boy.

0000-3FFF: ROM bank 0
4000-7FFF: switchable ROM bank
8000-9FFF: VRAM
A000-BFFF: external RAM
C000-CFFF: WRAM0
D000-DFFF: WRAM1
E000-FDFF: ECHO (typically not used)
FE00-FE9F: OAM RAM
FEA0-FEFF: unused
FF00-FF7F: Game Boy hardware registers (not related to the CPU registers described earlier)
FF80-FFFE: HRAM
FFFF: Interrupt enable register

Each of these areas of RAM has a specific purpose.
VRAM, video RAM, is for tile data.
External RAM is (I believe) save data.
WRAM, work RAM, is general scratch area. This is why Gameshark codes are between 01XX00C0 and 01XXFFDF: the device only modifies WRAM because that's where games keep most data like lives and hit points.
OAM RAM contains sprites.
HRAM, high RAM, is the only RAM that can be accessed during a DMA transfer.

As you can see, ROM bank 0 is always in RAM. The first $4000 bytes of ROM are always at their corresponding location in RAM. Look at any memory dump and you will see the ROM header starting at $104. Writing to this area will have no effect, because it is read-only.

The area of RAM from $4000 to $7FFF can contain any ROM bank except bank 0. One bank at a time, of course; you must switch between them. This is done with a piece of hardware in the cartridge called a Memory Bank Controller. When you write to RAM location $2000, normally a meaningless procedure because that area is read-only, the MBC will intercept the instruction and page in a bank. E.g., after the following instructions:

ld a,2
ld [$2000],a

ROM bank 2 (that is, the area of ROM from $8000 to $BFFF) will be paged into RAM locations $4000 to $7FFF.

Banking is why pointers to ROM locations are typically between $4000 and $7FFF -- because they're really pointing to RAM, not directly to the ROM.

It goes without saying that the area of RAM from $4000 to $7FFF is also read-only.

#14 1970-01-01 00:33:30

~Red
Member
Registered: 2010-10-16
Post 13/276

Re: Pokemon Red Sprite Decompression and Scripts

So I could put decompressed sprites into the ROM. Switch to the bank that holds them then move it from that part of the RAM to the address that holds the currently loaded sprite?

(I think the address for opponents sprite and your backsprite is $9000 for about 200 bytes)

Offline

#15 1970-01-01 00:33:30

12/703

Re: Pokemon Red Sprite Decompression and Scripts

Yes.

#16 1970-01-01 00:33:30

~Red
Member
Registered: 2010-10-16
Post 14/276

Re: Pokemon Red Sprite Decompression and Scripts

How to I move blocks of data? So far I only know how to move one or two bytes of data at any one time.

Offline

#17 1970-01-01 00:33:30

13/703

Re: Pokemon Red Sprite Decompression and Scripts

How to I move blocks of data? So far I only know how to move one or two bytes of data at any one time.

The game developers put in routines to make this easier. In Pokémon Red, it looks like this:

ld hl,$4000
ld de,$D000
ld bc,$10
call $00B5

When this is run, $10 bytes starting at $4000 will be copied to $D000.

Mnemonics for the parameters: byte count, destination. This register pattern often holds for other existing ASM routines, but it is of course not a hard-and-fast rule (we only have so many registers to work with).

If you want to know how this copy routine was implemented, you can look at offset $B5.

#18 1970-01-01 00:33:30

~Red
Member
Registered: 2010-10-16
Post 15/276

Re: Pokemon Red Sprite Decompression and Scripts

ASM doesn't seem that hard now I've been reviewing it. Also, you can compile ASM but can you decompile it? Or is that what you meant by the red decompile you are making, are you doing it opcode for opcode?

Offline

#19 1970-01-01 00:33:30

14/703

Re: Pokemon Red Sprite Decompression and Scripts

Disassemblers do exist. The catch is that disassembling is a very hard problem to solve. Programs can't tell the difference between code and data -- to them, bytes are bytes. Good disassemblers will partially emulate the processor and disassemble code as they run it, but it's still impossible to exhaust all possible code paths.

The other problem is that you need a human to understand what the code's doing. What good is a disassembly if it's all inscrutable code, hardcoded addresses, and no comments or labels? If it says "ld hl,$4000", which $4000 is it referring to? How do you know it's even in the same bank? I would rather have a few important things (like trainer AI, data parsing, etc) disassembled by hand and readable and the rest of the ROM included as a binary blob than have a bunch of undocumented source code. Disassembling byte-by-byte lets me figure out what the programmers were trying to do.

That said, it is slow and even I don't have all Game Boy machine code memorized (although I do know many opcode-byte equivalents). I have an automated disassembly (I used wlad for that) that I use side-by-side with the hex editor so I don't have to look up opcodes.

#20 1970-01-01 00:33:30

~Red
Member
Registered: 2010-10-16
Post 19/276

Re: Pokemon Red Sprite Decompression and Scripts

I've just figured out why my music wouldn't work. I added some music byte by byte to a blank part of the ROM but it wouldn't work. I'm guessing that it was in a different ROM Bank to the normal music so I'd need to switch banks for it to work.

Offline

#21 2012-09-08 06:29:15

Danny-E 33
Administrator
Registered: 2012-06-09
Post 114/1,119

Re: Pokemon Red Sprite Decompression and Scripts

I agree. This is the first time I've stumbled upon good explinations of each RAM bank. And I've wondered about that for some time now.

IIMarckus wrote:

HRAM, high RAM, is the only RAM that can be accessed during a DMA transfer.

What does this mean exactly?

It's interesting to realize the RAM is only 4 banks... I never thought it was that short. I just never had the RAM spelled out so clearly for me before. Each time I heard the term VRAM, external RAM, WRAM0, WRAM1, ECHO RAM, OAM RAM, I always assumed each of those was its own bank :P

Offline

#22 2012-09-08 14:50:15

Miksy91
Member
Registered: 2010-10-16
Post 1,091/2,339

Re: Pokemon Red Sprite Decompression and Scripts

Danny-E 33 wrote:

I agree. This is the first time I've stumbled upon good explinations of each RAM bank. And I've wondered about that for some time now.

IIMarckus wrote:

HRAM, high RAM, is the only RAM that can be accessed during a DMA transfer.

What does this mean exactly?

It's interesting to realize the RAM is only 4 banks... I never thought it was that short. I just never had the RAM spelled out so clearly for me before. Each time I heard the term VRAM, external RAM, WRAM0, WRAM1, ECHO RAM, OAM RAM, I always assumed each of those was its own bank :P

Not sure how right I'm here when pointing this out but there are only two 0x4000-byte banks and other "banks" are smaller (resulting in there being more than 4). The first two including ROM bank 0 and "ROM Bank 1-7F" are of course these two.

Offline

#23 2012-09-08 20:43:56

513/703

Re: Pokemon Red Sprite Decompression and Scripts

Danny-E 33 wrote:
IIMarckus wrote:

HRAM, high RAM, is the only RAM that can be accessed during a DMA transfer.

What does this mean exactly?

Here’s an explanation.. DMA (direct memory access) is a method of transferring data “all at once” instead of copying a byte at a time from one location to the other.

#24 2012-09-09 04:37:27

514/703

Re: Pokemon Red Sprite Decompression and Scripts

kkj1116 wrote:
IIMarckus wrote:

When you write to RAM location $2000, normally a meaningless procedure because that area is read-only, the MBC will intercept the instruction and page in a bank. E.g., after the following instructions:

ld a,2
ld [$2000],a

ROM bank 2 (that is, the area of ROM from $8000 to $BFFF) will be paged into RAM locations $4000 to $7FFF.

Does the MBC always intercept anything that is written to RAM's ROM bank 0?

Yes, but these may have different effects depending on location. See “Memory Bank Controllers” in pandocs.

Of course, in a game with no MBC (like Tetris), writing to $2000 will do nothing. That byte won’t be changed, because it’s still read‐only memory.

kkj1116 wrote:

Does the bank number of the desired ROM bank have to be written to $2000 in RAM?

In all the MBCs Nintendo released, the range $2000–$3FFF handles ROM banking.

#25 2012-09-10 12:50:52

FroggestSpirit
Member
Registered: 2012-03-12
Post 15/300
Website

Re: Pokemon Red Sprite Decompression and Scripts

IIMarckus wrote:

Disassemblers do exist. The catch is that disassembling is a very hard problem to solve. Programs can't tell the difference between code and data -- to them, bytes are bytes. Good disassemblers will partially emulate the processor and disassemble code as they run it, but it's still impossible to exhaust all possible code paths.

I'm currently making a GameBoy emulator for the DS to do this somewhat... Basically, as you play the game it will log addresses ran as code to a separate file (1 bit representing each byte of code) and a second file for data loaded like GFX, music, etc. (still 1 bit per byte) I figured if you play through a game, it should log enough to be able to do everything you did in game, and if a few people played through, you could probably combine the log files.


This isn't easy to say, but…
Music and ASM hacker

Offline

Board footer

Powered by FluxBB