SGDK: Creating a Header File

Included Files

Header File Tutorial base.zip – A base template to follow along with the header tutorial via the Pigsy’s Retro Dev Tutorial video .

Header File Tutorial Complete.zip – The completed project for you to use as a comparison once you’re done with the tutorial.

nemoSG_full.png – A sprite resource to help you place an object on the screen. This is from Little Nemo: The Dream Master for the NES and not a redone image of the Alex Kidd sprite shown in the Pigsy tutorial.

Adding a .res file and folder

First, you can erase all the VDP_drawText information that Pigsy has in his main.c file. If you want to make sure you can compile properly before beginning, you can give it a try and see if everything compiles properly. If you’re having problems with IntelliSense not recognizing SGDK commands then refer to Pigsy’s video regarding the .json object as well as the updating of the “boot” folder. Pigsy used SGDK v. 2.11 in his tutorial whereas I used v. 2.0 for mine.

It’s common among various tutorials to see a resources.res where all the asset information is input. To keep things compartmentalized, Pigsy is going to create a res_player.res file and use this to focus specifically on the “player” character assets. A separate .res file/folder will be done for the “enemies” in another one of his tutorials.

First, right-click on “res” and choose “New File”. The name of the file will be res_player.res rather than our previous default of resources.res. Since we’re using a different sprite asset, you’ll want to make sure your sprite declaration in this tutorial isn’t identical to the one in the Pigsy video. We’ll also want to right-click on “res” again and choose “New Folder”. This folder name will be called player_assets.

Remember, the format for declaring your assets in the .res file for a SPRITE looks like this.

SPRITE [identifier] [“path.file extension” for the asset] [width] [height] [compression type] [animation speed]


 

Your Explorer bar should look like this.

A screenshot of a computer program

AI-generated content may be incorrect.

Try seeing if you can declare the nemo sprite properly in your newly created res_player.res file by doing the Save/Clean/Compile dance in SGDK. You may want to open the nemo asset in Aesprite/Libresprite to see what the dimensions of the sprite are. Below is a snippet of the asset with the 8x8 grid overlay for reference.

A pixelated cartoon of a person

AI-generated content may be incorrect. 

 

If you’re having compiling issues, it’s possible that you’ve input the format incorrectly into your res_player.res file.

If you’ve done it correctly it should look something like this.

Remember, this asset is from a sprite sheet, it’s important to remember that you only need to provide the size for the first animation cel.  

Adding functions and declarations to main.c

Now that we’ve added the asset properly, it’s time to start writing code in main.c to make it appear on screen.

Previously, we would have an #include <resources.h> but for this tutorial we’re replacing it with #include “res_player.h” instead. Notice that we’re using quotation marks rather than the < > enclosure. Pigsy doesn’t explain why this is the case so neither will I.

Add the VDP_setScreenWidth256(); and SPR_init(); functions in main(). Then add the SPR_update(); function in the while(1) loop.

If you’ve done it right, it should look like this.

A screen shot of a computer program

AI-generated content may be incorrect.

Next, we’re going to declare our Sprite and write the functions to draw it on screen. Above the main() function, you’ll want to declare your sprite using the Sprite* [label]; format.

Pigsy has chosen Sprite* player; in his code. I did the same thing though my label in the res_player.res is named differently.

 

 

Below SPR_init(); we’re going to add the following code:

We’ll create a function with this code momentarily but for now give your code the S/C/C treatment and see if it compiles properly.

If you’re successful, then we’re going to take this code and place it within a function called createPlayer();

Pigsy is going to pre-declare this function above main() by typing void createPlayer(); and then below the while(1) loop, he completes the function.

void createPlayer(){

    PAL_setPalette(PAL3, img_nemo.palette->data, DMA);

    player = SPR_addSprite(&img_nemo, 10, 10, TILE_ATTR(PAL3, FALSE, FALSE, FALSE));

}

You’ll also want to call the createPlayer(); function in the main() loop.


 

Creating a header to store a function

The next thing we’re going to do is condense down what gets called in the main() function by moving the createPlayer() function into player.h and corresponding player.c files.

First, we’re going to right-click on the inc folder and add a file named player.h. Then we’re going to make sure that the header file has the mandatory information in it. Pigsy looks at the res_player.h file as a reference in his video. Essentially, you’ll have the name of your header file referenced using the #ifndef _PLAYER_H_ #define _H_H_ #endif format. We’ll also want to make sure we include a reference to the genesis.h header as well so the header will recognize SGDK commands. We also need to reference the “res_player.h” as it has our sprite data in it. So, let’s cut it from main.c and put it in our player.h file

It's a bit hard to read that and follow along so here’s what the code looks like.

A screenshot of a computer program

AI-generated content may be incorrect.

Before we create the corresponding player.c file, we need to put some information in this header file to reference what we need in the createPlayer() function. The first thing we’re going to do is pull the Sprite* declaration we made above the main() function and put it in this header file.  You can cut the Sprite* player; line from main.c and before pasting it into our player.h file, you’ll need to define this as an extern (external) and then paste the Sprite* player; line.

We’re going to do the same thing with the void createPlayer(); line we predeclared above the main() function. So, it too will use the extern label in front of the void createPlayer(); line. Now, in main.c we’ll add #include “player.” Below our <genesis.h> reference.

 

When you’re done, the declarations that were above the main() function should now be gone from main.c and now reside in the player.h header file. The player.h and main.c file should look like the images below.

A screenshot of a computer program

AI-generated content may be incorrect.

A screenshot of a computer program

AI-generated content may be incorrect.

Now that we’ve made the player.h header file, it’s time to add a player.c file to our src folder.

Within the player.c file, we add an #include “player.h”. The #ifndef, #define, #endif, format was for the header. The formatting for a .c file is something you should be relatively familiar with at this point.

Once you have your #incldue “player.h” line, we’re going to add our Sprite* player; reference. We don’t add the extern label this time we just use Sprite* player; and then we cut the entire void createPlayer(); function that was below the while(1) loop and paste it below our Sprite reference.

If you’ve done everything correctly, the player.c file should look like this.

A screen shot of a computer

AI-generated content may be incorrect.

Now, the real estate in main.c should be very condensed down. Everything in main.c should now look like this.

A screenshot of a computer program

AI-generated content may be incorrect.

 

 

 

For comparison, having everything declared in main.c for the createPlayer() function was roughly 31 lines (see image below) but now we’ve condensed it to around 19 lines. VSCode has some optimization plug-ins to help you navigate sections of your code but you can still surmise that creating these header files will help keep your main.c file from becoming unwieldy over time.

A screenshot of a computer program

AI-generated content may be incorrect.

Try taking some of the other projects that are available on the site and see if you can successfully condense down a function into a header file.

Good luck.