LNK2019 error; what is missing/not defined here? [duplicate] - c++

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 3 years ago.
When I try to build out my progam I get this error:
error LNK2019: unresolved external symbol "bool __cdecl TextGame::spaceVoid(struct TextGame::Position const &,struct TextGame::RoomData const &)" (?spaceVoid#TextGame##YA_NABUPosition#1#ABURoomData#1##Z) referenced in function "void __cdecl TextGame::UpdateGame(struct TextGame::PlayerState &,struct TextGame::WorldState &)" (?UpdateGame#TextGame##YAXAAUPlayerState#1#AAUWorldState#1##Z)
This is for a basic ASCII dungeon crawler. I'm a relative newbie taking a college class. Right now we're just following along with a video 1-for-1, so I'm not entirely sure where the error is. Obviously it seems to want something defined regarding the Position (coordinates of an object in a room) and RoomData (properties of the room). But I'm lost as to what exactly. Sorry I can't be more specific - please let me know if there's extra info I can provide.
namespace TextGame
{
RoomData CreateRoom(const std::string& inName, const std::string& inDescription)
{
RoomData room = {};
room.Name = inName;
room.Description = inDescription;
return room;
}
void InitializeGame(PlayerState& playerState, WorldState& worldState)
{
printf("Welcome to...\n");
printf("A GAME by SOMEONE\n\n");
printf("TELL THE PLAYER THE GOAL OF THE GAME\n\n");
playerState.WantsDescription = true;
playerState.CurrentRoomIndex = 0;
playerState.CurrentPosition.X = 3;
playerState.CurrentPosition.Y = 4;
worldState.Rooms.clear();
// 0
{
RoomData room = CreateRoom("ROOM NAME", "ROOM DESCRIPTION");
room.RoomMapWidth = 10;
room.RoomPosition = { 0, 0 };
room.RoomMap =
"####.#####"
"#........#"
"#........#"
"#........."
"#........."
"#........#"
"#........#"
"##########";
room.Inventory.push_back({ ItemType_Key, {5,3} });
room.Inventory.push_back({ ItemType_Sword, {7,5} });
room.LockedDoors.push_back({ {4, 0} });
worldState.Rooms.push_back(room);
}
// 1
{
RoomData room = CreateRoom("ROOM NAME 1", "ROOM DESCRIPTION 1");
room.RoomMapWidth = 10;
room.RoomPosition = { 1, 0 };
room.RoomMap =
"##########"
"#........#"
"#........#"
".........#"
".........#"
"#........#"
"#........#"
"##########";
worldState.Rooms.push_back(room);
}
// 2
{
RoomData room = CreateRoom("ROOM NAME 2", "ROOM DESCRIPTION 2");
room.RoomMapWidth = 10;
room.RoomPosition = { 0, -1 };
room.RoomMap =
"####.#####"
"#........#"
"#........#"
"#........#"
"#........#"
"#........#"
"#........#"
"####..####";
worldState.Rooms.push_back(room);
}
// 3
{
RoomData room = CreateRoom("ROOM NAME 3", "ROOM DESCRIPTION 3");
room.RoomMapWidth = 10;
room.RoomPosition = { 0, -2 };
room.RoomMap =
"####..####"
"#........#"
"#........#"
"#........#"
"#........#"
"#........#"
"#........#"
"####..####";
worldState.Rooms.push_back(room);
}
// 4
{
RoomData room = CreateRoom("ROOM NAME 4", "ROOM DESCRIPTION 4");
room.RoomMapWidth = 10;
room.RoomPosition = { 0, -3 };
room.RoomMap =
"##########"
"#....A...#"
"#........#"
"#........#"
"#........#"
"#........#"
"#........#"
"####..####";
worldState.Rooms.push_back(room);
}
}
void GetInput(PlayerState& playerState, const WorldState& worldState)
{
playerState.WantsToExit = false;
playerState.WantsDescription = false;
playerState.WantsInventoryListed = false;
playerState.DesiredPosition = playerState.CurrentPosition;
playerState.WantsToGet = false;
//playerState.Inventory.push_back({ ItemType_Key, Position() });
//playerState.Inventory.push_back({ ItemType_Sword, Position() });
//playerState.Inventory.push_back({ ItemType_Key, Position() });
printf("What do you do?\n");
printf("> ");
TextAdventureCommand command = ParseAdventureCommand();
if (command.Verb == "quit")
{
playerState.WantsToExit = true;
}
else if (command.Verb == "north" || command.Verb == "w")
{
playerState.DesiredPosition.Y = playerState.DesiredPosition.Y - 1;
}
else if (command.Verb == "south" || command.Verb == "s")
{
playerState.DesiredPosition.Y = playerState.DesiredPosition.Y + 1;
}
else if (command.Verb == "west" || command.Verb == "a")
{
playerState.DesiredPosition.X = playerState.DesiredPosition.X - 1;
}
else if (command.Verb == "east" || command.Verb == "d")
{
playerState.DesiredPosition.X = playerState.DesiredPosition.X + 1;
}
else if (command.Verb == "look")
{
playerState.WantsDescription = true;
}
else if (command.Verb == "inventory" || command.Verb == "inv")
{
playerState.WantsInventoryListed = true;
}
else if (command.Verb == "get")
{
playerState.WantsToGet = true;
}
else if (command.Verb == "help")
{
printf("Command List: look, quit, inventory, get, w, a, s, d\n");
printf("Key:\n");
printf(" # - Player\n");
printf(" A - Altar\n");
printf(" i - Item\n");
printf(" . - Floor\n");
printf(" # - Wall\n");
printf(" H - Door (Locked)\n");
}
else
{
printf("I don't understand\n");
}
printf("\n");
}
void RenderGame(const PlayerState& playerState, const WorldState& worldState)
{
if (playerState.WantsDescription)
{
const RoomData& currRoom = worldState.Rooms[playerState.CurrentRoomIndex];
printf("================================================\n");
printf("LOCATION: %s\n", currRoom.Name.c_str());
printf("%s\n\n", currRoom.Description.c_str());
std::string renderedMapString = "";
unsigned int currentSpace = 0;
while (currentSpace < currRoom.RoomMap.size())
{
char CharacterToDisplay = currRoom.RoomMap[currentSpace];
for (unsigned int i = 0; i < currRoom.Inventory.size(); ++i)
{
const InventoryItem& currItem = currRoom.Inventory[i];
if (PositionToIndex(currItem.ItemPosition, currRoom.RoomMapWidth) == currentSpace)
{
CharacterToDisplay = getItemIcon(currItem.Type);
}
}
for (unsigned int i = 0; i < currRoom.LockedDoors.size(); ++i)
{
const LockedDoorData& currDoor = currRoom.LockedDoors[i];
if (PositionToIndex(currDoor.DoorPosition, currRoom.RoomMapWidth) == currentSpace)
{
CharacterToDisplay = 'H';
}
}
//Set where the player is drawn based on the input X and Y coordinates
if (PositionToIndex(playerState.CurrentPosition, currRoom.RoomMapWidth) == currentSpace)
{
CharacterToDisplay = '#';
}
renderedMapString += CharacterToDisplay;
if (currentSpace % currRoom.RoomMapWidth == currRoom.RoomMapWidth - 1)
{
renderedMapString += "\n";
}
currentSpace++;
}
printf("%s\n", renderedMapString.c_str());
printf("\n");
}
else if (playerState.WantsInventoryListed)
{
printf("================================================\n");
printf("INVENTORY:\n");
if (playerState.Inventory.size() == 0)
{
printf("You're not carrying anything.\n");
}
else
{
for (unsigned int i = 0; i < playerState.Inventory.size(); ++i)
{
printf("%s\n", GetItemName(playerState.Inventory[i].Type).c_str());
}
}
printf("\n");
}
}
void UpdateGame(PlayerState& playerState, WorldState& worldState)
{
RoomData& currRoom = worldState.Rooms[playerState.CurrentRoomIndex];
if (playerState.DesiredPosition != playerState.CurrentPosition)
{
TryToUnlockDoor(playerState.DesiredPosition, currRoom, playerState);
if (spaceVoid(playerState.DesiredPosition, currRoom))
{
Position desiredRoomPosition = currRoom.RoomPosition;
int playerPositionType = 0;
if (playerState.DesiredPosition.X < 0)
{
desiredRoomPosition.X--;
playerPositionType = 1;
}
else if(playerState.DesiredPosition.X >= currRoom.RoomMapWidth)
{
desiredRoomPosition.X++;
playerPositionType = 2;
}
else if (playerState.DesiredPosition.Y < 0)
{
desiredRoomPosition.Y--;
playerPositionType = 3;
}
else if (playerState.DesiredPosition.Y >= ((int)currRoom.RoomMap.size() / currRoom.RoomMapWidth))
{
desiredRoomPosition.Y++;
playerPositionType = 4;
}
bool foundNewRoom = false;
for (unsigned int i = 0; i < worldState.Rooms.size(); ++i)
{
if (worldState.Rooms[i].RoomPosition == desiredRoomPosition)
{
playerState.CurrentRoomIndex = i;
playerState.WantsDescription = true;
switch (playerPositionType)
{
case 1:
playerState.CurrentPosition.X = worldState.Rooms[playerState.CurrentRoomIndex].RoomMapWidth - 1;
break;
case 2:
playerState.CurrentPosition.X = 0;
break;
case 3:
playerState.CurrentPosition.Y = (worldState.Rooms[playerState.CurrentRoomIndex].RoomMap.size() / worldState.Rooms[playerState.CurrentRoomIndex].RoomMapWidth) - 1;
break;
case 4:
playerState.CurrentPosition.Y = 0;
break;
}
foundNewRoom = true;
}
}
if (!foundNewRoom)
{
printf("It's just the void beyond this point.\n");
}
}
else if (spaceOpen(playerState.DesiredPosition, currRoom))
{
playerState.CurrentPosition = playerState.DesiredPosition;
playerState.WantsDescription = true;
}
else
{
printf("It's blocked.\n");
}
}
else if (playerState.WantsToGet)
{
bool foundItem = false;
for (unsigned int i = 0; i < currRoom.Inventory.size(); ++i)
{
const InventoryItem& currItem = currRoom.Inventory[i];
if (currItem.ItemPosition == playerState.CurrentPosition)
{
printf("Picked up a %s\n\n", GetItemName(currItem.Type).c_str());
playerState.Inventory.push_back(currItem);
currRoom.Inventory.erase(currRoom.Inventory.begin() + i);
foundItem = true;
break;
}
}
if (!foundItem)
{
printf("There's nothing her to pick up.\n\n");
}
}
}
void CleanupGame(PlayerState& playerState, WorldState& worldState)
{
worldState.Rooms.clear();
}
int PositionToIndex(const Position& position, int roomWidth)
{
return position.Y * roomWidth + position.X;
}
bool spaceOpen(const Position& position, const RoomData& currRoom)
{
for (unsigned int i = 0; i < currRoom.LockedDoors.size(); ++i)
{
const LockedDoorData& currDoor = currRoom.LockedDoors[i];
if (currDoor.DoorPosition == position)
{
return false;
}
}
int spaceIndex = PositionToIndex(position, currRoom.RoomMapWidth);
return currRoom.RoomMap[spaceIndex] == '.';
}
void TryToUnlockDoor(const Position& position, RoomData& currRoom, PlayerState& playerState)
{
for (unsigned int i = 0; i < currRoom.LockedDoors.size(); ++i)
{
const LockedDoorData& currDoor = currRoom.LockedDoors[i];
if (currDoor.DoorPosition == position)
{
//Door found, now find key
for (unsigned int j = 0; j < playerState.Inventory.size(); ++j)
{
const InventoryItem& currItem = playerState.Inventory[j];
if (currItem.Type == ItemType_Key)
{
//Key found
currRoom.LockedDoors.erase(currRoom.LockedDoors.begin() + i);
playerState.Inventory.erase(playerState.Inventory.begin() + j);
return;
}
}
}
}
}
bool spaceVoid(const Position& position, const RoomData& currRoom, PlayerState& playerState)
{
return position.X < 0 || position.X >= currRoom.RoomMapWidth || position.Y < 0 || position.Y >= ((int)currRoom.RoomMap.size() / currRoom.RoomMapWidth);
}
std::string GetItemName(ItemType itemType)
{
switch (itemType)
{
case ItemType_Key:
return "Key";
break;
case ItemType_Sword:
return "Sword";
break;
}
}
char getItemIcon(ItemType itemType)
{
switch (itemType)
{
case TextGame::ItemType_Key:
return 'k';
break;
case TextGame::ItemType_Sword:
return 's';
break;
}
}
}

The linker is complaining about not finding the spacevoid method taking two parameters:
bool __cdecl TextGame::spaceVoid(struct TextGame::Position const &,struct TextGame::RoomData const &)
because in your code there is only a spacevoid method with three parameters defined:
bool spaceVoid(const Position& position, const RoomData& currRoom, PlayerState& playerState)
You'll need to decide which one is the right one or add an additional spacevoid method taking two parameters only.

Related

Trying to make a custom shortcut keyboard with esp32 with arduino ide

Ok, so as in the title I am trying to make a custom shortcut keyboard with esp32 with Arduino ide and keep running into errors so if someone could fix it all for me that would be appreciated.
one of these errors is: no return statement in function returning non-void [-Werror=return-type]
Code:
#include <BleKeyboard.h>
BleKeyboard bleKeyboard;
const int buttonPin[] = {36, 39, 34, 35, 32, 33};
int pinCount = 6;
int potPin = 2;
int prevPotState = -1;
int potState = -1;
int potTolerance = 1;
long potDebounceDelay = 20;
int buttonState[] = {1, 1, 1, 1, 1, 1};
int prevButtonState[] = {HIGH, HIGH, HIGH, HIGH, HIGH, HIGH};
long startedPressing[] = {0, 0, 0, 0, 0, 0};
boolean longPressing[] = {false, false, false, false, false, false};
long lastDebounceTime[] = {0, 0, 0, 0, 0, 0, 0}; // 1 more for the pot
long debounceDelay = 0;
boolean testHardware = false;
int keyComb(char key1 = 0, char key2 = 0, char key3 = 0, char key4 = 0) {
if (key1 != 0) {
bleKeyboard.press(key1);
}
if (key2 != 0) {
bleKeyboard.press(key2);
}
if (key3 != 0) {
bleKeyboard.press(key3);
}
if (key4 != 0) {
bleKeyboard.press(key4);
}
delay(100);
bleKeyboard.releaseAll();
}
int sendLine(char const * line) {
bleKeyboard.print(line);
delay(750);
keyComb(KEY_RETURN);
}
// Output actions. Probably the only part that you need to change
int outputAction(int currentButton, int typeOfPress = 0) {
// typeOfPress 1: on push; 2: on release; 3: on long press; 4: on lingering press.
// actions on release, on long press and lingering press include the action press. Action lingering press cancels action release and long press.
if (testHardware) {
bleKeyboard.print(currentButton + 1);
if (typeOfPress == 1) {
bleKeyboard.print(" pressed ");
}
if (typeOfPress == 2) {
bleKeyboard.print(" released ");
}
if (typeOfPress == 3) {
bleKeyboard.print(" long ");
}
if (typeOfPress == 4) {
bleKeyboard.print(" lingering ");
}
bleKeyboard.print(millis());
bleKeyboard.print("Pressed: ");
bleKeyboard.print(lastDebounceTime[currentButton]);
keyComb(KEY_RETURN);
} else {
if (currentButton + 1 == 1) {
if (typeOfPress == 1) {
keyComb(KEY_LEFT_CTRL, KEY_LEFT_ALT, KEY_LEFT_SHIFT, 'M');
}
if (typeOfPress == 3) {
keyComb(KEY_LEFT_CTRL, KEY_LEFT_ALT, KEY_LEFT_SHIFT, 'S');
}
}
if (currentButton + 1 == 2) {
if (typeOfPress == 1) {
keyComb(KEY_LEFT_CTRL, KEY_LEFT_ALT, KEY_LEFT_SHIFT, 'P');
}
}
if (currentButton + 1 == 3) {
if (typeOfPress == 1) {
keyComb(KEY_LEFT_CTRL, KEY_LEFT_ALT, KEY_LEFT_SHIFT, 'M');
}
}
if (currentButton + 1 == 4) {
if (typeOfPress == 2) {
keyComb(KEY_LEFT_CTRL, KEY_LEFT_ALT, KEY_LEFT_SHIFT, 'L');
}
}
if (currentButton + 1 == 5) {
if (typeOfPress == 1) {
keyComb(KEY_LEFT_CTRL, KEY_LEFT_ALT, KEY_LEFT_SHIFT, 'K');
}
}
if (currentButton + 1 == 6) {
if (typeOfPress == 1) {
keyComb(KEY_LEFT_CTRL, KEY_LEFT_ALT, KEY_LEFT_SHIFT, 'N');
}
}
}
}
void setup() {
Serial.begin(115200);
for (int thisPin = pinCount - 1; thisPin >= 0; thisPin--) {
pinMode(buttonPin[thisPin], INPUT);
analogWrite(buttonPin[thisPin], HIGH); // In some versions use INPUT_PULLUP to use the built-in pull up resistor
}
bleKeyboard.begin();
}
void loop() {
for (int thisPin = pinCount - 1; thisPin >= 0; thisPin--) {
buttonState[thisPin] = analogRead(buttonPin[thisPin]);
// HIGH = state 1 <- button not pressed
// LOW = state 0 <- button pressed
// On longer press
if ((startedPressing[thisPin] == 0) || ((millis() - startedPressing[thisPin]) <= 1200)) {
// Debouncing not working properly with current hardware
//if (((buttonState[thisPin] != prevButtonState[thisPin])) && ((millis() - lastDebounceTime[thisPin]) > debounceDelay)) {
if ((buttonState[thisPin] != prevButtonState[thisPin])) {
if (buttonState[thisPin] == 0) {
// Standard press action
startedPressing[thisPin] = millis();
outputAction(thisPin, 1);
} else {
if (!longPressing[thisPin]) {
if ((millis() - startedPressing[thisPin]) < 500) {
// On release (to avoid standard action if is incompatible with Long or Longer action)
outputAction(thisPin, 2);
} else {
// Long action (+standard action already sent)
outputAction(thisPin, 3);
}
}
startedPressing[thisPin] = 0;
longPressing[thisPin] = false;
}
lastDebounceTime[thisPin] = millis();
}
} else {
outputAction(thisPin, 4);
longPressing[thisPin] = true;
startedPressing[thisPin] = 0;
}
prevButtonState[thisPin] = buttonState[thisPin];
}
// The pot
int thisPin = pinCount; // To consider it the last one in the lastDebounceTime array
potState = (int) (analogRead(potPin) / 6);
if (prevPotState == -1) {
prevPotState = potState;
}
if (((potState > prevPotState + potTolerance) || (potState < prevPotState - potTolerance))
&& ((millis() - lastDebounceTime[thisPin]) > potDebounceDelay)
) {
if (potState > prevPotState) {
keyComb(KEY_UP_ARROW);
} else {
keyComb(KEY_DOWN_ARROW);
}
lastDebounceTime[thisPin] = millis();
prevPotState = potState;
}
}
!!!FILLER!!!
hehehuheuheuheuhuehdkl;lbkljdfklbfklvjnbgkljnjbgvnjkvjbkvfnvkljklbjk
From the declaration of your function, you declare the function can return an integer in the code. But you don't return an integer.
For your example,
int sendLine(char const * line) {
bleKeyboard.print(line);
delay(750);
keyComb(KEY_RETURN);
}
You don't return an integer in the function sendLine.
Another function you declared to have the same issue too.

Setting NULL causes lag with [MAX_STRING_LENGTH] = {'\0'};

I thought it would be a good best practice to search thru my code for any references like ..
char buf[MAX_STRING_LENGTH];
... and replace them with ...
char buf[MAX_STRING_LENGTH] = {'\0'};
Doing a search in the code I have a number that are set to null (around 239) and others that are not (1,116).
When I replaced the remaining 1,116 instances with char buf[MAX_STRING_LENGTH] = {'\0'}; and pushed the code live the game was noticeably laggy.
Reverting the change removed the lag.
Can someone explain why setting these to null would cause the game to lag while running?
Example code setting to Null
void do_olist(Character *ch, char *argument, int cmd)
{
int header = 1;
int type = -1;
int wear_bit = -1;
int i = 0;
int inclusive;
int zone = -1;
int yes_key1 = 0;
int yes_key2 = 0;
int yes_key3 = 0;
int count = 0;
Object *obj;
bool found = false;
char key1 [MAX_STRING_LENGTH] = {'\0'};
char key2 [MAX_STRING_LENGTH] = {'\0'};
char key3 [MAX_STRING_LENGTH] = {'\0'};
char buf [MAX_STRING_LENGTH];
argument = one_argument(argument, buf);
if (!*buf)
{
ch->send("Selection Parameters:\n\n");
ch->send(" +/-<object keyword> Include/exclude object keyword.\n");
ch->send(" <zone> Objects from zone only.\n");
ch->send(" <item-type> Include items of item-type.\n");
ch->send(" <wear-bits> Include items of wear type.\n");
ch->send("\nExample: olist +sword -rusty weapon 10\n");
ch->send("will only get non-rusty swords of type weapon from zone 10.\n");
return;
}
while (*buf)
{
inclusive = 1;
if (strlen(buf) > 1 && isalpha(*buf) &&
(type = index_lookup(item_types, buf)) != -1)
{
argument = one_argument(argument, buf);
continue;
}
if (strlen(buf) > 1 && isalpha(*buf) &&
(wear_bit = index_lookup(wear_bits, buf)) != -1)
{
argument = one_argument(argument, buf);
continue;
}
if (isdigit(*buf))
{
if ((zone = atoi(buf)) >= MAX_ZONE)
{
ch->send("Zone not in range 0..99\n");
return;
}
argument = one_argument(argument, buf);
continue;
}
switch (*buf)
{
case '-':
inclusive = 0;
case '+':
if (!buf [1])
{
ch->send("Expected keyname after 'k'.\n");
return;
}
if (!*key1)
{
yes_key1 = inclusive;
strcpy(key1, buf + 1);
}
else if (!*key2)
{
yes_key2 = inclusive;
strcpy(key2, buf + 1);
}
else if (*key3)
{
ch->send("Sorry, at most three keywords.\n");
return;
}
else
{
yes_key3 = inclusive;
strcpy(key3, buf + 1);
}
break;
case 'z':
argument = one_argument(argument, buf);
if (!isdigit(*buf) || atoi(buf) >= MAX_ZONE)
{
ch->send("Expected valid zone after 'z'.\n");
return;
}
zone = atoi(buf);
break;
}
argument = one_argument(argument, buf);
}
*b_buf = '\0';
for (obj = full_object_list; obj; obj = obj->lnext)
{
if (zone != -1 && obj->zone != zone)
continue;
if (type != -1 && obj->obj_flags.type_flag != type)
continue;
if (wear_bit != -1)
{
for (i = 0; (*wear_bits[i] != '\n'); i++)
{
if (IS_SET(obj->obj_flags.wear_flags, (1 << i)))
{
if (i != wear_bit)
continue;
else
found = true;
}
}
if (found)
found = false;
else
continue;
}
if (*key1)
{
if (yes_key1 && !strcasestr(const_cast<char*> (obj->getName().c_str()), key1))
continue;
else if (!yes_key1 && strcasestr(const_cast<char*> (obj->getName().c_str()), key1))
continue;
}
if (*key2)
{
if (yes_key2 && !strcasestr(const_cast<char*> (obj->getName().c_str()), key2))
continue;
else if (!yes_key2 && strcasestr(const_cast<char*> (obj->getName().c_str()), key2))
continue;
}
if (*key3)
{
if (yes_key3 && !strcasestr(const_cast<char*> (obj->getName().c_str()), key3))
continue;
else if (!yes_key3 && strcasestr(const_cast<char*> (obj->getName().c_str()), key3))
continue;
}
count++;
if (count < 200)
olist_show(obj, type, header);
header = 0;
}
if (count > 200)
{
sprintf(buf, "You have selected %d objects (too many to print all at once).\n",
count);
ch->send(buf);
//return;
}
else {
sprintf(buf, "You have selected %d objects.\n",
count);
ch->send(buf);
}
page_string(ch->desc, b_buf);
}
I took the advice to replace instances of ...
char buf[MAX_STRING_LENGTH] = {'\0'};
with ...
char buf[MAX_STRING_LENGTH]; *buf = 0;

How to assign hexadecimal values to arrays using switch or an if-else step at particular locations?

I was working on a hobby project and it require me to assign hex values to an array based on certain hex function calls. However the array is not returned and simply freezes the program at execution.Looking for some insights.
I need to then take the returned unsigned char array and then move it to a second array free of NULL values. This I will use in my main program.
Thanks,
Aurelius
//Function to get hex condition
unsigned char set_lpx_var(char S0,char S1,char S2,char S3)
{
unsigned char PIN;
if((S0==0)&&(S1==0)&&(S2==0)&&(S3==0)) PIN = 0x00;
else if((S0==1)&&(S1==0)&&(S2==0)&&(S3==0)) PIN = 0x01;
else if((S0==0)&&(S1==1)&&(S2==0)&&(S3==0)) PIN = 0x02;
else if((S0==1)&&(S1==1)&&(S2==0)&&(S3==0)) PIN = 0x03;
else if((S0==0)&&(S1==0)&&(S2==1)&&(S3==0)) PIN = 0x04;
else if((S0==1)&&(S1==0)&&(S2==1)&&(S3==0)) PIN = 0x05;
else if((S0==0)&&(S1==1)&&(S2==1)&&(S3==0)) PIN = 0x06;
else if((S0==1)&&(S1==1)&&(S2==1)&&(S3==0)) PIN = 0x07;
else if((S0==0)&&(S1==0)&&(S2==0)&&(S3==1)) PIN = 0x08;
else if((S0==1)&&(S1==0)&&(S2==0)&&(S3==1)) PIN = 0x09;
else if((S0==0)&&(S1==1)&&(S2==0)&&(S3==1)) PIN = 0x0A;
else if((S0==1)&&(S1==1)&&(S2==0)&&(S3==1)) PIN = 0x0B;
else if((S0==0)&&(S1==0)&&(S2==1)&&(S3==1)) PIN = 0x0C;
else if((S0==1)&&(S1==0)&&(S2==1)&&(S3==1)) PIN = 0x0D;
else if((S0==0)&&(S1==1)&&(S2==1)&&(S3==1)) PIN = 0x0E;
else if((S0==1)&&(S1==1)&&(S2==1)&&(S3==1)) PIN = 0x0F;
else PIN = 0x00;
printf("\n Obtained hexa digit %u",(unsigned)PIN);
return PIN;
}
Function to assign hex values to array
unsigned char* command(unsigned char PIN,int sw,int size)
{
unsigned char* x;
x = (unsigned char*)malloc(size);
//select line assignment to array
if(sw == 1)
{
if(PIN==0x00)
{
x[0]='0';
x[1]='0';
x[2]='0';
}
else if(PIN==0X01)
{
x[0]='1';
x[1]='0';
x[2]='0';
}
else if(PIN==0x02)
{
x[0]='0';
x[1]='1';
x[2]='0';
}
else if(PIN==0x03)
{
x[0]='1';
x[1]='1';
x[2]='0';
}
else if(PIN==0x04)
{
x[0]='0';
x[1]='0';
x[2]='1';
}
else if(PIN==0x05)
{
x[0]='1';
x[1]='0';
x[2]='1';
}
else if(PIN==0x06)
{
x[0]='0';
x[1]='1';
x[2]='1';
}
else if(PIN==0x07)
{
x[0]='1';
x[1]='1';
x[2]='1';
}
else
{
printf("\n Invalid hexa digit %u",(unsigned)PIN);
}
//selection command
return x;
}
else if(sw == 2)
{
if(PIN==0x00)
{
x[3]='0';
x[4]='0';
x[5]='0';
}
else if(PIN==0X01)
{
x[3]='1';
x[4]='0';
x[5]='0';
}
else if(PIN==0x02)
{
x[3]='0';
x[4]='1';
x[5]='0';
}
else if(PIN==0x03)
{
x[3]='1';
x[4]='1';
x[5]='0';
}
else if(PIN==0x04)
{
x[3]='0';
x[4]='0';
x[5]='1';
}
else if(PIN==0x05)
{
x[3]='1';
x[4]='0';
x[5]='1';
}
else if(PIN==0x06)
{
x[3]='0';
x[4]='1';
x[5]='1';
}
else if(PIN==0x07)
{
x[3]='1';
x[4]='1';
x[5]='1';
}
else
{
printf("\n Invalid hexa digit %u",(unsigned)PIN);
}
//selection command
return x;
}
else if(sw == 3)
{
if(PIN==0x00)
{
x[6]='0';
x[7]='0';
x[8]='0';
}
else if(PIN==0X01)
{
x[6]='1';
x[7]='0';
x[8]='0';
}
else if(PIN==0x02)
{
x[6]='0';
x[7]='1';
x[8]='0';
}
else if(PIN==0x03)
{
x[6]='1';
x[7]='1';
x[8]='0';
}
else if(PIN==0x04)
{
x[6]='0';
x[7]='0';
x[8]='1';
}
else if(PIN==0x05)
{
x[6]='1';
x[7]='0';
x[8]='1';
}
else if(PIN==0x06)
{
x[6]='0';
x[7]='1';
x[8]='1';
}
else if(PIN==0x07)
{
x[6]='1';
x[7]='1';
x[8]='1';
}
else
{
printf("\n Invalid hexa digit %u",(unsigned)PIN);
}
//selection command
return x;
}
else if(sw == 4)
{
if(PIN==0x00)
{
x[9]='0';
x[10]='0';
x[11]='0';
}
else if(PIN==0X01)
{
x[9]='1';
x[10]='0';
x[11]='0';
}
else if(PIN==0x02)
{
x[9]='0';
x[10]='1';
x[11]='0';
}
else if(PIN==0x03)
{
x[9]='1';
x[10]='1';
x[11]='0';
}
else if(PIN==0x04)
{
x[9]='0';
x[10]='0';
x[11]='1';
}
else if(PIN==0x05)
{
x[9]='1';
x[10]='0';
x[11]='1';
}
else if(PIN==0x06)
{
x[9]='0';
x[10]='1';
x[11]='1';
}
else if(PIN==0x07)
{
x[9]='1';
x[10]='1';
x[11]='1';
}
else
{
printf("\n Invalid hexa digit %u",(unsigned)PIN);
}
//selection command
return x;
}
else if(sw == 5)
{
if(PIN==0x00)
{
x[12]='0';
x[13]='0';
x[14]='0';
}
else if(PIN==0X01)
{
x[12]='1';
x[13]='0';
x[14]='0';
}
else if(PIN==0x02)
{
x[12]='0';
x[13]='1';
x[14]='0';
}
else if(PIN==0x03)
{
x[12]='1';
x[13]='1';
x[14]='0';
}
else if(PIN==0x04)
{
x[12]='0';
x[13]='0';
x[14]='1';
}
else if(PIN==0x05)
{
x[12]='1';
x[13]='0';
x[14]='1';
}
else if(PIN==0x06)
{
x[12]='0';
x[13]='1';
x[14]='1';
}
else if(PIN==0x07)
{
x[12]='1';
x[13]='1';
x[14]='1';
}
else
{
printf("\n Invalid hexa digit %u",(unsigned)PIN);
}
//selection command
return x;
}
else if(sw == 6)
{
if(PIN==0x00)
{
x[15]='0';
x[16]='0';
x[17]='0';
x[18]='0';
}
else if(PIN==0x01)
{
x[15]='1';
x[16]='0';
x[17]='0';
x[18]='0';
}
else if(PIN==0x02)
{
x[15]='0';
x[16]='1';
x[17]='0';
x[18]='0';
}
else if(PIN==0x03)
{
x[15]='1';
x[16]='1';
x[17]='0';
x[18]='0';
}
else if(PIN==0x04)
{
x[15]='0';
x[16]='0';
x[17]='1';
x[18]='0';
}
else if(PIN==0x05)
{
x[15]='1';
x[16]='0';
x[17]='1';
x[18]='0';
}
else if(PIN==0x06)
{
x[15]='0';
x[16]='1';
x[17]='1';
x[18]='0';
}
else if(PIN==0x07)
{
x[15]='1';
x[16]='1';
x[17]='1';
x[18]='0';
}
else if(PIN==0x08)
{
x[15]='0';
x[16]='0';
x[17]='0';
x[18]='1';
}
else if(PIN==0x09)
{
x[15]='1';
x[16]='0';
x[17]='0';
x[18]='1';
}
else if(PIN==0x0A)
{
x[15]='0';
x[16]='1';
x[17]='0';
x[18]='1';
}
else if(PIN==0x0B)
{
x[15]='1';
x[16]='1';
x[17]='0';
x[18]='1';
}
else if(PIN==0x0C)
{
x[15]='0';
x[16]='0';
x[17]='1';
x[18]='1';
}
else if(PIN==0x0D)
{
x[15]='1';
x[16]='0';
x[17]='1';
x[18]='1';
}
else if(PIN==0x0E)
{
x[15]='0';
x[16]='1';
x[17]='1';
x[18]='1';
}
else if(PIN==0x0F)
{
x[15]='1';
x[16]='1';
x[17]='1';
x[18]='1';
}
else
{
printf("\n Invalid hexa digit %u",(unsigned)PIN);
}
return x;
}
else if(sw == 7)
{
if(PIN==0x00)
{
x[19]='0';
x[20]='0';
x[21]='0';
}
else if(PIN==0X01)
{
x[19]='1';
x[20]='0';
x[21]='0';
}
else if(PIN==0x02)
{
x[19]='0';
x[20]='1';
x[21]='0';
}
else if(PIN==0x03)
{
x[19]='1';
x[20]='1';
x[21]='0';
}
else if(PIN==0x04)
{
x[19]='0';
x[20]='0';
x[21]='1';
}
else if(PIN==0x05)
{
x[19]='1';
x[20]='0';
x[21]='1';
}
else if(PIN==0x06)
{
x[19]='0';
x[20]='1';
x[21]='1';
}
else if(PIN==0x07)
{
x[19]='1';
x[20]='1';
x[21]='1';
}
else
{
printf("\n Invalid hexa digit %u",(unsigned)PIN);
}
//selection command
return x;
}
}
Main function
int main()
{
int sw = 1,i,size=22;
char S3=0,S2=1,S1=0,S0=1;
unsigned char PIN;
PIN=set_lpx_var(S0,S1,S2,S3);
unsigned char *x;
unsigned char *d;
x=command(PIN,sw,size);//sw = 1
for (i = 0; i < size; i++)
{
if (x[i]!='\0')
{
d[i]=x[i];
}
}
sw = 2;
S3=0,S2=1,S1=1,S0=1;
PIN=set_lpx_var(S0,S1,S2,S3);
x=command(PIN,sw,size);
for (i = 0; i < size; i++)
{
if (x[i]!='\0')
{
d[i]=x[i];
}
}
sw = 3;
S3=0,S2=1,S1=0,S0=0;
PIN=set_lpx_var(S0,S1,S2,S3);
x=command(PIN,sw,size);
for (i = 0; i < size; i++)
{
if (x[i]!='\0')
{
d[i]=x[i];
}
}
sw = 4;
S3=0,S2=0,S1=1,S0=1;
PIN=set_lpx_var(S0,S1,S2,S3);
x=command(PIN,sw,size);
for (i = 0; i < size; i++)
{
if (x[i]!='\0')
{
d[i]=x[i];
}
}
sw = 5;
S3=0,S2=1,S1=1,S0=0;
PIN=set_lpx_var(S0,S1,S2,S3);
x=command(PIN,sw,size);
for (i = 0; i < size; i++)
{
if (x[i]!='\0')
{
d[i]=x[i];
}
}
sw = 6;
S3=1,S2=1,S1=1,S0=0;
PIN=set_lpx_var(S0,S1,S2,S3);
x=command(PIN,sw,size);
for (i = 0; i < size; i++)
{
if (x[i]!='\0')
{
d[i]=x[i];
}
}
sw = 7;
S3=0,S2=1,S1=1,S0=0;
PIN=set_lpx_var(S0,S1,S2,S3);
x=command(PIN,sw,size);
for (i = 0; i < size; i++)
{
if (x[i]!='\0')
{
d[i]=x[i];
}
}
for (i = 0; i < size; i++)
{
{
printf("Value at %i is %c",i,d[i]);
}
}
}
A quick way to optimize you first function while reducing the possibility for errors:
//Function to get hex condition
unsigned char set_lpx_var(char s0, char s1, char s2, char s3)
{
unsigned char result = (unsigned char)(((s3 != 0) << 3) + ((s2 != 0) << 2)
+ ((s1 != 0) << 1) + (s0 != 0));
printf("\n Obtained hexa digit %u", result);
return result;
}
Function #2:
unsigned char* command(unsigned char PIN,int sw,int size)
{
unsigned char* x;
size_t offset = sw - 1;
if (PIN & 0x08) // hard to know from your code what to do in case
// of error here.
{
printf("\n Invalid hexa digit %u", PIN);
return NULL;
}
if (size < 22 || (sw < 1 || 7 < sw)) // avoid out-of-bounds errors
{
printf("\n Invalid buffer size %d", size);
return NULL;
}
x = (unsigned char*)malloc(size); // why not new ?
// why not passing an array for result?
if (!x)
return NULL;
memset(x, 0, size); // dynamic memory needs to be initialized.
//select line assignment to array
size_t offset = sw - 1;
x[offset + 0] = (PIN & 0x01) ? '1' : '0';
x[offset + 1] = (PIN & 0x02) ? '1' : '0';
x[offset + 2] = (PIN & 0x04) ? '1' : '0';
return x;
}
As for main(), you do not check for allocation errors in return value from command(), you leak every single buffer returned by command(), and you assign values into d, which is an uninitialized pointer, this very likely generates a segmentation fault.
unsigned char *d; // <-- d is an uninitialized pointer
x=command(PIN,sw,size);//sw = 1, ****x is assigned a block of memory within command so that's good****
for (i = 0; i < size; i++)
{
if (x[i]!='\0')
{
d[i]=x[i]; // ****<-- where did you assign d to a block of memory?****
}
}
The most obvious issue I see is the assignment to the uninitialized pointer d. You need to allocate a block of memory for that. There could be other problems in the program too which you'll need to debug in order to find.

Arduino LCD game not displaying

I am getting crazy on my Snake LCD game.
I use an Arduino Mega and I'd like to use the LCD screen and the PmodKYPD for my Snake game. The problem is that it will not display anything, no matter which key I will press.
Here is my code:
#include <LiquidCrystal.h>
#include "Keypad.h"
byte mySnake[8][8] =
{
{ B00000,
B00000,
B00011,
B00110,
B01100,
B11000,
B00000,
},
{ B00000,
B11000,
B11110,
B00011,
B00001,
B00000,
B00000,
},
{ B00000,
B00000,
B00000,
B00000,
B00000,
B11111,
B01110,
},
{ B00000,
B00000,
B00011,
B01111,
B11000,
B00000,
B00000,
},
{ B00000,
B11100,
B11111,
B00001,
B00000,
B00000,
B00000,
},
{ B00000,
B00000,
B00000,
B11000,
B01101,
B00111,
B00000,
},
{ B00000,
B00000,
B01110,
B11011,
B11111,
B01110,
B00000,
},
{ B00000,
B00000,
B00000,
B01000,
B10000,
B01000,
B00000,
}
};
// keypad type definition
const byte ROWS = 4; //four rows
const byte COLS = 4; //three columns
char keys[ROWS][COLS] =
{{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'0','F','E','D'}};
byte rowPins[ROWS] = {
37, 36, 35, 34}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {
33,32, 31, 30}; // connect to the column pinouts of the keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
boolean levelz[5][2][16] = {
{{false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false},
{false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false}},
{{true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,true},
{true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,true}},
{{true,false,false,false,true,false,false,false,false,false,false,true,false,false,false,true},
{true,false,false,false,false,false,false,false,true,false,false,false,false,false,false,true}},
{{true,false,true,false,false,false,false,false,false,true,false,false,false,true,false,false},
{false,false,false,false,true,false,false,true,false,false,false,true,false,false,false,true}}
};
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
unsigned long time, timeNow;
int gameSpeed;
boolean skip, gameOver, gameStarted;
int olddir;
int selectedLevel,levels;
int NUM_KEYS = 5;
int adc_key_in;
int key=-1;
char key_read;
int oldkey=-1;
boolean x[16][80];
byte myChar[8];
byte nullChar[8] = { 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0 };
boolean special;
struct partdef
{
int row,column,dir; //0 - up, 1 - down, 2 - right, 3 - left
struct partdef *next;
};
typedef partdef part;
part *head, *tail;
int i,j,collected;
long pc,pr;
void drawMatrix()
{
int cc=0;
if (!gameOver)
{
x[pr][pc] = true;
//for (i=0;i<8;i++) lcd.createChar(i, nullChar);
for(int r=0;r<2;r++)
{
for(int c=0;c<16;c++)
{
special = false;
for(int i=0;i<8;i++)
{
byte b=B00000;
if (x[r*8+i][c*5+0]) {b+=B10000; special = true;}
if (x[r*8+i][c*5+1]) {b+=B01000; special = true;}
if (x[r*8+i][c*5+2]) {b+=B00100; special = true;}
if (x[r*8+i][c*5+3]) {b+=B00010; special = true;}
if (x[r*8+i][c*5+4]) {b+=B00001; special = true;}
myChar[i] = b;
}
if (special)
{
lcd.createChar(cc, myChar);
lcd.setCursor(c,r);
lcd.write(byte(cc));
cc++;
}
else
{
lcd.setCursor(c,r);
if (levelz[selectedLevel][r][c]) lcd.write(255);
else lcd.write(254);
}
}
}
}
}
void freeList()
{
part *p,*q;
p = tail;
while (p!=NULL)
{
q = p;
p = p->next;
free(q);
}
head = tail = NULL;
}
void gameOverFunction()
{
delay(1000);
lcd.clear();
freeList();
lcd.setCursor(3,0);
lcd.print("Game Over!");
lcd.setCursor(4,1);
lcd.print("Score: ");
lcd.print(collected);
delay(1000);
}
void growSnake()
{
part *p;
p = (part*)malloc(sizeof(part));
p->row = tail->row;
p->column = tail->column;
p->dir = tail->dir;
p->next = tail;
tail = p;
}
void newPoint()
{
part *p;
p = tail;
boolean newp = true;
while (newp)
{
pr = random(16);
pc = random(80);
newp = false;
if (levelz[selectedLevel][pr / 8][pc / 5]) newp=true;
while (p->next != NULL && !newp)
{
if (p->row == pr && p->column == pc) newp = true;
p = p->next;
}
}
if (collected < 13 && gameStarted) growSnake();
}
void moveHead()
{
switch(head->dir) // 1 step in direction
{
case 0: head->row--; break;
case 1: head->row++; break;
case 2: head->column++; break;
case 3: head->column--; break;
default : break;
}
if (head->column >= 80) head->column = 0;
if (head->column < 0) head->column = 79;
if (head->row >= 16) head->row = 0;
if (head->row < 0) head->row = 15;
if (levelz[selectedLevel][head->row / 8][head->column / 5]) gameOver = true; // wall collision check
part *p;
p = tail;
while (p != head && !gameOver) // self collision
{
if (p->row == head->row && p->column == head->column) gameOver = true;
p = p->next;
}
if (gameOver)
gameOverFunction();
else
{
x[head->row][head->column] = true;
if (head->row == pr && head->column == pc) // point pickup check
{
collected++;
if (gameSpeed < 25) gameSpeed+=3;
newPoint();
}
}
}
void moveAll()
{
part *p;
p = tail;
x[p->row][p->column] = false;
while (p->next != NULL)
{
p->row = p->next->row;
p->column = p->next->column;
p->dir = p->next->dir;
p = p->next;
}
moveHead();
}
void createSnake(int n) // n = size of snake
{
for (i=0;i<16;i++)
for (j=0;j<80;j++)
x[i][j] = false;
part *p, *q;
tail = (part*)malloc(sizeof(part));
tail->row = 7;
tail->column = 39 + n/2;
tail->dir = 3;
q = tail;
x[tail->row][tail->column] = true;
for (i = 0; i < n-1; i++) // build snake from tail to head
{
p = (part*)malloc(sizeof(part));
p->row = q->row;
p->column = q->column - 1; //initial snake id placed horizoltally
x[p->row][p->column] = true;
p->dir = q->dir;
q->next = p;
q = p;
}
if (n>1)
{
p->next = NULL;
head = p;
}
else
{
tail->next = NULL;
head = tail;
}
}
void startF()
{
gameOver = false;
gameStarted = false;
selectedLevel = 1;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Select level: 1");
for(i=0;i<8;i++)
{
lcd.createChar(i,mySnake[i]);
lcd.setCursor(i+4,1);
lcd.write(byte(i));
}
collected = 0;
gameSpeed = 8;
createSnake(3);
time = 0;
}
void setup()
{
levels = 5; //number of lvls
lcd.begin(16, 2);
startF();
}
void loop()
{
if (!gameOver && !gameStarted)
{
key_read = keypad.getKey(); // get key press
key = key_read - '0';
if (key != oldkey) // if keypress is detected
{
delay(50); // wait for debounce time
key_read = keypad.getKey(); // get key press
key = key_read - '0';
if (key != oldkey)
{
oldkey = key;
if (key >=0)
{
olddir = head->dir;
if (key==1 && selectedLevel<levels) selectedLevel++;
if (key==2 && selectedLevel>1) selectedLevel--;
if (key==4)
{
lcd.clear();
selectedLevel--;
newPoint();
gameStarted = true;
}
else
{
lcd.setCursor(14,0);
lcd.print(selectedLevel);
}
}
}
}
}
if (!gameOver && gameStarted)
{
skip = false; //skip the second moveAll() function call if the first was made
key_read = keypad.getKey(); // get key press
key = key_read - '0';
if (key != oldkey) // if keypress is detected
{
delay(50); // wait for debounce time
key_read = keypad.getKey(); // get key press
key = key_read - '0';
if (key != oldkey)
{
oldkey = key;
if (key >=0)
{
olddir = head->dir;
if (key==0 && head->dir!=3) head->dir = 2;
if (key==1 && head->dir!=1) head->dir = 0;
if (key==2 && head->dir!=0) head->dir = 1;
if (key==3 && head->dir!=2) head->dir = 3;
if (olddir != head->dir)
{
skip = true;
delay(1000/gameSpeed);
moveAll();
drawMatrix();
}
}
}
}
if (!skip)
{
timeNow = millis();
if (timeNow - time > 1000 / gameSpeed)
{
moveAll();
drawMatrix();
time = millis();
}
}
}
if(gameOver)
{
key_read = keypad.getKey(); // get key press
key = key_read - '0';
if (key != oldkey) // if keypress is detected
{
delay(50); // wait for debounce time
key_read = keypad.getKey(); // get key press
key = key_read - '0';
if (key != oldkey)
{
oldkey = key;
if (key >=0)
{
startF();
}
}
}
}
}
Does anyone know something about this issue?

Why does this segfault only when I move up (and how to fix)? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have been trying to make a basic game using SFML and C++, but when I walk upwards, my game segfaults and crashes.
The segfault occurs on line 5 of this function inside my character class:
bool character::collision_check(character *player, backgroundItem *obj, char direction, bool isRunning)
{
sf::Vector2f player_pos = player->_sprite.getPosition();
sf::Vector2f obj_pos = obj->_sprite.getPosition();
int height = obj->height;
int width = obj->width;
if (direction == 'u')
{
if (isRunning)
{
if ((player_pos.y - 8) == (obj_pos.y + (height/2)))
{
return 0;
}
else if ((player_pos.y - 9) == (obj_pos.y + (height/2)))
{
return 0;
}
else if ((player_pos.y - 10) == (obj_pos.y + (height/2)))
{
return 1;
}
}
else if ((player_pos.y - 8) == (obj_pos.y + (height/2)))
{
return 0;
}
}
else if (direction == 'd')
{
if (isRunning)
{
if ((player_pos.y + 8) == (obj_pos.y - (height/2)))
{
return 0;
}
else if ((player_pos.y + 9) == (obj_pos.y - (height/2)))
{
return 0;
}
else if ((player_pos.y + 10) == (obj_pos.y - (height/2)))
{
return 1;
}
}
else if ((player_pos.y + 8) == (obj_pos.y - (height/2)))
{
return 0;
}
}
else if (direction == 'l')
{
if (isRunning)
{
if ((player_pos.x - 8) == (obj_pos.x + (width/2)))
{
return 0;
}
else if ((player_pos.x - 9) == (obj_pos.x + (width/2)))
{
return 0;
}
else if ((player_pos.x - 10) == (obj_pos.x + (width/2)))
{
return 1;
}
}
else if ((player_pos.x - 8) == (obj_pos.x + (width/2)))
{
return 0;
}
}
else if (direction == 'r')
{
if (isRunning)
{
if ((player_pos.x + 8) == (obj_pos.x - (width/2)))
{
return 0;
}
else if ((player_pos.x + 9) == (obj_pos.x - (width/2)))
{
return 0;
}
else if ((player_pos.x + 10) == (obj_pos.x - (width/2)))
{
return 1;
}
}
else if ((player_pos.x + 8) == (obj_pos.x - (width/2)))
{
return 0;
}
}
return 1;
}
which is called multiple times by the walk function in my player class:
void player::walk(character *player, sf::View *main, backgroundItem* obj)
{
bool canMove = true;
bool isRunning = false;
bool move_amount[4];
short speed = 1;
if(sf::Keyboard::isKeyPressed(sf::Keyboard::LShift) || sf::Keyboard::isKeyPressed(sf::Keyboard::RShift))
{
isRunning = true;
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::S))
{
if(player->player_texture_state == 0)
{
player->_sprite.setTexture(player->_textures[1]);
player->player_texture_state = 1;
for(int i=0;i<5;i++)
{
move_amount[i] = player->collision_check(player, obj, 'd', isRunning);
obj++;
if (move_amount[i] == 0)
{
canMove = false;
}
else
{
speed = move_amount[i];
}
}
if (canMove)
{
if (isRunning)
{
speed *= 2;
}
player->_sprite.move(0, speed);
main->move(0, speed);
}
}
else if(player->player_texture_state == 1)
{
player->_sprite.setTexture(player->_textures[0]);
player->player_texture_state = 2;
}
else if(player->player_texture_state == 2)
{
player->_sprite.setTexture(player->_textures[2]);
player->player_texture_state = 3;
for(int i=0;i<5;i++)
{
move_amount[i] = player->collision_check(player, obj, 'd', isRunning);
obj++;
if (move_amount[i] == 0)
{
canMove = false;
}
else
{
speed = move_amount[i];
}
}
if (canMove)
{
if (isRunning)
{
speed *= 2;
}
player->_sprite.move(0, speed);
main->move(0, speed);
}
}
else if(player->player_texture_state == 3)
{
player->_sprite.setTexture(player->_textures[0]);
player->player_texture_state = 0;
}
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::A))
{
if(player->player_texture_state == 0)
{
player->_sprite.setTexture(player->_textures[4]);
player->player_texture_state = 1;
for(int i=0;i<5;i++)
{
move_amount[i] = player->collision_check(player, obj, 'l', isRunning);
obj++;
if (move_amount[i] == 0)
{
canMove = false;
}
else
{
speed = move_amount[i];
}
}
if (canMove)
{
if (isRunning)
{
speed *= 2;
}
player->_sprite.move(-speed, 0);
main->move(-speed, 0);
}
}
else if(player->player_texture_state == 1)
{
player->_sprite.setTexture(player->_textures[3]);
player->player_texture_state = 2;
}
else if(player->player_texture_state == 2)
{
player->_sprite.setTexture(player->_textures[5]);
player->player_texture_state = 3;
for(int i=0;i<5;i++)
{
move_amount[i] = player->collision_check(player, obj, 'l', isRunning);
obj++;
if (move_amount[i] == 0)
{
canMove = false;
}
else
{
speed = move_amount[i];
}
}
if (canMove)
{
if (isRunning)
{
speed *= 2;
}
player->_sprite.move(-speed, 0);
main->move(-speed, 0);
}
}
else if(player->player_texture_state == 3)
{
player->_sprite.setTexture(player->_textures[3]);
player->player_texture_state = 0;
}
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::D))
{
if(player->player_texture_state == 0)
{
player->_sprite.setTexture(player->_textures[7]);
player->player_texture_state = 1;
for(int i=0;i<5;i++)
{
move_amount[i] = player->collision_check(player, obj, 'r', isRunning);
obj++;
if (move_amount[i] == 0)
{
canMove = false;
}
else
{
speed = move_amount[i];
}
}
if (canMove)
{
if (isRunning)
{
speed *= 2;
}
player->_sprite.move(speed, 0);
main->move(speed, 0);
}
}
else if(player->player_texture_state == 1)
{
player->_sprite.setTexture(player->_textures[6]);
player->player_texture_state = 2;
}
else if(player->player_texture_state == 2)
{
player->_sprite.setTexture(player->_textures[8]);
player->player_texture_state = 3;
for(int i=0;i<5;i++)
{
move_amount[i] = player->collision_check(player, obj, 'r', isRunning);
obj++;
if (move_amount[i] == 0)
{
canMove = false;
}
else
{
speed = move_amount[i];
}
}
if (canMove)
{
if (isRunning)
{
speed *= 2;
}
player->_sprite.move(speed, 0);
main->move(speed, 0);
}
}
else if(player->player_texture_state == 3)
{
player->_sprite.setTexture(player->_textures[6]);
player->player_texture_state = 0;
}
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::W))
{
if(player->player_texture_state == 0)
{
player->_sprite.setTexture(player->_textures[10]);
player->player_texture_state = 1;
for(int i=0;i<5;i++)
{
move_amount[i] = player->collision_check(player, obj, 'u', isRunning);
obj++;
if (move_amount[i] == 0)
{
canMove = false;
}
else
{
speed = move_amount[i];
}
}
if (canMove)
{
if (isRunning)
{
speed *= 2;
}
player->_sprite.move(0, -speed);
main->move(0, -speed);
}
}
else if(player->player_texture_state == 1)
{
player->_sprite.setTexture(player->_textures[9]);
player->player_texture_state = 2;
}
else if(player->player_texture_state == 2)
{
player->_sprite.setTexture(player->_textures[10]);
player->player_texture_state = 1;
for(int i=0;i<5;i++)
{
move_amount[i] = player->collision_check(player, obj, 'u', isRunning);
obj++;
if (move_amount[i] == 0)
{
canMove = false;
}
else
{
speed = move_amount[i];
}
}
if (canMove)
{
if (isRunning)
{
speed *= 2;
}
player->_sprite.move(0, -speed);
main->move(0, -speed);
}
}
else if(player->player_texture_state == 3)
{
player->_sprite.setTexture(player->_textures[9]);
player->player_texture_state = 0;
}
}
}
The part that I don't understand is why this only segfaults when I move up (by pressing 'w'). When I move in any other direction it works fine, even though the collision_check function goes through line 5 every single time it is called.
When debugging with gdb it tells me:
Program received signal SIGSEGV, Segmentation fault.
0x0804bef3 in character::collision_check (this=0xbfffe840, player=0xbfffe840,
obj=0xbfffffa0, direction=117 'u', isRunning=false)
at character_class.cpp:53
53 int height = obj->height;
and when I ask it to print the value of obj->height it says:
Cannot access memory at address 0xc00000d4
Any help you can give me with this problem would be greatly appreciated, this has been driving me mad!
EDIT
The problem was as stated in user2421739's answer, but as requested here is the code to make it Minimal, Complete and Verifiable:
Main.cpp:
#include "header.hpp"
#include "backgroundItem_class.hpp"
#include "character_class.hpp"
#include "player_class.hpp"
int newID(int* currentID)
{
return *currentID++;
}
int main()
{
int currentID = 0;
sf::RenderWindow window(sf::VideoMode(1024, 768), "Game", sf::Style::Fullscreen);
window.setVerticalSyncEnabled(true);
sf::View main(sf::Vector2f(500, 350), sf::Vector2f(300, 200));
player player("Images/Player-0.png", "Images/Player-1.png", "Images/Player-2.png", "Images/Player-3.png",
"Images/Player-4.png", "Images/Player-5.png", "Images/Player-6.png", "Images/Player-7.png",
"Images/Player-8.png", "Images/Player-9.png", "Images/Player-10.png", "Images/Player-11.png");
backgroundItem wall_1("Images/Wall-h.png", 64, 1, 500, 278, 128, 2, newID(&currentID));
backgroundItem wall_2("Images/Wall-l.png", 1, 64, 428, 350, 2, 128, newID(&currentID));
backgroundItem wall_3("Images/Wall-h.png", 64, 1, 500, 422, 128, 2, newID(&currentID));
backgroundItem wall_4("Images/Wall-l.png", 1, 64, 572, 350, 2, 128, newID(&currentID));
backgroundItem item_array[4] = {wall_1, wall_2, wall_3, wall_4};
while(window.isOpen())
{
player.walk(&player, &main, item_array);
sf::Event event;
while(window.pollEvent(event))
{
if((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape))
{
window.close();
}
}
window.setView(main);
window.clear(sf::Color::White);
window.draw(player._sprite);
window.draw(wall_1._sprite);
window.draw(wall_2._sprite);
window.draw(wall_3._sprite);
window.draw(wall_4._sprite);
window.display();
sf::sleep(sf::milliseconds(125));
}
return 0;
}
backgroundItem_class.hpp:
#ifndef BACKGROUNDITEM_CLASS
#define BACKGROUNDITEM_CLASS
#include "header.hpp"
using namespace std;
class backgroundItem
{
public:
backgroundItem(string, int, int, int, int, int, int, int);
backgroundItem();
sf::Sprite _sprite;
sf::Texture _texture;
int width;
int height;
int id;
};
#endif
backgroundItem_class.cpp:
#include "header.hpp"
#include "backgroundItem_class.hpp"
backgroundItem::backgroundItem(string filename, int originX, int originY, int positionX, int positionY, int width, int height, int id)
:width(width), height(height), id(id)
{
if(!_texture.loadFromFile(filename))
{
assert(false);
}
_sprite.setTexture(_texture);
_sprite.setOrigin(originX, originY);
_sprite.setPosition(positionX, positionY);
}
backgroundItem::backgroundItem()
{}
character_class.hpp:
#ifndef CHARACTER_CLASS
#define CHARACTER_CLASS
#include "header.hpp"
#include "backgroundItem_class.hpp"
using namespace std;
class character
{
public:
character(string, string, string, string, string, string, string, string, string, string, string, string);
character();
void setFilenames(string, string, string, string, string, string, string, string, string, string, string, string);
void setTextures(string[12]);
bool collision_check(character*, backgroundItem*, char, bool);
virtual void walk() {};
sf::Sprite _sprite;
sf::Texture _textures[12];
short player_texture_state;
protected:
string _filenames[12];
};
#endif
character_class.cpp:
#include "header.hpp"
#include "character_class.hpp"
#include "backgroundItem_class.hpp"
void character::setFilenames(std::string file_a, std::string file_b, std::string file_c, std::string file_d, std::string file_e, std::string file_f, std::string file_g, std::string file_h, std::string file_i, std::string file_j, std::string file_k, std::string file_l)
{
_filenames[0] = file_a;
_filenames[1] = file_b;
_filenames[2] = file_c;
_filenames[3] = file_d;
_filenames[4] = file_e;
_filenames[5] = file_f;
_filenames[6] = file_g;
_filenames[7] = file_h;
_filenames[8] = file_i;
_filenames[9] = file_j;
_filenames[10] = file_k;
_filenames[11] = file_l;
}
void character::setTextures(std::string _filenames[12])
{
for(int i=0; i<12; i++)
{
if(!_textures[i].loadFromFile(_filenames[i]))
{
assert(false);
}
}
}
character::character(std::string file_a, std::string file_b, std::string file_c, std::string file_d, std::string file_e, std::string file_f, std::string file_g, std::string file_h, std::string file_i, std::string file_j, std::string file_k, std::string file_l)
:player_texture_state(0)
{
setFilenames(file_a, file_b, file_c, file_d, file_e, file_f, file_g, file_h, file_i, file_j, file_k, file_l);
setTextures(_filenames);
_sprite.setTexture(_textures[0]);
_sprite.setOrigin(8, 8);
_sprite.setPosition(500, 350);
}
character::character()
:player_texture_state(0)
{}
/*And character::collision_check as up there*/
header.hpp:
#ifndef HEADER
#define HEADER
#include <string.h>
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include <assert.h>
#endif
player_class.hpp:
#ifndef PLAYER_CLASS
#define PLAYER_CLASS
#include "header.hpp"
#include "backgroundItem_class.hpp"
#include "character_class.hpp"
using namespace std;
class player: public character
{
public:
player(string, string, string, string, string, string, string, string, string, string, string, string);
void walk(character*, sf::View*, backgroundItem*);
short player_texture_state;
};
#endif
player_class.cpp:
#include "header.hpp"
#include "backgroundItem_class.hpp"
#include "character_class.hpp"
#include "player_class.hpp"
player::player(std::string file_a, std::string file_b, std::string file_c, std::string file_d, std::string file_e, std::string file_f, std::string file_g, std::string file_h, std::string file_i, std::string file_j, std::string file_k, std::string file_l)
:player_texture_state(0)
{
setFilenames(file_a, file_b, file_c, file_d, file_e, file_f, file_g, file_h, file_i, file_j, file_k, file_l);
setTextures(_filenames);
_sprite.setTexture(_textures[0]);
_sprite.setOrigin(8, 8);
_sprite.setPosition(500, 350);
}
/*With player::walk as up there*/
The main reason I didn't want to post it all was the length, this is as short as I can get it which still includes everything needed.
Also, thanks for everybody's help!
Your move_amount array has only four elements but your loops are accessing five elements. This leads to undefined behavior and is likely to be why the code crashes.
As noted in the comments, we cannot give an exact answer without more details. As noted in the previous answer, move_amount should be of length 5 otherwise the stack will be corrupted.
The debugger output may give a different clue on the crash however.
for(int i=0;i<5;i++)
{
move_amount[i] = player->collision_check(player, obj, 'u', isRunning);
obj++;
Could it be that the input argument obj is not an array or the array too short? The obj++ will move the pointer to the next element in the array. Similar to the issue with move_amount, going past the end will likely result in a segmentation fault.
That the pointer value spans a page boundary (0xc000000) gives more evidence for this theory.