As the title says, I have successfully compiled, linked and ran a program made in sfml-1.6 on Linux Mint 14. I used g++ for compiling. However as soon as I moved the source files to Windows and tried to compile to the Windows equivalent of the sfml libraries, it crashes. The program compiles and links just fine but it crashes BEFORE it reaches main. I have made sure I dont have any global objects/variables in my own .h files. But I cannot do it for the sfml library. I suspected that it might be because the library was broken so I ported the code for sfml 2.0., and the problem persists. Any clues on what I am doing wrong? I have also made sure I dont use any platform specific headers.
Here is my main.cpp
#include <SFML/System.hpp>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include "World.h"
#include <sstream>
#include <vector>
#include <zip.h>
enum states
{
MENU,
GAME,
PAUSE,
EXIT,
DIE
};
player plr;
sf::Clock timer;
void getKeys(const sf::Input& input);
std::string floatToString(float flt);
int main(int argc, char** argv)
{
sf::RenderWindow window(sf::VideoMode(1024, 768), "sfTest");
window.SetFramerateLimit(60);
sf::Music startSong;
sf::Music endSong;
sf::Music s1, s2, s3;
sf::String musicBy;
musicBy.SetText("Music by Kevin McLeod: www.incompetech.com");
if(!s1.OpenFromFile("Batty McFaddin.ogg"))
return -1;
if(!s2.OpenFromFile("Merry Go.ogg"))
return -1;
if(!s3.OpenFromFile("One-eyed Maestro.ogg"))
return -1;
if(!endSong.OpenFromFile("One-eyed Maestro.ogg"))
return -10;
if(!startSong.OpenFromFile("Comedic Juggernaut.ogg"))
return -15;
endSong.SetVolume(50);
std::vector<sf::Music*> playList;
std::vector<sf::Music*>::iterator mIt;
s1.SetVolume(25);
s2.SetVolume(25);
s3.SetVolume(25);
playList.push_back(&s2);
playList.push_back(&s3);
playList.push_back(&s1);
startSong.SetLoop(true);
startSong.SetVolume(50);
const sf::Input& input = window.GetInput();
plr.setSpeed(.5);
plr.setMaxSpeed(15.0);
plr.setJumpForce(.4f);
plr.setJumpSpeed(16.f);
int state = MENU;
sf::String str;
str.SetText("Welcome to fatrunning!");
sf::String str2;
str2.SetText("Developed by Echoes Entertainment");
str2.Move(0, 100);
sf::String cont;
cont.SetText("Please press enter to play...");
cont.Move(0, 30);
sf::String spd;
sf::String menuHelp;
menuHelp.SetText("Stand on the block equivalent to the level (0-15) and press TAB");
menuHelp.Move(0, 30);
float endTime = 60*5;
float curTime = 0;
sf::Sprite menu;
sf::Image mim;
mim.LoadFromFile("MenuBackground.png");
menu.SetImage(mim);
sf::String scr;
sf::String thanks("Thanks for playing! Your score was: ");
//sf::String tarantulas(" Tarantual tarantulas Everybody loves tarantulas if there's just fuzz where your hamster was it's propably because of tarantulas They're so soft and they're so furry And they're so cute if your vision's blurry all of mine got free but dont you worry though they're crawling up your wall in a big hurry Tarantual tarantulas Everybody loves tarantulas if there's just fuzz where your hamster was it's propably because of tarantulas Don't look now but i have a feeling there's one above you on your ceiling but when they crawl they never fall unless the person under them is nervous at all Tarantual tarantulas Everybody loves tarantulas if there's just fuzz where your hamster was it's propably because of tarantulas \t \t can you feel that itch on the top of your head it could be one of them crawling instead but it wont bite unless it senses fear so just stay calm til' it's gone in a year \t\t Tarantual tarantulas Everybody loves tarantulas if there's just fuzz where your hamster was it's propably because of tarantulas Tarantual tarantulas Everybody loves tarantulas if there's just fuzz where your hamster was it's propably because of tarantulas if there's just fuzz where your hamster was it's propably because of tarantulas Tarantulas tarantulas it's propably because of tarantulas");
//.tarantulas.Move(3000, 0);
thanks.Move(0, 30);
scr.Move(500, 30);
World world;
world.addLevel("lvl1", "lvl1.txt");
world.addLevel("lvl2", "lvl2.txt");
world.addLevel("lvl3", "lvl3.txt");
world.addLevel("lvl4", "lvl4.txt");
world.addLevel("lvl5", "lvl5.txt");
world.addLevel("lvl6", "lvl6.txt");
world.addLevel("lvl7", "lvl7.txt");
world.addLevel("lvl8", "lvl8.txt");
world.addLevel("lvl9", "lvl9.txt");
world.addLevel("lvl10", "lvl10.txt");
world.addLevel("lvl11", "lvl11.txt");
world.addLevel("lvl12", "lvl12.txt");
world.addLevel("lvl13", "lvl13.txt");
world.addLevel("lvl14", "lvl14.txt");
world.addLevel("lvl15", "lvl15.txt");
world.setMenuLevel("menu.txt");
world.regPlr(plr);
bool once = false;
bool unodos = false;
float finalScore = 0;
while (state != DIE)
{
sf::Event e;
while (window.GetEvent(e))
{
if ( e.Type == sf::Event::Closed )
{
window.Close();
state = EXIT;
}
if( e.Type == sf::Event::KeyPressed )
{
if(e.Key.Code == sf::Key::Return)
{
if(!unodos)
{
state = GAME;
unodos = true;
}
}
}
}
getKeys(input);
window.Clear();
switch(state)
{
case MENU:
if(startSong.GetStatus() == sf::Sound::Stopped)
startSong.Play();
window.Draw(menu);
window.Draw(str);
window.Draw(str2);
window.Draw(cont);
break;
case GAME:
if(startSong.GetStatus() == sf::Sound::Playing)
{
mIt = playList.begin();
(*mIt)->Play();
startSong.Stop();
}
if((*mIt)->GetStatus() == sf::Sound::Stopped)
{
mIt++;
if(mIt == playList.end())
mIt = playList.begin();
(*mIt)->Play();
}
timer.Reset();
spd.SetText(floatToString(endTime-plr.time));
world.drawWorld(window);
world.update(input);
plr.update();
window.Draw(plr.getSprite());
window.Draw(spd);
plr.time+=timer.GetElapsedTime();
if(plr.time >= endTime || world.quit)
{
state = EXIT;
plr.time = endTime;
}
if(world.atMenu)
state = PAUSE;
break;
case PAUSE:
if(startSong.GetStatus() == sf::Sound::Playing)
startSong.Stop();
spd.SetText(floatToString(endTime-plr.time));
plr.update();
world.drawWorld(window);
world.update(input);
window.Draw(plr.getSprite());
window.Draw(spd);
window.Draw(menuHelp);
if(!world.atMenu)
state = GAME;
if(world.quit)
state = EXIT;
break;
case EXIT:
if(!once)
{
endSong.Play();
(*mIt)->Stop();
world.addLevel("end", "end.txt");
world.setLevel("end");
once = true;
finalScore = plr.score;
finalScore += (endTime-plr.time);
}
//tarantulas.Move(-3.5, 0);
plr.update();
world.drawWorld(window);
window.Draw(plr.getSprite());
scr.SetText(floatToString(finalScore));
//window.Draw(tarantulas);
window.Draw(musicBy);
window.Draw(thanks);
window.Draw(scr);
if(world.curLvl->atEnd)
state = DIE;
break;
case DIE:
window.Close();
break;
default:
break;
}
window.Display();
}
return 0;
}
std::string floatToString(float flt)
{
std::stringstream ss;
ss << flt;
return ss.str();
}
void getKeys(const sf::Input& input)
{
if(input.IsKeyDown(sf::Key::D))
{
plr.isAcc = true;
plr.right();
}
else if(input.IsKeyDown(sf::Key::A))
{
plr.isAcc = true;
plr.left();
}
if(input.IsKeyDown(sf::Key::Space))
{
plr.isJump = false;
plr.jump();
}
if(!input.IsKeyDown(sf::Key::D) && !input.IsKeyDown(sf::Key::A))
{
plr.isAcc = false;
}
if(!input.IsKeyDown(sf::Key::Space))
plr.isJump = true;
}
That is the whole main.cpp, if you need to look at the other sources, ask me. But the program crashes BEFORE it reaches main. It doesn't even reach the enum define.
This could be due to any undefined or unspecified behavior in
the constructors of objects with static lifetime. One of the
most frequence causes, however, is order of initialization
issues. Do some of your objects with static lifetime use other
objects with static lifetime in their constructor? For example,
does the constructor for player use a static object defined in
World? Or even something from SFML? (A quick glance shows some
objects with static lifetime in the library. You shouldn't use
any of these in any of your constructors of objects with static
lifetime.)
Run the program in the debugger (windbg.exe), that should show you where the exception occurs, with helpful progress text in the output window about what's been loaded so far, any 'swallowed' exceptions, and you can take it from there.
It's possible the crash is due to some incompatibility between how the EXE was compiled and how the library was compiled... check your code-generation flags, character sets, etc.
Related
I made this code that shows a timer and pauses when you press spacebar:
#include <SFML/Graphics.hpp>
#include <iostream>
using namespace sf;
using namespace std;
void events();
bool pause, exitPause;
char key;
double timeFrame, timeTot = 0;
Clock timer;
Text text;
Font font;
RenderWindow window(VideoMode(800, 600), "Window", Style::Close);
int main()
{
font.loadFromFile("C:/Windows/Fonts/arial.ttf");
text.setFont(font);
text.setCharacterSize(15);
window.setFramerateLimit(120);
while (window.isOpen())
{
for (Event event; window.pollEvent(event);) {
if (event.type == Event::Closed)
window.close();
if (event.type == Event::TextEntered) {
key = std::tolower(static_cast<char>(event.text.unicode));
if (key == ' ') {
pause = !pause;
if (!pause) {
timer.restart();
}
}
}
}
if (!pause) {
timeFrame = timer.restart().asSeconds();
timeTot += timeFrame;
text.setString(to_string(timeTot));
window.clear();
window.draw(text);
}
window.display();
}
}
If you test, you will see something curious. When pausing by pressing the spacebar, window.display alternates between the last and the current displayed number.
But if I put window.clear and window.draw together with window.display, the problem does not happen.
if (!pause) {
timeFrame = timer.restart().asSeconds();
timeTot += timeFrame;
text.setString(to_string(timeTot));
}
window.clear();
window.draw(text);
window.display();
I thought windows.display, alone, would only show the last buffer.
What is the problem?
The moment you pause you stop updating the draw buffers. SFML is always double-buffered, and in each iteration you always need to parse input, update whatever needs updating, redraw the "hidden" frame, and then flip the buffers. This is basically a "Game Loop" pattern.
In your code you always parse input, update the timer and pause state based on that, and you always flip the buffers (with window.display()). You only redraw the "hidden" frame buffer if the state is not paused, however.
So, you are seeing the expected output, and you found the correct solution.
As an aside, there are indeed several style issues in your code, including uninitialized variables, which is always dangerous in C++.
I'm doing a game that uses a chronometer.
The game is written in C++ and I'm also using glade and GTK3.0
My problem is that when I start the game the chronometer doesn't work as it should..
I have created a file time.h with this code inside:
struct aTimer
{
bool running = false;
int hour_expired = 0;
int min_expired = 59;
int sec_expired = 50;
};
void start_time(aTimer *&t)
{
t->running = true;
}
void reset_time(aTimer *&t)
{
t->running = false;
t->sec_expired = 0;
t->min_expired = 0;
t->hour_expired = 0;
}
In my main file, I include it and also declare a new chronometer like this:
void start_time(aTimer *&);
void reset_time(aTimer *&);
aTimer *tempo = new aTimer;
Now, in my game, I have 2 windows, when i press play from the first window, the second window becomes visible and I hide the first one. When the second one is closed, the first becomes visible and the second invisible..
When the first window is closed, the application is closed.
In the struct, the bool running is false, because my idea was to make it true when you actually play the game (that is when you have the second window visible) and not at the start of the application..
So I've done this in the main file:
void start_game()
{
start_time(tempo);
}
gboolean update_time()
{
if (tempo->running)
{
if (tempo->sec_expired == 60)
{
tempo->sec_expired = 0;
(tempo->min_expired)++;
if (tempo->min_expired == 60)
{
tempo->min_expired = 0;
(tempo->hour_expired)++;
}
}
ostringstream oss;
GtkLabel *time = GTK_LABEL(gtk_builder_get_object(builder, "lblSec"));
oss<<(tempo->sec_expired)++;
gtk_label_set_text(time, oss.str().c_str());
oss.str("");
oss.clear();
time = GTK_LABEL(gtk_builder_get_object(builder, "lblMin"));
oss<<tempo->min_expired<<":";
gtk_label_set_text(time, oss.str().c_str());
oss.str("");
oss.clear();
time = GTK_LABEL(gtk_builder_get_object(builder, "lblHour"));
oss<<tempo->hour_expired<<":";
gtk_label_set_text(time, oss.str().c_str());
oss.str("");
oss.clear();
}
return tempo->running;
}
and in the main function of the main file i have also:
g_timeout_add_seconds(1, GSourceFunc(update_time), NULL);
If I start the application with the bool running = false, it won't work at all
If I start it the running = true, then it does work when i start the application, but as i come back to the "menu" and want to play another game, it won't start again.. The new time will just be the old time and won't increment anymore
I don't understand why though... Can someone help me?
Thank you
********************UPDATE************************
I tried the GTimer "option" as #José Fonte suggested but still can't come ahead..
This is an example that i tried..
#include <iostream>
#include <glib.h>
#include <sstream>
#include <gtk/gtk.h>
static GtkBuilder *builder;
using namespace std;
GTimer *timing;
bool start = false;
extern "C" void btnStartPause_click(GtkButton *button)
{
if (!start)
{
timing = g_timer_new();
start = true;
}
else
{
g_timer_stop(timing);
start = false;
}
}
gboolean update_time()
{
if (start)
{
gulong *micro;
double sec;
sec = g_timer_elapsed(timing, micro);
ostringstream oss;
GtkLabel *time = GTK_LABEL(gtk_builder_get_object(builder, "lblSec"));
oss<<(sec)++;
gtk_label_set_text(time, oss.str().c_str());
oss.str("");
oss.clear();
}
return start;
}
int main(int argc, char *argv[])
{
gtk_init(&argc, &argv);
builder = gtk_builder_new();
gtk_builder_add_from_file(builder,"glade.glade", NULL);
gtk_builder_connect_signals(builder, NULL);
// timing
g_timeout_add_seconds(1, GSourceFunc(update_time), NULL);
gtk_main();
return 0;
}
The problem again is.. I wanna start the timing when i click the btnStartPause button (not when i start the application), so i want it to start in the btnClick function..
But it seems like that the application tries instantly to do the gboolean update_time() function but since at the start of the application the boolean start is false, it just won't do the code, but when i click the button, so that the boolean start becomes true, it doesn't try again the gboolean update_time(), like it tried at the start of the application, and won't try it anymore.. I don't understand this..
This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 7 years ago.
When trying to compile my code in Code::Blocks I receive a bunch of Undefined reference errors. The code is below.
Header
#ifndef BLACKJACK_GAME
#define BLACKJACK_GAME
// A game of blackjack has a deck and two hands
#include "Deck.h"
#include "BlackjackHand.h"
// Different ways the game can end. The first states take precedence over
// over the latter states so check for the early ones first (like blackjack)!
// Note that a "natural 21" is when you are delt two cards totaling 21.
enum eGameState {
GAME_BLACKJACK_PUSH, // Both player and dealer have a natural 21
GAME_DEALER_BLACKJACK, // Dealer has a natural 21
GAME_PLAYER_BLACKJACK, // Player has a natural 21
GAME_DEALER_BUST, // The dealer has more than 21
GAME_PLAYER_BUST, // The player has more than 21
GAME_DEALER_WIN, // The dealer's score is higher than players
GAME_PLAYER_WIN, // The player's score is higher than dealers
GAME_PUSH // The scores are tied
};
class BlackjackGame
{
public:
BlackjackGame();
// Clear the players hands and shuffle the deck
void newGame();
// Play a single round of blackjack showing the output using
// the 'PDcurses' library (for color and card suits).
void playGameCurses();
// Display the deck on the screen (for debugging purposes)
void printDeckCurses();
// Print both players hands to the screen using 'PDCurses'
// If pShowDealerScore is true then the dealer's score is printed
// Otherwise, the dealer's score is shown as '??'
void printHandsCurses(bool pShowDealerScore = false) const;
// Determine the state of the game. Note that if you have not yet
// played a round since you constructed this object or called newGame()
// Then the state returned is not accurate.
eGameState getGameState() const;
private:
// A deck of cards for shufflying and dealing hands
Deck mDeck;
// The two hands for the player and the dealer
BlackjackHand mPlayer, mDealer;
// A helper function for prompting the player (internal use only)
char promptPlayerCurses();
// A helper function to quit the game (internal use only)
void quitGameCurses();
};
#endif
CPP
#include "BlackjackGame.h"
// The library used for our text based user interface
#include <curses.h>
// Normal text color for PDCurses (defined in main)
#define NORM_TEXT 1
// Default constructor (does nothing)
BlackjackGame::BlackjackGame() {}
/* newGame() - Clear the two hands so we are ready for a new game */
void BlackjackGame::newGame()
{
mDealer.clear();
mPlayer.clear();
}
/* playGameCurses() - Play a single round of poker with one human player and one
* dealer following standard Vegas rules. Uses PDCurses for input and output to
* the console.
*
* You must implement this method but you do not need to worry about curses. Call
* 'promptPlayerCurses() to show the hands and prompt the human player to hit, stand
* or quit. This method will return the key they pressed. You can also use
* quitGameCurses() to exit properly if the user chose to 'quit'.
*/
void BlackjackGame::playGameCurses()
{
// TODO: Shuffle the deck and deal the cards (make sure dealer's first card is hidden).
mDeck.shuffle();
mPlayer.takeCard(mDeck.dealCard());
mDealer.takeCard(mDeck.dealCard());
mDealer.hideCard();
mPlayer.takeCard(mDeck.dealCard());
mDealer.takeCard(mDeck.dealCard());
// TODO: Check for a 'natural 21' (blackjack) before playing
if ( mDealer.hasBlackjack() || mPlayer.hasBlackjack())
quitGameCurses();
// TODO: Allower human player to hit, stand and quit as needed (repeat until player is done)
int flag = 0;
while(flag!=1)
{
char input = promptPlayerCurses(); // This line is an example only, a placeholder
switch(input)
{
case 'h': mPlayer.takeCard(mDeck.dealCard());
break;
case 's': flag =1;
break;
case 'q': quitGameCurses();
break;
default: break;
}
}
// TODO: Play the 'dealer' hand according to vegas rules
mDealer.showCards();
while(vegasDealerWouldHit())
{
mDealer.takeCard(mDeck.dealCard());
}
}
/* promptPlayerCurses() - Show the hands and prompt the human player to hit, stand or quit.
* output: returns the single character entered by the player at the prompt.
* - 'h' means hit, 's' means stand
* - 'q' means you should immediatly quit (call 'quitGameCurses()')
*/
char BlackjackGame::promptPlayerCurses()
{
// Show the hands
printHandsCurses();
// Hit or stand?
attron(COLOR_PAIR(NORM_TEXT));
mvprintw(3, 0, "Hit, stand or Quit ('h', 's', 'q'): ");
refresh();
// Read and return a single character
return getch();
}
/* quitGameCurses() - End curses output and exit the program immediately */
void BlackjackGame::quitGameCurses()
{
// End curses output, then pause and exit
endwin();
system("pause");
exit(0);
}
/* printDeckCurses() - A handy function that displays the content of the game deck
* using curses.
*
* This can be handy for debugging your deck and making sure it is getting properly
* shuffled. It is presently used for the fancy opening screen.
*/
void BlackjackGame::printDeckCurses()
{
// Start at the upper left corner of the screen
move(0, 0);
// For all 52 cards
for(int i=1; i<=52; i++)
{
// Get the next card and print it
PrintableCard lCard = mDeck.dealCard();
lCard.printCurses();
// If we've output 13 cards then move down a row
if(i%13 == 0)
{
move(2*(i/13), 0);
}
else
{
// Switch back to normal text color and output ' ' characters
attron(COLOR_PAIR(NORM_TEXT));
if(lCard.getFaceValue() == VALUE_TEN) printw(" ");
else printw(" ");
}
}
}
/* printHandsCurses() - A function to display the current scores and hands for this game
* using curses.
*
* This function is used in promptPlayerCurses() to show the hands before asking them if
* they want to hit or stand. Note that it alsways clears the window before drawing.
*/
void BlackjackGame::printHandsCurses(bool pShowDealerScore) const
{
// Clear window
erase();
// Show dealer and player hands
attron(COLOR_PAIR(NORM_TEXT));
mvprintw(0, 0, "Player: %d\n", mPlayer.score());
move(1, 0); mPlayer.printCurses();
attron(COLOR_PAIR(NORM_TEXT));
if(pShowDealerScore)
{
mvprintw(0, 50, "Dealer: %d\n", mDealer.score());
}
else
{
mvprintw(0, 50, "Dealer: ??\n");
}
move(1, 50); mDealer.printCurses();
refresh();
}
/* getGameStat() - Examine the hands of both players and return the current state of
* the game using the eGameState enum.
*
* You must examine the state of the game by comparing the two hands (their scores and their
* number of cards) and return the appropriate constant from the eGameState enum. Assume
* that the game is over (i.e. the player and dealer have both either gone bust or decided
* to stand).
*/
eGameState BlackjackGame::getGameState() const
{
if(mDealer.hasBlackjack() && mPlayer.hasBlackjack())
{
return GAME_BLACKJACK_PUSH;
}
else if(mDealer.hasBlackjack())
{
return GAME_DEALER_BLACKJACK;
}
else if(mPlayer.hasBlackJack())
{
return GAME_PLAYER_BLACKJACK;
}
else if(mPlayer.score() > 21)
{
return GAME_PLAYER_BUST;
}
else if(mDealer.score() > 21)
{
return GAME_DEALER_BUST;
}
else if(mDealer.score() > mPlayer.score())
{
return GAME_DEALER_WIN;
}
else if(mDealer.score() < mPlayer.score())
{
return GAME_PLAYER_WIN;
}
else {
return GAME_PUSH;
}
}
}
Main
#include <cstdlib>
#include <iostream> // Standard input and output
#include <string>
using namespace std;
#include <curses.h>
#include "BlackjackGame.h"
// Three different types of text colors used with PDCurses
#define NORM_TEXT 1
#define WIN_TEXT 2
#define LOSE_TEXT 3
int main()
{
// Setup 'PDcurses'
initscr();
start_color();
// Define our colors text colors (foreground, background)
init_pair(NORM_TEXT, COLOR_WHITE, COLOR_BLACK);
init_pair(WIN_TEXT, COLOR_YELLOW, COLOR_BLACK);
init_pair(LOSE_TEXT, COLOR_RED, COLOR_BLACK);
// Define our card colors (these are declared in PrintableCard.h)
init_pair(BLACK_CARD, COLOR_BLACK, COLOR_WHITE);
init_pair(RED_CARD, COLOR_RED, COLOR_WHITE);
// Input from the user and a game object
char ch = '\0';
BlackjackGame myGame;
// Output a 'fancy' welcome screen
myGame.printDeckCurses();
attron(COLOR_PAIR(WIN_TEXT));
mvprintw(1, 13, "Welcome to Blackjack!");
mvprintw(5, 11, "Press any key to play ...");
refresh();
// Wait for input (the 'press any key to begin' thing)
ch = getch();
// Back to normal text to start the game
attron(COLOR_PAIR(NORM_TEXT));
do // Loop to play a new game until the user exits
{
// Restart and play a game (using curses)
myGame.newGame();
// Play a round of blackjack (most of the magic happens here!)
myGame.playGameCurses();
// Print the final status of the game
myGame.printHandsCurses(true);
// Print a game results message (use BOLD and the appropriate text color)
attron(A_BOLD);
switch(myGame.getGameState())
{
case GAME_BLACKJACK_PUSH:
attron(COLOR_PAIR(WIN_TEXT));
mvprintw(10, 25, "BLACKJACK TIE!!");
break;
case GAME_DEALER_BLACKJACK:
attron(COLOR_PAIR(LOSE_TEXT));
mvprintw(10, 25, "Dealer Blackjack. You lose.");
break;
case GAME_PLAYER_BLACKJACK:
attron(COLOR_PAIR(WIN_TEXT));
mvprintw(10, 25, "BLACKJACK! You win!");
break;
case GAME_DEALER_BUST:
attron(COLOR_PAIR(WIN_TEXT));
mvprintw(10, 25, "Dealer Bust. You Win!");
break;
case GAME_PLAYER_BUST:
attron(COLOR_PAIR(LOSE_TEXT));
mvprintw(10, 25, "BUST. You lose.");
break;
case GAME_DEALER_WIN:
attron(COLOR_PAIR(LOSE_TEXT));
mvprintw(10, 25, "You lose.");
break;
case GAME_PLAYER_WIN:
attron(COLOR_PAIR(WIN_TEXT));
mvprintw(10, 25, "You Win!");
break;
case GAME_PUSH:
attron(COLOR_PAIR(WIN_TEXT));
mvprintw(10, 25, "It's a tie!");
break;
}
// Turn off bold and return to normal text color
attroff(A_BOLD);
attron(COLOR_PAIR(NORM_TEXT));
// Prompt user to play again
mvprintw(20, 0, "Play again (y/n): ");
refresh();
ch = getch();
} while(ch != 'n');
// Close out 'PDCurses' and pause before exiting
endwin();
system("pause");
return 0;
}
In this program I am trying to create the game BlackJack, most of the game is in other files, but I do not receive errors in the other files. The errors come from the code inside of the Main. The errors are
undefined reference to `BlackjackGame::blackjackGame()
undefined reference to `BlackjackGame::printDeckCurses()
undefined reference to `BlackjackGame::newGame()
undefined reference to `BlackjackGame::playGameCurses()
undefined reference to `BlackjackGame::printedHandsCurses()
undefined reference to `BlackjackGame::getGameState()
With all of these errors coming from the main and these references in the header, that must be my problem, linking the two. Is that correct?
This problem is telling you that you are not linking in the BlackjackGame.o object file when you are building your executable or library.
You must fix your Makefile to link in this file in order to pass the linking stage.
Edit:
Seeing as how you are using Codeblocks for compilation, check these links out(as this error message means different things in different compilers):
undefined reference to function code blocks
Code::Blocks 10.05 Undefined reference to function
It looks like you need to add BlackJackGame.cpp to your project, based on the answer in link 2
Go to Project/Add files to add BlackJackGame source files to your Project, then re-build and that should work
In my project written in C++, I have FMOD currently working from my main.cpp. To help organize my engine I want to move my sound code to it's own translation unit. For some reason when I try to run my sound code from within my class, it doesn't play any sound. I'm not sure if it is because of incorrect assignment of the value or if there is a bigger issue that I don't know about. This is my class implementation:
//Sound.h
#ifndef SOUND_H
#define SOUND_H
#include <iostream>
#include "inc\fmod.hpp"
#include "inc\fmod_errors.h"
class Sound
{
public:
Sound(void);
~Sound(void);
void Init();
void FMODErrorCheck(FMOD_RESULT res);
void PlaySound();
void ResumeSound();
void PauseSound();
void Update();
private:
//sound
FMOD::System *sys;
FMOD_RESULT result;
size_t version; //this is just an unsigned int
FMOD_SPEAKERMODE speakerMode;
int numDrivers;
FMOD_CAPS caps;
char name[256];
FMOD::Sound *sound;
FMOD::Channel *channel;
bool quitFlag;
};
#endif
//Sound.cpp
#include "Sound.h"
Sound::Sound(void)
{
Init();
}
Sound::~Sound(void)
{
FMODErrorCheck(sound->release());
FMODErrorCheck(sys->release());
}
void Sound::Init()
{
// Create FMOD interface object
result = FMOD::System_Create(&sys);
FMODErrorCheck(result);
// Check version
result = sys->getVersion(&version);
FMODErrorCheck(result);
if(version < FMOD_VERSION)
{
std::cout << "Error! You are using an old version of FMOD " << version << ". This program requires " << FMOD_VERSION << std::endl;
exit(0);
}
// Get number of sound cards
result = sys->getNumDrivers(&numDrivers);
FMODErrorCheck(result);
// No sound cards (disable sound)
if(numDrivers == 0)
{
result = sys->setOutput(FMOD_OUTPUTTYPE_NOSOUND);
FMODErrorCheck(result);
}
// At least one sound card
else
{
// Get the capabilities of the default (0) sound card
result = sys->getDriverCaps(0, &caps, 0, &speakerMode);
FMODErrorCheck(result);
// Set the speaker mode to match that in Control Panel
result = sys->setSpeakerMode(speakerMode);
FMODErrorCheck(result);
// Increase buffer size if user has Acceleration slider set to off
if(caps & FMOD_CAPS_HARDWARE_EMULATED)
{
result = sys->setDSPBufferSize(1024, 10);
FMODErrorCheck(result);
}
// Get name of driver
result = sys->getDriverInfo(0, name, 256, 0);
FMODErrorCheck(result);
// SigmaTel sound devices crackle for some reason if the format is PCM 16-bit.
// PCM floating point output seems to solve it.
if(strstr(name, "SigmaTel"))
{
result = sys->setSoftwareFormat(48000, FMOD_SOUND_FORMAT_PCMFLOAT, 0, 0, FMOD_DSP_RESAMPLER_LINEAR);
FMODErrorCheck(result);
}
}
// Initialise FMOD
result = sys->init(100, FMOD_INIT_NORMAL, 0);
// If the selected speaker mode isn't supported by this sound card, switch it back to stereo
if(result == FMOD_ERR_OUTPUT_CREATEBUFFER)
{
result = sys->setSpeakerMode(FMOD_SPEAKERMODE_STEREO);
FMODErrorCheck(result);
result = sys->init(100, FMOD_INIT_NORMAL, 0);
}
FMODErrorCheck(result);
// Open music as a stream
//FMOD::Sound *song1, *song2, *effect;
//result = sys->createStream("Effect.mp3", FMOD_DEFAULT, 0, &sound);
//FMODErrorCheck(result);
result = sys->createSound("Effect.mp3", FMOD_DEFAULT, 0, &sound);
FMODErrorCheck(result);
// Assign each song to a channel and start them paused
//result = sys->playSound(FMOD_CHANNEL_FREE, sound, true, &channel);
//FMODErrorCheck(result);
// Songs should repeat forever
channel->setLoopCount(-1);
}
void Sound::FMODErrorCheck(FMOD_RESULT res)
{
if(res != FMOD_OK)
{
std::cout << "FMOD ERROR: (" << res << ") - " << FMOD_ErrorString(res) << std::endl;
//quitFlag = true;
}
}
void Sound::PlaySound()
{
sys->playSound(FMOD_CHANNEL_FREE, sound, false, 0);
}
void Sound::ResumeSound()
{
channel->setPaused(false);
}
void Sound::PauseSound()
{
channel->setPaused(true);
}
void Sound::Update()
{
sys->update();
}
//Main.cpp
Sound sound;
// Initialization routine.
void setup(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
sound = &Sound();
}
//------------------------------------------------------------ OnInit()
//
void OnIdle()
{
if(IsKeyPressed(KEY_ESCAPE))
{
exit(EXIT_SUCCESS);
}
if(IsKeyPressed('1'))
{
sound->PlaySound();
}
sound->Update();
// redraw the screen
glutPostRedisplay();
}
Currently it is giving me 2 errors:
Unhandled exception at 0x0F74465A (fmodex.dll) in TestOpenGL.exe: 0xC0000005: Access violation reading location 0x062C5040
and
FMOD error! (36) An invalid object handle was used
Any idea why it isn't working? Any idea how I solve these issues?
From your last comment and looking at your code I see a problem. You have created a pointer by FMOD::System *sys; but this pointer is not initialized to any instance of FMOD::System that is, there should be something like sys = new FMOD::System or sys = new FMOD::System(/* whatever argument you must supply to it's constructor */); somewhere in your code but right before you try to access anything related to FMOD::System object. This is most probably the reason for your program crash. Also since sys is a pointer to FMOD::System there's another problem at line containing result = FMOD::System_Create(&sys); you are passing a pointer by reference. I suggest you read a couple of articles about pointers in C and C++ and also some more about object creation and destruction in object oriented programming languages.
I was able to get help with the issue. I was initializing my sound variable incorrectly.
sound = &Sound();
Should actually be:
sound = new Sound();
I am trying to retreive content of websice in c++ usind SDL but it is giving me this error:
'SDL_main' : must return a value
my code is:
#include <iostream>
#include "SDL.h"
#include "SDL_net.h"
#include <cstring>
int main(int argc,char** argv)
{
SDL_Init(SDL_INIT_EVERYTHING);
SDLNet_Init();
IPaddress ip;
SDLNet_ResolveHost(&ip,"www.linux.org",80);
const char* http="GET / HTTP/1.1\nHost: www.linux.org\n\n";
TCPsocket client=SDLNet_TCP_Open(&ip);
SDLNet_TCP_Send(client,http,strlen(http)+1);
char text[10000];
while(SDLNet_TCP_Recv(client,text,10000))
std::cout << text;
SDLNet_TCP_Close(client);
SDLNet_Quit();
SDL_Quit();
}
When I put return 0; at the end, it built project but it finished immediately after that
(I am using vs2012)
UPDATE
cout<<"Some message";
doesn't print anything, is it possible that I have configured my imports wrong? are those additional dependencies right?
SDL.lib;SDL_net.lib;SDLmain.lib
I don't know what else could be wrong ...
It's because SDL defines a macro like this:
#define main SDL_main
So the function you've written is actually called SDL_main and like any other function that is not the actual main function, if it doesn't return void, you have to give it a return statement.
because your code doesn't loop forever it just returns 0 after first pass, you need to make a loop like:
while(1){
sdl_events event;
switch(event){
//handle events, drawings and so on
...
...
...
case SDL_QUIT:
exit (0);
break;
}
}
http://sdl.beuc.net/sdl.wiki/OpenGL_Full_Example
UPDATE
you may also have some problem connecting to host so you could check if connection succeed like this:
#define MAXLEN 1024
int result;
char msg[MAXLEN];
result = SDLNet_TCP_Recv(sock,msg,MAXLEN-1);
if(result <= 0) {
// TCP Connection is broken. (because of error or closure)
SDLNet_TCP_Close(sock);
exit(1);
}
else {
msg[result] = 0;
printf("Received: \"%s\"\n",msg);
}
UPDATE 2
change this:
while(SDLNet_TCP_Recv(client,text,10000))
std::cout << text;
to this:
while(SDLNet_TCP_Recv(client,text,9999))
std::cout << text;
UPDATE 3
try this, put your receive part in this if statement
if(SDLNet_SocketReady(client) == 1)
{
while(SDLNet_TCP_Recv(client,text,9999))
std::cout << text;
}
if this still doesn't work I suggest to use QT sockets or Boost asio, both async and more intuitive