GBDK C-Compiler Parsing Errors: Why won't it let me declare variables at such specific places?

533 views Asked by At

I am currently learning C in order to program the original Game Boy using the GBDK library & C Compiler. For whatever reason, the C Compiler continues to run into parser errors whenever I try to declare variables within certain parts of my main function and whenever I try to declare variables within other functions. This may be an issue with there not being enough memory space to store these variables in, so the parser creates a max number of variables..? I have no idea.

I've attempted to utilize different data-types at the lines indicated by the error logs to be the issues, (see below). I also have attempted to move where these variables are being declared, to no avail. Edit: To be more specific, I altered the order that some of the variables were being declared, but it only swapped what the token the parse error said it had an issue with. The problem is definitely related to the order of declaration somehow, but only in that it occurs after a certain number of variables have been declared.

Here is my source code:

'''

#include <gb/gb.h>
#include <stdio.h>
#include "playerSprites.c"
#include "levelTileset.c"
#include "levelOne.c"

#define TRUE 1
#define FALSE 0

//Entity = x, y, sprID, direction, timer, frame, *sprites, state, type, speed, lspr, cspr, & damage.
typedef struct Entity {
    UBYTE x;
    UBYTE y;
    UBYTE sprID; //Sprite ID
    BYTE direction;
    UWORD timer;
    UBYTE frame;
    UBYTE state; //0x80, 0x40, & 0x20 = HP/Pickup ID; 0x10, 0x08, 0x04, 0x02 = Score; 0x01 = State. --> For Non-Player Entities
    //0x80, 0x40, 0x20, & 0x10 = HP; 0x08, 0x04, 0x02, & 0x01 = AP. --> For Player
    UBYTE type; //0 = Player; 1 = Pushblock; 2 = Chasing Enemy; 3 = Turret Enemy; 4 = Fleeing Enemy; 5 = Pickup; 6 = Projectile; 7 = Explosive.
    UWORD speed;
    UBYTE lspr; //Last Sprite Index
    UBYTE cspr; //Current Sprite Index
    UBYTE damage;
} Entity;

//PlayerData = level, score, deaths, kills, secretsFound, overallTime[2], max_HP_AP, weapons, multipliers, cooldown, activeWeapon, powerupTimer, & currentPowerup.
typedef struct SaveData {
    UBYTE level; //Current level.
    UWORD score; //Total score of player.
    UWORD deaths; //Number of times player has died.
    UWORD kills; //Number of enemies killed.
    UBYTE secretsFound;
    UWORD overallTimeH; //Overall time spent playing for this save file. (HIGH)
    UWORD overallTimeL; //Overall time spent playing for this save file. (LOW)
    UBYTE max_HP_AP; //0x80, 0x40, 0x20, & 0x10 = Max HP; 0x08, 0x04, 0x02, & 0x01 = Max AP.
    UBYTE weapons; //0x80 & 0x40 = Quake; 0x20 & 0x10 = Beam; 0x08 & 0x04 = Spreadshot; 0x02 & 0x01 = Boomer.
    UBYTE multipliers; //0x80 & 0x40 = Damage Multiplier; 0x20 & 0x10 = Speed Multiplier; 0x08 & 0x04 = Point Collection Multiplier; 0x02 & 0x01 = Weapon Cooldown Multiplier.
    UBYTE cooldown; //Used during combat to determine whether or not the player is able to use the currently selected weapon. Each weapon has a different cooldown rate. This value gets reset to 0 every time the player switches to a different weapon and when the game is saved at the end of each level.
    UBYTE activeWeapon;
    UBYTE powerupTimer;
    UBYTE currentPowerup; //0 = None, 1 = Double Damage, 2 = Half Cooldown Time, 3 = Invincibility, 4 = Double Points, 5 = Double Speed.
} SaveData;

void apply_input(Entity *player);
void updatePlayerAnimation(Entity *player);

void main()
{
    static Entity player;

    player.x = 8U;
    player.y = 16U;
    player.sprID = 0U;
    player.direction = 2;
    player.timer = 0U;
    player.frame = 0U;
    player.lspr = 0U;
    player.cspr = 0U;
    player.state = 0x33U;
    player.type = 0U;
    player.speed = 4U;
    player.lspr = 0U;
    player.cspr = 0U;
    player.damage = 1U;

    SaveData player_data;

    player_data.level = 0U;
    player_data.score = 0U;
    player_data.deaths = 0U;
    player_data.kills = 0U;
    player_data.secretsFound = 0U;
    player_data.overallTimeH = 0U;
    player_data.overallTimeL = 0U;
    player_data.max_HP_AP = 0x33U;
    player_data.weapons = 0x00U;
    player_data.multipliers = 0x55U;
    player_data.cooldown = 0U;
    player_data.activeWeapon = 0U;
    player_data.powerupTimer = 0U;
    player_data.currentPowerup = 0U;

    set_sprite_data(player.sprID, 8, PlayerSprites);
    set_sprite_tile(player.sprID, player.cspr);
    move_sprite(player.sprID, player.x, player.y);
    set_bkg_data(0, 79, LevelTileset);
    set_bkg_tiles(0, 0, 30, 43, LevelOne);

    SHOW_SPRITES;
    SHOW_BKG;
    DISPLAY_ON;

    while (TRUE)
    {
        apply_input(&player);
        updatePlayerAnimation(&player);
    }
}

void apply_input(Entity *player) {
        UBYTE joypad_status = joypad();

        if (joypad_status && (player->timer == 325U || player->timer == 750U))
        {
            UWORD speed = player->speed;
            UBYTE direction = player->direction;
            UBYTE sprID = player->sprID;
            switch (joypad_status)
            {
                case J_LEFT:
                    if (direction == -1)
                        scroll_sprite(sprID, -speed, 0);
                    else
                        direction = -1;
                    break;
                case J_RIGHT:
                    if (direction == 1)
                        scroll_sprite(sprID, speed, 0);
                    else
                        direction = 1;
                    break;
                case J_UP:
                    if (direction == -2)
                        scroll_sprite(sprID, 0, -speed);
                    else
                        direction = -2;
                    break;
                case J_DOWN:
                    if (direction == 2)
                        scroll_sprite(sprID, 0, speed);
                    else
                        direction = 2;
                    break;
                case J_LEFT | J_UP:
                    if (direction == -2)
                        scroll_sprite(sprID, -speed, -speed);
                    else
                        direction = -2;
                    break;
                case J_LEFT | J_DOWN:
                    if (direction == 2)
                        scroll_sprite(sprID, -speed, speed);
                    else
                        direction = 2;
                    break;
                case J_RIGHT | J_UP:
                    if (direction == -2)
                        scroll_sprite(sprID, speed, -speed);
                    else
                        direction = -2;
                    break;
                case J_RIGHT | J_DOWN:
                    if (direction == 2)
                        scroll_sprite(sprID, speed, speed);
                    else
                        direction = 2;
                    break;
                default:
                    break;
            }
        }
}

void updatePlayerAnimation(Entity *player) {
    UWORD timer = player->timer;

    if (timer == 625U)
            player->frame = player->frame ? 0U : 1U;

        if (timer == 750U)
            player->timer = 0U;
        else
            player->timer++;

        UBYTE frame = player->frame;

            switch (player->direction)
            {
                case -2: //UP
                    player->cspr = frame + 2U;
                    break;
                case -1: //LEFT
                    player->cspr = frame + 6U;
                    break;
                case 1: //RIGHT
                    player->cspr = frame + 4U;
                    break;
                case 2: //DOWN
                    player->cspr = frame;
                    break;
                default:
                    break;
            }

        UBYTE cspr = player->cspr;

        if (player->lspr != cspr)
        {
            set_sprite_tile(player->sprID, cspr);
            player->lspr = cspr;
        }
}

'''

And here is the error log I keep getting in the Windows command console whenever I attempt to compile:

'''

c:\gbdk\bin\lcc -Wa-l -Wl-m -Wl-j -DUSE_SFR_FOR_REG -c -o main.o main.c

main.c(67) parse error: token -> 'SaveData' ; column 16
main.c(69):error *** Undefined identifier 'player_data'
main.c(69):error *** Structure/Union expected left of '.->'
main.c(70):error *** Undefined identifier 'player_data'
main.c(70):error *** Structure/Union expected left of '.->'
main.c(71):error *** Undefined identifier 'player_data'
main.c(71):error *** Structure/Union expected left of '.->'
main.c(72):error *** Undefined identifier 'player_data'
main.c(72):error *** Structure/Union expected left of '.->'
main.c(73):error *** Undefined identifier 'player_data'
main.c(73):error *** Structure/Union expected left of '.->'
main.c(74):error *** Undefined identifier 'player_data'
main.c(74):error *** Structure/Union expected left of '.->'
main.c(75):error *** Undefined identifier 'player_data'
main.c(75):error *** Structure/Union expected left of '.->'
main.c(76):error *** Undefined identifier 'player_data'
main.c(76):error *** Structure/Union expected left of '.->'
main.c(77):error *** Undefined identifier 'player_data'
main.c(77):error *** Structure/Union expected left of '.->'
main.c(78):error *** Undefined identifier 'player_data'
main.c(78):error *** Structure/Union expected left of '.->'
main.c(79):error *** Undefined identifier 'player_data'
main.c(79):error *** Structure/Union expected left of '.->'
main.c(80):error *** Undefined identifier 'player_data'
main.c(80):error *** Structure/Union expected left of '.->'
main.c(81):error *** Undefined identifier 'player_data'
main.c(81):error *** Structure/Union expected left of '.->'
main.c(82):error *** Undefined identifier 'player_data'
main.c(82):error *** Structure/Union expected left of '.->'
error *** code not generated for 'main' due to previous errors
error *** code not generated for 'apply_input' due to previous errors

main.c(176) parse error: token -> 'UBYTE' ; column 21

main.c(196) parse error: token -> 'UBYTE' ; column 21
main.c(181):error *** Undefined identifier 'frame'
main.c(184):error *** Undefined identifier 'frame'
main.c(187):error *** Undefined identifier 'frame'
main.c(190):error *** Undefined identifier 'frame'
main.c(198):error *** Undefined identifier 'cspr'
main.c(200):error *** Undefined identifier 'cspr'
main.c(201):error *** Undefined identifier 'cspr'
error *** code not generated for 'updatePlayerAnimation' due to previous errors
c:\gbdk\bin\lcc -Wa-l -Wl-m -Wl-j -DUSE_SFR_FOR_REG -o main.gb main.o

'''

The current expectation for this code is just to put an animated sprite onto the screen that is moved by whatever keys are assigned to the Game Boy D-Pad by whatever emulator the game is being run on. However, I can't even tell if it will have the right output since it won't even parse correctly. Any help would be appreciated.

0

There are 0 answers