Gameboy Development Forum

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.

Ads

#1 2018-08-23 04:35:01

CatDadJynx
Member
Registered: 2018-08-23
Posts: 15

New to GB development (but not to c), first question, about sprites...

Hey everyone. As the title says, I'm new to Gameboy development (but not c), and I'm having a hard time figuring out sprite animation here.

As far as I've made it, I've found this wonderful tutorial here: http://gbdev.gg8.se/wiki/articles/GBDK_Sprite_Tutorial

And I've managed to create a sprite (with multiple frames), and insert and compile this sprite into a standalone Gameboy file. However, the example used in the tutorial is only a two-frame sprite, animated on the right half, but mine is for a character walking and uses the left half as well (and a total of four frames).

Currently, my code is as follows:

#include <gb/gb.h>
#include "CharacterTestSprite.c"

void main(){
    SPRITES_8x16;
    set_sprite_data(0, 8, CharacterTestSprite);
    set_sprite_tile(0, 0);
    move_sprite(0, 75, 75);
    set_sprite_tile(1, 2);
    move_sprite(1, 75 + 8, 75);
    SHOW_SPRITES;

    while(1){
        set_sprite_tile(1, 6);
        delay(500);
        set_sprite_tile(1,2);
        delay(500);
    }
}


I am also using the BGB emulator (with vram viewer open) but for some reason i just can't seem to follow the tutorial as far as what frame is where, so I'm having difficulty figuring out what to insert for additional frames for the other half.

Thanks!

Last edited by CatDadJynx (2018-08-23 04:36:29)

Offline

 

#2 2018-08-23 06:43:45

gbjosh
Member
From: KY
Registered: 2016-06-15
Posts: 51

Re: New to GB development (but not to c), first question, about sprites...

Hi CatDadJynx,

In your code you have two sprites 0 and 1. You set what the sprites look like with set_sprite_tile(number of the sprite, number of tile). You're animating the right side (sprite 1) by changing the sprite tile in your while loop. If you wanted to animate the other side you can change the tile by using set_sprite_tile(0, number of tile). You don't always have to use set_sprite_tile for animation as there are other ways such as set_sprite_prop's FLIP_X http://gbdk.sourceforge.net/doc/html/c0504.html . The VRAM viewer in BGB will show you what tiles are being used currently so you should see whatever tile is being used highlighted as it changes with set_sprite_tile.

Last edited by gbjosh (2018-08-23 08:12:41)

Offline

 

#3 2018-08-23 06:58:50

CatDadJynx
Member
Registered: 2018-08-23
Posts: 15

Re: New to GB development (but not to c), first question, about sprites...

Ohhh, awesome, now I see just what you mean! Thanks a lot 😊

Last edited by CatDadJynx (2018-08-23 06:59:19)

Offline

 

#4 2018-08-23 23:52:20

CatDadJynx
Member
Registered: 2018-08-23
Posts: 15

Re: New to GB development (but not to c), first question, about sprites...

Alright, so I still seem to be having trouble with this. Now my code is as follows:

#include <gb/gb.h>
#include "PlayerTestSprite.c"

void main(){
    SPRITES_8x16;
    set_sprite_data(0, 8, PlayerTestSprite);
    set_sprite_tile(0, 0); //number of the sprite, number of tile. 0 is left side, 0 is frame 1
    move_sprite(0, 75, 75);
    set_sprite_tile(1, 2); //number of the sprite, number of tile. 1 is right side, 2 is frame 2
    move_sprite(1, 75 + 8, 75);
    SHOW_SPRITES;

    while(1){
        set_sprite_tile(1, 6);
        delay(500);
        set_sprite_tile(1,2);
        delay(500);
        set_sprite_tile(0,0);
        delay(500);
        set_sprite_tile(0,5);
        delay(500);
    }
}





I can see pretty clearly that the delays are working, however its now still only animating the right half. I also tried 3 in place of 5 in case i was just using the wrong frame, but the left side remains unchanged (aside from the additional delays).

Offline

 

#5 2018-08-25 00:36:46

CatDadJynx
Member
Registered: 2018-08-23
Posts: 15

Re: New to GB development (but not to c), first question, about sprites...

Also, because someone messaged me and asked to see it, here is the contents of my PlayerTestSprite file:



/*

PLAYERTESTSPRITE.C

Tile Source File.

Info:
  Form                 : All tiles as one unit.
  Format               : Gameboy 4 color.
  Compression          : None.
  Counter              : None.
  Tile size            : 16 x 16
  Tiles                : 0 to 3

  Palette colors       : None.
  SGB Palette          : None.
  CGB Palette          : None.

  Convert to metatiles : No.

This file was generated by GBTD v2.2

*/

/* Start of tile array. */
unsigned char PlayerTestSprite[] =
{
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x07,0x07,0x08,0x0F,0x0F,0x0A,
  0x0F,0x08,0x07,0x05,0x0B,0x0B,0x02,0x02,
  0x02,0x02,0x02,0x02,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0xC0,0xC0,0x20,0xE0,0xE0,0xA0,
  0xE0,0x20,0xC0,0x40,0xA0,0xA0,0x80,0x80,
  0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x07,0x07,0x08,0x0F,0x0F,0x0A,
  0x0F,0x08,0x07,0x05,0x0B,0x0B,0x02,0x02,
  0x02,0x02,0x02,0x02,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0xC0,0xC0,0x20,0xE0,0xE0,0xA0,
  0xE0,0x20,0xC0,0x40,0xA0,0xA0,0x80,0x80,
  0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x07,0x07,0x08,0x0F,0x0F,0x0A,
  0x0F,0x08,0x07,0x05,0x0B,0x0B,0x02,0x02,
  0x02,0x02,0x02,0x02,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0xC0,0xC0,0x20,0xE0,0xE0,0xA0,
  0xE0,0x20,0xC0,0x40,0xA0,0xA0,0x80,0x80,
  0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x07,0x07,0x08,0x0F,0x0F,0x0A,
  0x0F,0x08,0x07,0x05,0x0B,0x0B,0x02,0x02,
  0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0xC0,0xC0,0x20,0xE0,0xE0,0xA0,
  0xE0,0x20,0xC0,0x40,0xA0,0xA0,0x80,0x80,
  0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00
};

/* End of PLAYERTESTSPRITE.C */

Offline

 

#6 2018-08-25 11:38:36

ssjason123
Member
Registered: 2017-03-21
Posts: 45

Re: New to GB development (but not to c), first question, about sprites...

The data for sprite 0 and sprite 5 look identical. It sounds like its animating but there is no change in the sprite. Here is what i was looking at:

16 bytes per tile:
2 tiles for 8x16 sprite mode. The lowest bit is ignored for the first tile and the second tile OR's 0x01 for the second.

tiles 0 and 1:
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x07,0x07,0x08,0x0F,0x0F,0x0A,

  0x0F,0x08,0x07,0x05,0x0B,0x0B,0x02,0x02,
  0x02,0x02,0x02,0x02,0x00,0x00,0x00,0x00,

tiles 4 and 5:
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x07,0x07,0x08,0x0F,0x0F,0x0A,

  0x0F,0x08,0x07,0x05,0x0B,0x0B,0x02,0x02,
  0x02,0x02,0x02,0x02,0x00,0x00,0x00,0x00,

It also looks like you are loading in only half of the tiles with set_sprite_data(0, 8, PlayerTestSprite);. My guess is you need to double your tile count and indices to get your expected animation.

Offline

 

#7 2018-08-25 13:14:57

CatDadJynx
Member
Registered: 2018-08-23
Posts: 15

Re: New to GB development (but not to c), first question, about sprites...

Ah, okay, now I see what you mean. I'm still not entirely sure I follow, so apologies for my ignorance, but does this mean I should change it to set_sprite_data(0,16,PlayerTestSprite);?

And as for indices, I'm.not sure what you mean there. Sorry for such beginner questions, I just don't quite understand how this works (yet). Thanks!

Offline

 

#8 2018-08-25 13:21:37

CatDadJynx
Member
Registered: 2018-08-23
Posts: 15

Re: New to GB development (but not to c), first question, about sprites...

Also, part of my sprite is meant to look the same, as it's a character walking, so the first and middle animation should be the same (I'm sure there are other ways to do this to save memory, I'm just trying to get the fundamentals down first).

Offline

 

#9 2018-08-25 13:43:38

ssjason123
Member
Registered: 2017-03-21
Posts: 45

Re: New to GB development (but not to c), first question, about sprites...

After looking at it a bit more it looks like all of the 16x16 blocks are the same. You might want to double check your sprites in the GBTD:

One
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x07,0x07,0x08,0x0F,0x0F,0x0A,

  0x0F,0x08,0x07,0x05,0x0B,0x0B,0x02,0x02,
  0x02,0x02,0x02,0x02,0x00,0x00,0x00,0x00,

  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0xC0,0xC0,0x20,0xE0,0xE0,0xA0,

  0xE0,0x20,0xC0,0x40,0xA0,0xA0,0x80,0x80,
  0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,
 

Two
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x07,0x07,0x08,0x0F,0x0F,0x0A,

  0x0F,0x08,0x07,0x05,0x0B,0x0B,0x02,0x02,
  0x02,0x02,0x02,0x02,0x00,0x00,0x00,0x00,

  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0xC0,0xC0,0x20,0xE0,0xE0,0xA0,

  0xE0,0x20,0xC0,0x40,0xA0,0xA0,0x80,0x80,
  0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,



Three:
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x07,0x07,0x08,0x0F,0x0F,0x0A,

  0x0F,0x08,0x07,0x05,0x0B,0x0B,0x02,0x02,
  0x02,0x02,0x02,0x02,0x00,0x00,0x00,0x00,


  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0xC0,0xC0,0x20,0xE0,0xE0,0xA0,

  0xE0,0x20,0xC0,0x40,0xA0,0xA0,0x80,0x80,
  0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,


Four:
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x07,0x07,0x08,0x0F,0x0F,0x0A,

  0x0F,0x08,0x07,0x05,0x0B,0x0B,0x02,0x02,
  0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x00,

  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0xC0,0xC0,0x20,0xE0,0xE0,0xA0,

  0xE0,0x20,0xC0,0x40,0xA0,0xA0,0x80,0x80,
  0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00


To answer your question. Yeah, it should be set_sprite_data (0, 16, PlayerTestSprite); to load all the tile data.

From the GBTD header comment it looks like the tile data is in 16 x 16 format. So the first full tile is going to be 4 16 byte blocks:

Tile 0:
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x07,0x07,0x08,0x0F,0x0F,0x0A,
Tile 1:
  0x0F,0x08,0x07,0x05,0x0B,0x0B,0x02,0x02,
  0x02,0x02,0x02,0x02,0x00,0x00,0x00,0x00,
Tile 2:
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0xC0,0xC0,0x20,0xE0,0xE0,0xA0,
Tile 3:
  0xE0,0x20,0xC0,0x40,0xA0,0xA0,0x80,0x80,
  0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,

The second argument in set_sprite_tile is just the tile number above. 8x16 uses adjacent tiles using the logic I mentioned in the previous post where the first (top) tile will ignore the low bit and the next tile (bottom) will be your argument value OR'd with 0x01. So even numbers for the top odd numbers on bottom. It looks like you have 4 frames of tile data. First is tiles 0-3 (left 0, right 2), second 4-7 (left 4, right 6), third 8-11 (left 8, right 10) and fourth 12-15 (left 12, right 14).


Edit:
It looks like there is only a small difference in the tile data. It looks like only tile 3 and 7 are different all the rest look like they are the same.

Last edited by ssjason123 (2018-08-25 13:47:11)

Offline

 

#10 2018-08-25 14:12:31

CatDadJynx
Member
Registered: 2018-08-23
Posts: 15

Re: New to GB development (but not to c), first question, about sprites...

Oh alright, thanks for clarifying. Definitely still confused though haha, sorry! I'm not sure how to verify I've exported it correctly in the GBTD, but if you're saying there are only three different tiles in total (2 different and the rest the same) then that would lead me to believe it was exported correctly as two of the animations are the same and two are different (right foot, no step, left foot, no step in my animation). But at this point I think I'm even more lost -_- I'm sorry

Offline

 

#11 2018-08-25 14:17:27

CatDadJynx
Member
Registered: 2018-08-23
Posts: 15

Re: New to GB development (but not to c), first question, about sprites...

Actually, I think I see what you mean now (somewhat) in that the 4 16 bit blocks are one tile for each quadrant (top left, top right, bottom left, bottom right), and the 16 bits can be counted by the bit addresses in each. So is each tile set (for all four quadrants) represented by 0-3, 4-7, 8-11, and 12-15? Or am I just confusing myself more?

Offline

 

#12 2018-08-25 14:24:30

ssjason123
Member
Registered: 2017-03-21
Posts: 45

Re: New to GB development (but not to c), first question, about sprites...

You got it. One minor correction though the tile quadrant order is top left (0), bottom left (1), top right (2), bottom right(3).

Offline

 

#13 2018-08-25 14:34:42

CatDadJynx
Member
Registered: 2018-08-23
Posts: 15

Re: New to GB development (but not to c), first question, about sprites...

Awesome, thanks! Yeah, before I saw your most recent reply i very nearly got it working, only instead of alternating between left and right steps, my character lifts one leg, then the other, then puts his one leg back down, then puts the other back down (if you can imagine how silly this looks). But I've also been up all night so my brain is kind of fried, now that I know I'm on the right track I'll revisit once I'm nice and refreshed. Thanks so much for the help! 😊

Offline

 

#14 2018-08-25 14:41:03

ssjason123
Member
Registered: 2017-03-21
Posts: 45

Re: New to GB development (but not to c), first question, about sprites...

Nice, it sounds like you might just need to remove the delay between each side of the sprite. So that it updates both left and right then does the delay.

Offline

 

#15 2018-08-25 15:15:50

CatDadJynx
Member
Registered: 2018-08-23
Posts: 15

Re: New to GB development (but not to c), first question, about sprites...

Actually, I fixed it in like two seconds, all I had to do was move one line of code (and the accompanying delay) below another line, so the animation was happening in the proper order. Its a little slow so Ill just have to shorten the delays, but here is my working code:


#include <gb/gb.h>
#include "PlayerTestSprite.c"

void main(){
    SPRITES_8x16;
    set_sprite_data(0, 16, PlayerTestSprite);
    set_sprite_tile(0, 0);
    move_sprite(0, 75, 75);
    set_sprite_tile(1, 2);
    move_sprite(1, 75 + 8, 75);
    SHOW_SPRITES;

    while(1){
        set_sprite_tile(1, 6);
        delay(500);
        set_sprite_tile(1,2);
        delay(500);
        set_sprite_tile(0,12);
        delay(500);
        set_sprite_tile(0,0);
        delay(500);
    }
}




Thanks so much for the help, again! Next is to make a walking sprite facing left/right (which will require me to animate all four parts at the same time, fully implementing this newfound knowledge), but ill leave that for another time, and hopefully that should be sufficient information i can do that on my own. Thanks again, much appreciated!

Offline

 

#16 2018-08-26 23:33:20

CatDadJynx
Member
Registered: 2018-08-23
Posts: 15

Re: New to GB development (but not to c), first question, about sprites...

Soooo, it seems in my excitement I got a bit too ahead of myself tongue the code I posted above still works, however I realized that the numbers I put in didnt correspond with what you mentioned (and what id read in a tutorial somewhere), as in to make it successfully worked I had it alternate between 0,0 and 0,12 which should have been the top left quadrant, right? Although this works for me to animate a forward and back facing character sprite, now I need to make one facing left (then right) which would require me to animate all four parts at once, so now Im a little lost again as far as what Im looking at. Sorry! -_-

Offline

 

#17 2018-08-27 10:09:44

ssjason123
Member
Registered: 2017-03-21
Posts: 45

Re: New to GB development (but not to c), first question, about sprites...

So your overall sprite object is composed of two 8x16 sprite objects. In your code you have been updating one half delaying then updating the other half. Normally you would update both half's at the same time to play the entire frame of animation. The best advice i can give is to look at the VRAM Viewer in BGB. Specifically the OAM tab, this is going to show all of the sprite objects and the tiles in VRAM that they map to. You should be able to use that to get a visual layout to better understand how the tiles are being stored and looked up.

Offline

 

#18 2018-08-27 18:56:59

CatDadJynx
Member
Registered: 2018-08-23
Posts: 15

Re: New to GB development (but not to c), first question, about sprites...

Oh alright, thanks! Yeah, I've been using the vram viewer every step of the way, just been having a hard time correlating that with what is happening in the code, or how to change the code accordingly. But now that you mention it, if it's just doing it in halves (I was mistaken thinking it changed quadrants individually), then I might just need to remove a couple delays for it to synch up correctly, and/or maybe change the frame number. Will tool around with it a bit and post an update with the results. Thanks!

Offline

 

#19 2018-08-27 19:18:06

ssjason123
Member
Registered: 2017-03-21
Posts: 45

Re: New to GB development (but not to c), first question, about sprites...

In the OAM tab of the VRAM viewer it has some really nice visualization tools to highlight the sprites and where they are on screen if you mouse over an OAM entry or mouse over a sprite in the screen snapshot. The little details box will tell you the Tile number in the Tiles table which will match up to the second argument in your set_sprite_tile calls. Then you can use the Tiles tab to see how your tiles are loading into VRAM (the set_sprite_data call) and find the tile number that you want to be using.

Offline

 

#20 2018-08-28 02:16:58

CatDadJynx
Member
Registered: 2018-08-23
Posts: 15

Re: New to GB development (but not to c), first question, about sprites...

Ohhh, wonderful! Thanks so much!

Offline

 

#21 2018-08-30 12:49:00

ISSOtm
Member
From: Somewhere in Echo RAM
Registered: 2017-04-18
Posts: 160
Website

Re: New to GB development (but not to c), first question, about sprites...

By the way, as friendly advice I'd advise against using C on GB.


The French Lord Of Laziness.
Legend of Zelda and Undertale fan, I also tend to break Pokémon R/B/Y a little too much.

Twitter | Me on GCL | Discord : ISSOtm#9015 | Skype : isso.tm (I don't login anymore)

Offline

 

#22 2018-09-03 17:12:17

CatDadJynx
Member
Registered: 2018-08-23
Posts: 15

Re: New to GB development (but not to c), first question, about sprites...

I would imagine the assembler language would be better, it's just out of my scope of experience/knowledge at the moment. Any particular reasons, or just general bugginess? I was looking to flash it onto a cartridge as well (or a memory bank chip in particular, probably through an Arduino), but if this would be less likely to work that's understandable as well. I'd just seen it done elsewhere online so it seemed doable

Offline

 

#23 2018-09-03 18:19:01

ISSOtm
Member
From: Somewhere in Echo RAM
Registered: 2017-04-18
Posts: 160
Website

Re: New to GB development (but not to c), first question, about sprites...

C / GBDK's cons:
It's more buggy (tends to generate straight up wrong code sometimes!), generates more bloated code (thus is less likely to fit into a 32kB ROM if your platform only supports that), is more difficult to debug, is slower, eats more RAM.

ASM is more accessible than you think. You hsould give it a try, really! Even if you end up going back to C, it's still valuable knowledge because you know what to NOT do with your C code, and somewhat how to debug it.


The French Lord Of Laziness.
Legend of Zelda and Undertale fan, I also tend to break Pokémon R/B/Y a little too much.

Twitter | Me on GCL | Discord : ISSOtm#9015 | Skype : isso.tm (I don't login anymore)

Offline

 

#24 2018-09-03 18:31:39

CatDadJynx
Member
Registered: 2018-08-23
Posts: 15

Re: New to GB development (but not to c), first question, about sprites...

Will definitely look more into going that route, thanks!

Offline

 

Board footer

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson