Discussion about software development for the old-school Gameboys, ranging from the "Gray brick" to Gameboy Color
(Launched in 2008)
You are not logged in.
Hi everyone!
I'm so glad people are still coding for gb, that's insane.
Anyway, I want to display a image so I've follow the tuto perfectly: http://gbdev.gg8.se/wiki/articles/Displ … een_images
It convert my image, creat a C file and a MAP file
But I keep getting that answer from the compiler of the GBDK
ERROR: address overflow <addr 9900 >= 8000>
So I reduce the number of color from 8 to 4
Same answer
So I reduce the size of the img from 160x144 to...idk I've tried several till I reach 20x20
Same answer so here I am.
// I would like to post a picture to show you my screen but I'm still gonna figure who to do that. I'll post it later asap
Last edited by sofzilog (2018-02-16 14:23:20)
Offline
This is the image https://ibb.co/kRo6an
Top left: the compiler respond
Top right: The C file created by pcx
Bottom left: The main.c fil
Bottom right: The emulator respond
Have a nice day everyone!
Offline
You're trying to put more stuff into your ROM than is possible.
You have to start using banking and increase your ROM size.
Offline
Hey Sofzilog.
sofzilog wrote:
But I keep getting that answer from the compiler of the GBDK
ERROR: address overflow <addr 9900 >= 8000>
So, the error you're getting is because your data is taking up too much space.
There are a few ways you can go from here.
First, try making your tiles and map a const unsigned char array. This way they will be kept in ROM space only, and not copied to ram.
If that doesn't help. You will need to learn banking, and copy your tiles and/or map to separate ROM banks before loading them into VRAM.
If you are just following a tutorial and don't know about developing for GBDK otherwise, then this will probably be pretty difficult.
You can see my other thread, where I was struggling with banking. However, I did eventually figure it out, and you can search this forum for banking as well, if it turns out you need banking.
sofzilog wrote:
So I reduce the number of color from 8 to 4
The gameboy has a maximum of 8 palettes, with four colors per palette.
However, that doesn't mean you can always use all 32 (4*8) colors at once.
Some palettes will share the same colors.
sofzilog wrote:
Bottom right: The emulator respond
The reason why it gives that error is because your rom is 0 bytes! Look in your folder, you will see the rom is 0.
That's because the compiler doesn't output a rom when it errors. So no reason to test that rom!
Hope this helps,
- Greg
Offline
I've try with the const unsigned char
and....OMG it WORKS!!! (sort of)
This is the result: https://ibb.co/mCPh0n
It's kinda fucked up but I don't care, I'm like a child!
Many thanks Greg!
Sinds "const char" was the output of the pcx convertor, I wasn't gonna question that. I know so little.
I've learn the basic of C in order to code for GB and Playstation but my brain isn't design for coding
Anyway.
I'm gonna look it up, and try to figure it out.
Thanks again for your super clear and kind answer!
Offline
sofzilog wrote:
I've try with the const unsigned char
and....OMG it WORKS!!! (sort of)
This is the result: https://ibb.co/mCPh0n
It's kinda fucked up but I don't care, I'm like a child!
Many thanks Greg!
So, the reason why it looks like that, is that it's actually IMPOSSIBLE to display a full screen image on a GameBoy!
EDIT: apparently I'm wrong, see ISSOtm's post below. Huh, TIL.
I'm not sure why that tutorial implies you can, but here's the details:
Take a look at this image:
https://i.imgur.com/kGBJzZG.png
What you see is a 20 by 18 grid, which is the total number of tiles for the GameBoy screen.
Now, 20 x 18 = 360...
But there's a problem, GameBoy can only store a maximum of 256 unique tiles!
If you look closely, your image repeats after 13 rows of 20... and 13 x 20 = 260 ...
If you look even closer, the image starts repeating 5 tiles before the end of the last row. That's because it starts exactly after 256 tiles.., and the 13th row ends on tile 260.
In your code:
https://i.imgur.com/AvT0MNx.png
You can see that you load all 255 tiles, and that's the max.
Therefore, it is technically impossible to display a full screen image. Actual GameBoy games use repeating tiles to fill the background - so they can be under 256 total tiles.
Regarding the tutorial - it's a bit misleading. However, if you look at their source hamburger image:
http://gbdev.gg8.se/wiki/images/7/75/Burger1.png
(sorry don't know how to resize images on this board)
You can see that they have a transparent background!
I suspect that if you crop your image, make it a bit smaller, center it in a 160x144 image, and then make the background transparent, that program will be smart enough to fill the empty space with the same repeating empty tiles.
In this case, you may be able to get your image data, on a transparent background, down to less than 256 tiles.
Good luck, and have fun!
- Greg
Last edited by GuybrushThreepwood (2018-02-16 17:08:27)
Offline
To explain :
This error ("9800 >= 8000") means that the compiler exceeded the amount of memory a Game Boy game can have (which spans address range 0x0000 - 0x7FFF, thus 0x8000 bytes).
The reason why `const` solved your issue is that it placed the data into ROM. Here's a more detailed explanation.
When you declare an array as `const`, it is simply stored in ROM.
When you don't, the compiler instead generates a very inefficient block of instructions that set the table in RAM -- so in a way, your table is still stored in ROM, but may, WAY less efficiently. Plus, it's copied to RAM when really there's no need to.
tl;dr : use `const` whenever possible. Really.
Offline
GuybrushThreepwood wrote:
So, the reason why it looks like that, is that it's actually IMPOSSIBLE to display a full screen image on a GameBoy!
It's possible, since there are 384 tiles total, and the screen only uses 360 of them.
I'm not talking about using VRAM bank 1, either, a full-screen image can be displayed on a DMG.
Offline
ISSOtm wrote:
GuybrushThreepwood wrote:
So, the reason why it looks like that, is that it's actually IMPOSSIBLE to display a full screen image on a GameBoy!
It's possible, since there are 384 tiles total, and the screen only uses 360 of them.
I'm not talking about using VRAM bank 1, either, a full-screen image can be displayed on a DMG.
I see.
I thought the latter 128 were for sprites only, and could not be used as indices for background tiles.
And that the "middle" 128 could be shared for EITHER sprites or background tiles.
Didn't realize you could use all 384 tiles, just for background.
Either way, OP's program is only outputting 256 tiles.
Offline
There are three "blocks" of 128 tiles each.
You can either use 8000 as a base with unsigned numbering, or 9000 with signed numbering.
In either case, 8800-8FFF is mapped to tiles 128-255, but the 127 other can be either of these two blocks.
Now, sprites always use the 8000 base, and you can select either base for both BG and WIN via LCDC.
Changing the setting mid-frame lets you pulls tiles from both 8000-87FF and 9000-97FF in the same screen.
Offline
ISSOtm wrote:
Changing the setting mid-frame lets you pulls tiles from both 8000-87FF and 9000-97FF in the same screen.
Ah, so I remember finding this link, which is for GBJam, so not strictly real GB Dev (since GBJam allows games to be made for PC with modern tools, as long as they follow a specific set of GB limitations).
However, I remember this line standing out:
https://itch.io/jam/gbjam-5/topic/41384/the-actual-gb-limits wrote:
Max number of tiles in tilemap: 384 (with some nasty tricks), 256 (w/o nasty tricks)
That makes sense now.. that must be the "nasty tricks" they're referring to, haha.
However, just for curiosities sake, I'm wondering how this works? In my game I'm using the LCD vertical line interupt, however, can you also interrupt on a specific X column? I don't see anything about that. Since the max before switching mid-frame is 256, it would need to switch on the 15th tile in the 13th row...
Hmmm. I suppose you could just switch at the end of row 12, and keep the last 15 tiles in ram, and add the remaining 104 tiles. I guess I answered my own question, but maybe there's another way I'm not considering.
Anyway, thanks, this is interesting and good to know!
- Greg
Offline
ISSOtm wrote:
There are three "blocks" of 128 tiles each.
You can either use 8000 as a base with unsigned numbering, or 9000 with signed numbering.
In either case, 8800-8FFF is mapped to tiles 128-255, but the 127 other can be either of these two blocks.
Now, sprites always use the 8000 base, and you can select either base for both BG and WIN via LCDC.
Changing the setting mid-frame lets you pulls tiles from both 8000-87FF and 9000-97FF in the same screen.
Interesting idea. Is there any game or demo that actually uses that method? My impression is they always add black or white borders to large images (like in the opening scene of Link's Awakening, to name an example).
Offline
Thanks for your answers.
I've tried couple of things.
GIMP notice me transparanty not supported by the PCX format so it doesnt help to use or not transparanty
In BGB, the transparenty is replaced with white area (as you can see in this picture where I've loosely indicate it whit a red cross and a T)
https://ibb.co/cngOO7
So just to be sure, I shronk even more the picture down to 50x45 and what I realise is that when the PCX2GB do its magic, the sceen became black and the picture is converted.
But we can see the 160x40 borders I show in red here: https://ibb.co/jJt3O7
At my level of skills, I just don't know but I have like a gut feeling it's comming from the MAP file produce by the PCX2GB program.
After all, the program did produce a C file with "unsigned char" instead of "const unsigned char"
Therefore, maybe the MAP file also have some sort of problem, IDK
Or maybe it's in the main.c itself?
void main()
{
// Load up the tile data
set_bkg_data(0,255,tiledata);
// Switch to VRAM
VBK_REG = 1;
// Switch out of VRAM
VBK_REG = 0;
// Set screen x,y pos to 0,0 and draw the map 20,18(size of the screen)
set_bkg_tiles(0,0,20,18,tilemap);
// Show the background
SHOW_BKG;
// Turn the display on
DISPLAY_ON;
}
BTW Greg I've watch your FIX IT FELIX video, Brilliant!
Last edited by sofzilog (2018-02-16 19:07:14)
Offline
Jonas wrote:
ISSOtm wrote:
There are three "blocks" of 128 tiles each.
You can either use 8000 as a base with unsigned numbering, or 9000 with signed numbering.
In either case, 8800-8FFF is mapped to tiles 128-255, but the 127 other can be either of these two blocks.
Now, sprites always use the 8000 base, and you can select either base for both BG and WIN via LCDC.
Changing the setting mid-frame lets you pulls tiles from both 8000-87FF and 9000-97FF in the same screen.Interesting idea. Is there any game or demo that actually uses that method? My impression is they always add black or white borders to large images (like in the opening scene of Link's Awakening, to name an example).
I don't know of any. I would have suggested the LoZ: Oracle of * games, but since they're CGB-only, I bet they use VRA1 instead. (Which is much more convenient, since it removes the need for flipping the bit mid-frame and during VBlank)
sofzilog wrote:
At my level of skills, I just don't know but I have like a gut feeling it's comming from the MAP file produce by the PCX2GB program.
That's the issue, apparently. It re-uses some tiles, when it shouldn't. What's the array like ?
sofzilog wrote:
void main()
{
// Load up the tile data
set_bkg_data(0,255,tiledata);
// Switch to VRAM
VBK_REG = 1;
// Switch out of VRAM
VBK_REG = 0;
// Set screen x,y pos to 0,0 and draw the map 20,18(size of the screen)
set_bkg_tiles(0,0,20,18,tilemap);
// Show the background
SHOW_BKG;
// Turn the display on
DISPLAY_ON;
}
VBK_REG is useful only on the CGB. Since you're making a DMG-only game, you should remove these lines (they don't "switch in/out of VRAM", either.)
Offline
I've removed VBK_REG's lines. It doesn't solve the probleme.
I'm going to learn a bit more how GBDK fonctions works because I'm too much of a noOb
Thanks guys!
Offline
What you're looking for isn't GBDK. You need to learn about how the GB itself works.
I suggest http://gbdev.gg8.se/wiki/articles/Pan_Docs , then http://github.com/avivace/awesome-gbdev/
Last edited by ISSOtm (2018-02-17 11:10:41)
Offline
Ok I'm on it.
I'm gonna study that.
For the record, I've creat a cheezy loop to see how the picture is draw on screen
char a=1;
while (1){
set_bkg_data(0,a,tiledata);
SHOW_BKG; // Show the background
a++;
}
I know it's awfully writter but what it tell me is that the picture and his double is draw at the same time and not one after another.
I would have though it will first draw the maine picture, and then for some reason continue redrawing it bellow, but no apparantly.
See her:
https://ibb.co/muKHGS
https://ibb.co/ivzdO7
I've also play with GIMPS and increas or decreas those parameters which, according to the wiki tuto with the burger, should be set at 72.000 for x and y
https://ibb.co/mprWbS
I've also discover I can read the MAP file using text edit.
Both the C and the MAP file indicate 360 tiles, but the main.c get upset if beyond to 255. ---> set_bkg_data(0,255,tiledata);
I've tried set to tweak thoses values, not a good idea. ----> set_bkg_tiles(0,0,20,18,tilemap);
Sorry for my bad english.
Last edited by sofzilog (2018-02-17 12:40:58)
Offline
I'm not sure what exactly you want to achieve.
If your goal is to draw a fullscreen picture, you should accept that at least some of the tiles will have to repeat. With ISSOtm's concept, it's possible to draw a "real" fullscreen picture on a DMG. But with your coding skills it very probably isn't. So the easiest solution would be to create a smaller picture and add a black or white border around it to save some of the available tiles.
The pictures in your last posts look like you tried to display a smaller picture, but something is wrong with your map. Or maybe you try to load more bytes of map data to VRAM than there actually are in your array. To draw a picture of 50x45 pixels you should only need 7x6 tiles. So I wonder how large your map array actually is. Can you post what it looks like?
Offline
Thanks Jonas.
I've done that and it more or less worked. https://ibb.co/eeuFo7
I'm satisfied with that.
I didn't have a precise goal. It was already a thrill to put a "hello world" on a game boy.
I'm gonna display picture of my friends with texts like "happy birthday on gameboy".
Now I'm gonna do the same for PSone with the PSYQ which is the official SonySDK you can find on http://www.psxdev.net/
And for those who dont know, there is also a verry cool SDK for Genesis called BasiEgaXorz you can find here: http://devster.monkeeh.com/sega/basiegaxorz/
Thanks Greg, ISSOtm and Jonas!!!
Last edited by sofzilog (2018-02-18 14:12:24)
Offline
sofzilog wrote:
Thanks Jonas.
I've done that and it more or less worked. https://ibb.co/eeuFo7
Hey sofzilog. Just a quick idea: I'm pretty sure if you replace the last 20 items in your map array with 0x00, pretty sure it will get rid of that last line on the bottom.
The reason why I say is, is because your first tile: (0, 0) at the top left is solid white. So by making the last row (last 20 items) set to 0x00, it will reuse that white tile across the bottom and get rid of where the picture starts to repeat.
Anyway, good luck on your future adventures.
- Greg
Last edited by GuybrushThreepwood (2018-02-18 19:03:39)
Offline
I was skeptic because that's my 160x144 img which is white top and bottom https://ibb.co/i9YwwS
But it worked!!
So that mean, it's not the gameboy who interpret the MAP file in a weird repeating way, it's the MAP file itself who is written in a way to repeat itself....
Or maybe I'm off the rail.
One thing is still bugging me though.
How come that the creator of PCXtoGB let his program writting "unsigned char" instead of "const unsigned char"
They should had encounter the same overflow memory problem as me and yet leave it there.
Thats why I think maybe this program is a bit crazy to begin with.
Anyway, I don't have the knowledge to juge, I'm just speculating and I'm happy with the result!. Thanks Greg!
Offline
Maybe he thought the memory overflow issue could just be fixed with banking -- which isn't false, but stupid, as I explained.
Also, you shouldn't use this program. You should learn how the GB renders things, and make your own full-screen image using that knowledge. I'll be honest, that problem is trivial when you know how the GB displays things.
It's not very difficult, either. What is most difficult is to find a proper tutorial...
Offline
I will try to go deeper eventualy but I don't have what it takes to code, to realy code.
It take me a lot more time to learn thos kind of stuff, I can feel my brain telling me: "nop"
But it's not that big of a deal because I'm still amazed like a child when I watch the screen of a emulator display anything I've coded
Computers are amazing
Offline
I have read your topic but, I don't know how they show a full background picture in Donkey Kong Land as example.
Watch this screenshoot:
Last edited by Kitsune64 (2023-10-31 13:22:39)
Offline