The PokéCommunity Forums  

Go Back   The PokéCommunity Forums > Creative Discussions > Emulation & ROM Hacking > Research & Development
Sign Up Rules/FAQ Live Battle Blogs Mark Forums Read

Notices

Research & Development Got a well-founded knack with ROM hacking? Love reverse-engineering the Pokémon games? Or perhaps you love your assembly language. This is the spot for polling and gathering your ideas, and then implementing them! Share your hypothesis, get ideas from others, and collaborate to create!
New threads in this forum are to be approved by a moderator before they are displayed. The thread revival limit does not apply here.


Reply
Click here to go to the first staff post in this thread.  
Thread Tools
  #1    
Old March 23rd, 2010, 06:07 AM
Full Metal's Avatar
Full Metal
C(++) Developer.
 
Join Date: Jan 2008
Location: In my mind.
Age: 18
Gender: Male
Nature: Timid
Send a message via Windows Live Messenger to Full Metal
Warning to you wise-cracks

In no way, am i saying this is 100% accurate; I'm human, and make mistakes. You've been warned, so no flaming, just point somethin out then SHUT UP. Anyways on to the juicy stuff (i decided to start making things look professionalerer the first time so...its a bit more organized than my other threads)





Simple stuff
Terminology

Bit: The absolute smallest storage unit of data, can only be 1 (set) or 0 (unset)
Byte: 8 bits; maximum value of 0xFF (255)
Short: 2 bytes (16 bits); maximum value of 0xFFFF (65,535)
Integer: 4 bytes (32 bits); maximum value of 0xFFFFFF (4,294,967,295)
Color: err..go back to kindergarten, what are you doing here?
Palette: usually 16 or 256 colors
GBA: OK SRSLY WTF R U DOIN HERE?! (jk XD)
The gba has a screen size of 240x160 pixels.
This has the capability of having 30x20 tiles on the screen at a time.
The gba is a 16-bit color system. Meaning all the colors you have available on a computer, are not available on the GBA.

Colors
How colors are stored in the GBA vram

As previously stated, GBA colors are 16 bits a piece. Believe it or not, 1 bit is actually wasted :O.
heres how a gba color looks
[wasted bit][5 bits: Red value][5 bits: Green Value][5 bits: Blue value]
since each of the RGB values are only 5 bits long, there is a maximum of 31 value possibilities to each. You will get the closest match to the actual color, by simply multiplying those values by 8. If you are a programmer, here's how to store colors in GBA format.
#define gba(r,g,b) ( r | g<<5 | b << 10 )
If you aren't, that is simple enough, you should be able to figure it out (again, bitwise logic is needed) << means to shift left X times. Reversing that is as simple as bitshifting to the right the respective amount of times and a little bit of AND'ing to remove the other bits from the remaining colors.
The BG Palette Memory Starts at 0x5000000 and the Sprite Palette Memory starts at: 0x5000200

Un-Compressed Graphics
The Easy Stuff...

The GBA has IO2 (that i know of) different storages of graphics. Compressed, or Uncompressed. Uncompressed graphics are easier to understand. If you are in 4BPP mode, the least amount of pixels you can have is 2.
[4 bits: pixel 2 index][4 bits: pixel 1 index]
What I mean by "index" is which color value on the palette will be used. Usually, 4BPP will be used with tilemaps, but there are other cases (like sprites)
please note that 4 bits restrains you to a value of 15, which is oddly convenient...
8BPP graphics are stored similarly
[8 bits (1 byte): pixel index]
This will allow you access to all 256 colors of either the BG palette, or the Sprite Palette.

GBA Video Modes
How the gba processes the graphics

The gba has different "modes" for graphics display. How the GBA knows which mode to use, is that it reads from the address 0x4000000. That is where the screen mode, and which bg's are enabled is stored. To set the appropriate mode you need to know some bitwise logic (google it if you don't already know it)
the hex values for the different bgs being enabled are:
BG0: 0x100
BG1: 0x200
BG2: 0x400
BG3: 0x800
If sprites are also enabled, you can treat them as a BG as well. They're enabled code is 0x1000
---<bg X enabled code> do that for each bg you are enabling.
OR <Mode, simply the mode number in hex>
Spoiler:

Mode 0
--Is tiled
--All 4 "layers" are accessible
--The tilemap can be either 16 or 256 colors
--Rotation and scaling (GBA "specialty functions" only accessible through asm...) are not supported
Mode 1
--Only 3 of the four layers are available
--the third layer (which is actually layer two, because layer 0 is the first layer, i know, it's confusing)
--Always 256 colors
--A maximum of 256 tiles.
Mode 2
--Only applicable to layers 2 & 3
--supports "specialty functions"
--Only 256 colors
--Maximum of 256 tiles
Mode 3
--First "un-tiled" mode
--entire screen (layers don't "exist in this mode; there isn't enough room for more than one...)
--No palette index (uses 2 bytes per pixel)
Mode 4
--"un-tiled" (afaik, not entirely for sure though)
--only layer 2 (the third layer) is available
--supports animation (able to load up to a whole two frames at a time!--WOW xD)
--256 colors (this is an indexed mode)
Mode 5
--Really rare situations are able to use this (as in you probably will never use it)
--Only 160x128 of the gba's pixels are useable
--Layer 2 only
--All colors
--Allows for animation (AKA double buffering, which is why it has two frames, and not the entire screen)

Putting it all together
Some assembly required

To display a 240x160 256 colors image, heres what you need to do.
Store the palette in the ROM
Store the image in the ROM (using tilemoster or etc, so that it's uncompressed)
write a routine, and set the video mode to one appropriate for you (i reccomend mode 4) then add a that will enter a (i usually use C++, so try to bear with me on my terms like "loop") loop, writing the palette to the BG memory. Add another (separate) loop that will copy the bytes from your image offset into the appropriate BG memory (I challenge you to find that with nothing more than VBA, hint hint: check the "map viewer" )
add another (separate) loop. Next write a script that will fade the screen to black/other color, and call your routine (smart asm hackers obviously can call the routine through other methods, but i'm not exactly a "smart" asm hacker...still learning basics...) and voila! u see a nice pretty picture :D
...don't ask me how to return to normal play. Perhaps you could add a "waitforkeypress" to your script, then fade to black (yes, again) then fade from black to normal play. Or maybe you could loop in your routine (after displaying loading palette and pixels) and when a button is pushed the script would continue, which you could just fade into normal play from there. I dont' know branching and whatnot yet, so I can't post an example routine right nao...maybe i still wont' to help inspire others who dont know how either...

Tiles and their maps
Not alot to say...

Well, theres not a lot to these, especially since we have NTME and Cyclone, and PTC (lol, theres' so many...)
simple.
A tile: 8x8 block of pixels
Tilemap: a series of shorts describing which tile goes where on the GBA screen
I'm not going to touch on how to load tilemaps, its' a bit much for me to type out at 11:23 pm...

Tile Insertion
almost a little rant

Ok, so you have this nice set of tiles you'd like to insert right?
But holy shiz! ITS FRIGGIN HUGE!
Have no fear, this tutorial is here!
What I see a lot of is people getting the mis-understanding that tiles you insert have to be as you see them in the map; this is a lie. First let me explain to you what a "block" and a "map" are.
Block: a 2x2 set of tiles, with two layers.
Map: a bunch of tiles, with movement permissions, and events.
Tileset: a bunch of blocks.

So rather than have a 16x16 tile pasted into your tileset, and wasting space (assuming they're identical) you can break it down into perfect 8x8 tiles

How to do this?
well, you could just jump into sphere and convert it...but that could turn out disastrous.

First you need to gather all the tiles you want to insert, that share the same palette.

Open up paint, and paste all the tiles you want in there.
Fill the BG (your going to be indexing this, so be sure not to miss anything) with a transparent color (you want it to be completely unique, so using the paint default colors is perfectly exceptional. Ensure that the bottom-left pixel is the transparent color, and save as a un-indexed bitmap file.
Open up the saved file in irfanview, and index it into 16 colors. Save again (still bitmap format)


download and, maybe, install the GTK+ runtime, the tool "Full Metal Paletted" from here


once that's done, run the program. Click on the 4BPP bitmap option, and load the file from previous steps.
Then click on the save a-map palette button, and save the advance map palette. Open a-map, load your rom, go to a map with the right tileset and load block editor.

Choose the palette to replace, and load it from file (choose the file we saved in with palette editor).

Now comes the tile insertion part.
Open up each individual tile, and make sure it aligns with a pixel spot that, if added by one, is divisible by 8 (if the first pixel on the left is 0) and also make sure the same is true vertically. Save your image. Open up sphere, import->image to map and open the image we previously saved. Set the block size to 8x8 and click yes when it asks to remove duplicate tiles grab the tileset saved with sphere and save it. Open that up in paint, and copy it. Then go back to a-map, and save your tileset (with the palette you want to use). Open up your tileset with pain, paste your clipboard wherever it fits, and load the tileset again with amap. This is important, if you clicked "Write Palette Changes to ROM" then you'll have to load your palette again (from file) and then load your tileset, i'll explain why later. If you didn't click "Write Palette Changes to ROM" then you are good to go, load the tileset, and NOW click "write palette changes to ROM" and may begin block editing read some other tile insertion tutorial to learn how to do that...
So why can't you click "write palette changes to ROM"?
Every tileset image is stored with a .pal file right next to it. The .pal file has all the colors used in your palette, which is how A-map knows which pixel to put where, without using indexed bitmaps. If you have a pixel on your bitmap, that is not in your .pal file, then your tileset, when loaded, will not load the colors right, unless by some unlikely chance, all the colors are divisible by 8 and less than 248. So...why can't we click that button? Because when you do, a-map looses the original colors, and converts them to colors that are GBA compatible (divisible by 8 and less than 248) so when you save the tileset, the colors in the .pal file will NOT match the colors of the content in your clipboard.
__________________

★ full metal.

I like to push it,
and push it,
until my luck is over.

Last edited by Full Metal; March 30th, 2010 at 04:03 PM. Reason: lol...read 3rd post...FAIL on me XD
Reply With Quote
  #2    
Old March 26th, 2010, 06:50 PM
colcolstyles's Avatar
colcolstyles
Yours truly
 
Join Date: May 2008
Location: The Bay Area
Gender: Male
Nature: Lonely
Okay. How about explaining how a hacker might utilize this information? For example, where in the RAM does it say what mode is currently being used? How would one switch between different modes? Frankly, I don't think that there would be many uses for any mode other than Mode 0 in a Pokémon hack but I'm sure somebody out there could think of something.

It's a nice start but I can't really think of any practical applications for this information. I think you'd be better off explaining the ins and outs of the VRAM and the registers involved with the various Backgrounds.
__________________

Brother of Vrai
Reply With Quote
  #3    
Old March 26th, 2010, 07:26 PM
Full Metal's Avatar
Full Metal
C(++) Developer.
 
Join Date: Jan 2008
Location: In my mind.
Age: 18
Gender: Male
Nature: Timid
Send a message via Windows Live Messenger to Full Metal
gyahh! I didn't realize i posted this thats why its so incomplete --sorry guys XD
thanks for the quick response though colcolstyles
will do what you suggested (i originally planned too...>_< silly post button)
*edit* howzat fur ya?
__________________

★ full metal.

I like to push it,
and push it,
until my luck is over.

Last edited by Full Metal; March 26th, 2010 at 08:16 PM.
Reply With Quote
  #4    
Old March 26th, 2010, 08:53 PM
Darthatron's Avatar
Darthatron
巨大なトロール。
 
Join Date: Jan 2006
Location: Melbourne, Australia
Age: 22
Gender: Male
Nature: Modest
I recommend making the layout a little cleaner. But overall, it's a pretty nice document. But... elaborate some more.
__________________
あなた は しきしゃ です
わたし は ばか です
Reply With Quote
  #5    
Old March 30th, 2010, 04:04 PM
Full Metal's Avatar
Full Metal
C(++) Developer.
 
Join Date: Jan 2008
Location: In my mind.
Age: 18
Gender: Male
Nature: Timid
Send a message via Windows Live Messenger to Full Metal
*bump*
it's been updated with tile-insertion, and a css layout...
__________________

★ full metal.

I like to push it,
and push it,
until my luck is over.
Reply With Quote
  #6    
Old April 1st, 2010, 02:36 AM
Giga Universe's Avatar
Giga Universe
Working on a tool.
 
Join Date: Aug 2007
Location: South Africa
Age: 19
Gender: Male
Nature: Calm
Send a message via ICQ to Giga Universe Send a message via AIM to Giga Universe Send a message via Yahoo to Giga Universe Send a message via Skype™ to Giga Universe
Shouldn't you have explained how to use the I/O register at 0x4000000 properly? All you gave were some hex values for enabling the modes. Shouldn't you at least link to something like GBATek that shows what the individual bits do? Like Here? Maybe explain it it more detail though, because some people might not understand that it works in binary or something.

EDIT: And aren't colours stored in the PALETTE RAM, not the VRAM? Theres a mistake in your tutorial saying it's VRAM (In the heading under colours)
__________________

Last edited by Giga Universe; April 1st, 2010 at 02:58 AM.
Reply With Quote
  #7    
Old April 1st, 2010, 04:05 AM
Full Metal's Avatar
Full Metal
C(++) Developer.
 
Join Date: Jan 2008
Location: In my mind.
Age: 18
Gender: Male
Nature: Timid
Send a message via Windows Live Messenger to Full Metal
well...i kinda considered it part of VRAM because you can change what's on the screen just by modifying that...
it told them how to use those codes ?
all they need to do is OR it with the bg's needed, and then write the value to memory
__________________

★ full metal.

I like to push it,
and push it,
until my luck is over.
Reply With Quote
  #8    
Old April 1st, 2010, 06:08 AM
Giga Universe's Avatar
Giga Universe
Working on a tool.
 
Join Date: Aug 2007
Location: South Africa
Age: 19
Gender: Male
Nature: Calm
Send a message via ICQ to Giga Universe Send a message via AIM to Giga Universe Send a message via Yahoo to Giga Universe Send a message via Skype™ to Giga Universe
Well I'm going to attempt to work on some ASM today to get this working. Any ideas on how to get the routine to get pointers to the palette and image data?
__________________

Last edited by Giga Universe; April 1st, 2010 at 06:39 AM.
Reply With Quote
  #9    
Old April 1st, 2010, 12:20 PM
Full Metal's Avatar
Full Metal
C(++) Developer.
 
Join Date: Jan 2008
Location: In my mind.
Age: 18
Gender: Male
Nature: Timid
Send a message via Windows Live Messenger to Full Metal
er the palette data is at the very beginning of the vram if i remember right (0x500000)
__________________

★ full metal.

I like to push it,
and push it,
until my luck is over.
Reply With Quote
  #10    
Old April 1st, 2010, 01:03 PM
colcolstyles's Avatar
colcolstyles
Yours truly
 
Join Date: May 2008
Location: The Bay Area
Gender: Male
Nature: Lonely
Quote:
Originally Posted by Full Metal View Post
er the palette data is at the very beginning of the vram if i remember right (0x500000)
No the VRAM is at 0x0600:0000. The Palette Memory is at 0x0500:0000 but it's completely separate from the VRAM. However, seeing how this is in a ROM Hacking forum, telling us where the palettes are stored is only a step towards hacking the palettes. You'll find very quickly that simply writing to the Palette Memory won't change the palettes. The reason why you can't is something that I think belongs in this tutorial. I'll let you figure it out.
__________________

Brother of Vrai
Reply With Quote
  #11    
Old April 1st, 2010, 03:20 PM
Full Metal's Avatar
Full Metal
C(++) Developer.
 
Join Date: Jan 2008
Location: In my mind.
Age: 18
Gender: Male
Nature: Timid
Send a message via Windows Live Messenger to Full Metal
mkay....
Spoiler:

#include "beach.h"
#define screenmem 0x*^=-_ //I don't remember the exact spot aotm...i should prob add to teh tut...
#define bgmode 0x4000000
int main()
{
unsigned short* bgenable=bgmode;
*bgenable= (0x100)|(0x4); //Enable the background 0, in mode 4
unsigned int screen = 0x0; //Will be using in loops
unsigned short* palette=0x05000000; //Pointer to the palette data
unsigned char* screendata=screenmem; //Pointer to the screen data
for (;screen<=16*256;screen++) /*Until all the colors in the pallette memory have been filled in (16*256) with the following code, this code will continue to be executed */
{
*palette=beach_pal_data[screen]; //What is pointed at by "palette" becomes the value in "beach_pal_data[screen]"
palette+=2; //Increment our pointer to avoid re-writing the same color over and over again
}
for(screen=0x0;screen<=240x160;screen++)/*Reset the loop variable, until all pixels have been written on, this code will continue...*/
{
*screendata=beach_pic_data[screen]; //Look at the above for loop
screendata++;
}
return 0;
}

That is a C example of loading and displaying an image in the GBA. Download gba dev kit advance, create a file named "beach.pcx" drag and drop onto a program called "pcxtogba", then compile the code. Ill edit this and first post with an asm routine (if i can do one that is...) in just a minute....
*edit*
well, thanks to foofatron's documentation, i've found out where i can write to to change the palettes. Now i have a question for ya; What causes the writes i make in memory viewer to get overwritten? Is it because that's not legal to do in GBA?or is it because FireRed is doing something. I've opened up the disassembler in VBA, and i find the almost offset of where the palette's that work are being referenced frequently, so I think that it may be firered's doing....but you seem to know, so i thought i would ask.
__________________

★ full metal.

I like to push it,
and push it,
until my luck is over.

Last edited by Full Metal; April 1st, 2010 at 04:31 PM.
Reply With Quote
  #12    
Old April 2nd, 2010, 02:18 AM
Giga Universe's Avatar
Giga Universe
Working on a tool.
 
Join Date: Aug 2007
Location: South Africa
Age: 19
Gender: Male
Nature: Calm
Send a message via ICQ to Giga Universe Send a message via AIM to Giga Universe Send a message via Yahoo to Giga Universe Send a message via Skype™ to Giga Universe
I originally thought the same thing, but that is wrong. In order to write to VRAM, PALETTE RAM or OAM, you need to request a "blank" (or force it). This can be done by writing a 1 to the 8th bit at 0x04000000. You'll have to turn it off again after you've finished the write. Also, I have (sorta) figured out how to use the BIOS function for uncompressing LZ77 compressed data. It allows you to write a source location, then an output location for the data, and then will automatically decompress it for you.
__________________
Reply With Quote
  #13    
Old April 2nd, 2010, 04:43 AM
Full Metal's Avatar
Full Metal
C(++) Developer.
 
Join Date: Jan 2008
Location: In my mind.
Age: 18
Gender: Male
Nature: Timid
Send a message via Windows Live Messenger to Full Metal
hmmm....thanks GU
ima already trying to figure out lZSS though...
__________________

★ full metal.

I like to push it,
and push it,
until my luck is over.
Reply With Quote
  #14    
Old April 2nd, 2010, 04:47 PM
colcolstyles's Avatar
colcolstyles
Yours truly
 
Join Date: May 2008
Location: The Bay Area
Gender: Male
Nature: Lonely
Quote:
Originally Posted by Giga Universe View Post
I originally thought the same thing, but that is wrong. In order to write to VRAM, PALETTE RAM or OAM, you need to request a "blank" (or force it). This can be done by writing a 1 to the 8th bit at 0x04000000. You'll have to turn it off again after you've finished the write. Also, I have (sorta) figured out how to use the BIOS function for uncompressing LZ77 compressed data. It allows you to write a source location, then an output location for the data, and then will automatically decompress it for you.
I wasn't aware of that and yet I've been able to write to the VRAM just fine. o_O
__________________

Brother of Vrai
Reply With Quote
  #15    
Old April 2nd, 2010, 05:02 PM
Darthatron's Avatar
Darthatron
巨大なトロール。
 
Join Date: Jan 2006
Location: Melbourne, Australia
Age: 22
Gender: Male
Nature: Modest
Quote:
Originally Posted by GBAtek
SWI 11h (GBA/NDS7/NDS9) - LZ77UnCompWram
SWI 12h (GBA/NDS7/NDS9) - LZ77UnCompVram (NDS: with Callback)
Expands LZ77-compressed data. The Wram function is faster, and writes in units of 8bits. For the Vram function the destination must be halfword aligned, data is written in units of 16bits.
If the size of the compressed data is not a multiple of 4, please adjust it as much as possible by padding with 0. Align the source address to a 4-Byte boundary.

Code:
  r0   Source address, pointing to data as such:
        Data header (32bit)
          Bit 0-3   Reserved
          Bit 4-7   Compressed type (must be 1 for LZ77)
          Bit 8-31  Size of decompressed data
        Repeat below. Each Flag Byte followed by eight Blocks.
        Flag data (8bit)
          Bit 0-7   Type Flags for next 8 Blocks, MSB first
        Block Type 0 - Uncompressed - Copy 1 Byte from Source to Dest
          Bit 0-7   One data byte to be copied to dest
        Block Type 1 - Compressed - Copy N+3 Bytes from Dest-Disp-1 to Dest
          Bit 0-3   Disp MSBs
          Bit 4-7   Number of bytes to copy (minus 3)
          Bit 8-15  Disp LSBs
  r1   Destination address
  r2  Callback parameter (NDS SWI 12h only, see Callback notes below)
  r3  Callback structure (NDS SWI 12h only, see Callback notes below)
http://nocash.emubase.de/gbatek.htm#...ssionfunctions
Quote:
Originally Posted by Giga Universe View Post
I originally thought the same thing, but that is wrong. In order to write to VRAM, PALETTE RAM or OAM, you need to request a "blank" (or force it). This can be done by writing a 1 to the 8th bit at 0x04000000. You'll have to turn it off again after you've finished the write. Also, I have (sorta) figured out how to use the BIOS function for uncompressing LZ77 compressed data. It allows you to write a source location, then an output location for the data, and then will automatically decompress it for you.
I'm fairly sure that doesn't apply to VRAM. I write to that fine, all of the time.
__________________
あなた は しきしゃ です
わたし は ばか です
Reply With Quote
  #16    
Old April 2nd, 2010, 06:02 PM
Full Metal's Avatar
Full Metal
C(++) Developer.
 
Join Date: Jan 2008
Location: In my mind.
Age: 18
Gender: Male
Nature: Timid
Send a message via Windows Live Messenger to Full Metal
Quote:
Originally Posted by colcolstyles View Post
I wasn't aware of that and yet I've been able to write to the VRAM just fine.
he's definitely on to something
if you go to the 04 (multiple 0's)
you'll see a XX40 or XX80
when it's 04, that means you are able to edit the palette memory and what not.
if it's anything other than that, then you can't.
Atleast, that was my experience.
and happy day : i finally used the "disassembler" with VBA.
__________________

★ full metal.

I like to push it,
and push it,
until my luck is over.
Reply With Quote
  #17    
Old April 4th, 2010, 10:05 AM
Giga Universe's Avatar
Giga Universe
Working on a tool.
 
Join Date: Aug 2007
Location: South Africa
Age: 19
Gender: Male
Nature: Calm
Send a message via ICQ to Giga Universe Send a message via AIM to Giga Universe Send a message via Yahoo to Giga Universe Send a message via Skype™ to Giga Universe
Quote:
Originally Posted by colcolstyles View Post
I wasn't aware of that and yet I've been able to write to the VRAM just fine.
Quote:
Originally Posted by Darthatron View Post
http://nocash.emubase.de/gbatek.htm#...ssionfunctions

I'm fairly sure that doesn't apply to VRAM. I write to that fine, all of the time.
Strange... In my asm routines attempting to display images, I did not get any success until I set that byte. Thanks for the link, I was already aware of that. What I meant was that I still hadn't had any success to display an Image, therefore I would not have any success with a compressed Image. However, that bit DOES enable extremely fast VRAM editing if I'm not mistaken. So even if its not required to be set, It should speed things up.
__________________
Reply With Quote
  #18    
Old April 4th, 2010, 02:02 PM
Full Metal's Avatar
Full Metal
C(++) Developer.
 
Join Date: Jan 2008
Location: In my mind.
Age: 18
Gender: Male
Nature: Timid
Send a message via Windows Live Messenger to Full Metal
Which would mean that it's FireRed doing the over-writing, not the GBA right?
__________________

★ full metal.

I like to push it,
and push it,
until my luck is over.
Reply With Quote
  #19    
Old April 4th, 2010, 02:38 PM
colcolstyles's Avatar
colcolstyles
Yours truly
 
Join Date: May 2008
Location: The Bay Area
Gender: Male
Nature: Lonely
Quote:
Originally Posted by Full Metal View Post
Which would mean that it's FireRed doing the over-writing, not the GBA right?
If you're referring to the palettes, then yes that's right.
__________________

Brother of Vrai
Reply With Quote
Reply
Quick Reply

Sponsored Links


Thread Tools

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
Minimum Characters Per Post: 25



All times are UTC -8. The time now is 12:48 AM.


Style by Nymphadora, artwork by Sa-Dui.
Like our Facebook Page Follow us on Twitter © 2002 - 2014 The PokéCommunity™, pokecommunity.com.
Pokémon characters and images belong to The Pokémon Company International and Nintendo. This website is in no way affiliated with or endorsed by Nintendo, Creatures, GAMEFREAK, The Pokémon Company or The Pokémon Company International. We just love Pokémon.
All forum styles, their images (unless noted otherwise) and site designs are © 2002 - 2014 The PokéCommunity / PokéCommunity.com.
PokéCommunity™ is a trademark of The PokéCommunity. All rights reserved. Sponsor advertisements do not imply our endorsement of that product or service. User generated content remains the property of its creator.