|
Using Dev-Cpp to compile static library |
Bob Keane
Member #7,342
June 2006
|
After a bit of a vacation, I decided to return to game programming. I am using Bloodshed's Dev-Cpp ide for simplicity. I entered and compiled a program, but when linking, I get the following errors: "[linker error] undefined reference to 'backward' (2x) I selected project > project options then parameters, under compiler I had "-DALLEGRO_STATICLINK", under C++ compiler I had "_DALLEGRO_STATICLINK", and under linker, I had (in this order) "-lalleg_s -lkernel32 -luser32 -lgdi32 -lcomdlg32 -lole32 -ldinput -lddraw -ldxguid -lwinmm -ldsound". To create the project, I selected file, new project, multimedia and allegro static library, the programming language was set to C. I was able to compile and link with no problems before, but I cannot remember how. What did I miss? I am using allegro 4.2.0. Thanks in advance. By reading this sig, I, the reader, agree to render my soul to Bob Keane. I, the reader, understand this is a legally binding contract and freely render my soul. |
BAF
Member #2,981
December 2002
|
Well, I don't know what backward is, rans... what's that. Is that a misspelling of rand()? And testprintf-ex should be textprintf_ex. [edit] Can you post the source? |
Bob Keane
Member #7,342
June 2006
|
Its a long one. I am trying to adapt Game Programming All In One's tank war to suit my needs. I have not added my changes yet.
Source(main.c): [code] /* Sea War By Bob Keane My first attempt at programming a game. This game is based on the Game Programming All In One sample game Tank War. Changes include multiple enemy ships, A storyline and random ship movement. I will change as necessary when possible. */ #include "seawar.h" // drawtank function. construct the tank using drawing functions. void drawtank(int num) { int x = tanks[num].x; int y = tanks[num].y; int dir = tanks[num].dir; //draw tank body and turret. rectfill(screen, x - 11, y - 11, x + 11, y + 11, tanks[num].color); rectfill(screen, x - 6, y - 6, x + 6, y + 6, 7); // Draw the treads based on orientation. if (dir == 0 || dir ==2) { rectfill(screen, x - 16, y - 16, x - 11, y + 16, 8); rectfill(screen, x+11, y-16, x+16, y+16, 8); } else if (dir == 1 || dir == 3) { rectfill(screen, x-16, y-16, x+16, y-11, 8); rectfill(screen, x-16, y+16, x+16, y+11, 8); } // Draw the turret based on direction switch (dir) { case 0: rectfill(screen, x-1, y, x+1, y-16, 8); break; case 1: rectfill(screen, x, y-1, x+16, y+1, 8); break; case 2: rectfill(screen, x-1, y, x+1, y+16, 8); break; case 3: rectfill(screen, x, y-1, x-16, y+1, 8); break; } } // Erasetank function. erase the tank using rectfill. void erasetank(int num) { // calculate box to encompass the tank. int left = tanks[num].x - 17; int top = tanks[num].y - 17; int right = tanks[num].x + 17; int bottom = tanks[num].y + 17; // erase the tank. rectfill(screen, left, top, right, bottom, 0); } // movetank function. move the tank in the current direction. void movetank(int num) { int dir = tanks[num].dir; int speed = tanks[num].speed; // update the tank's position based on direction. switch (dir) { case 0: tanks[num].y-= speed; break; case 1: tanks[num].x+= speed; break; case 2: tanks[num].y+= speed; break; case 3: tanks[num].x-= speed; } // keep the tank inside the screen. if (tanks[num].x > SCREEN_W-22) { tanks[num].x = SCREEN_W - 22; tanks[num].speed = 0; } if (tanks[num].x < 22) { tanks[num].x = 22; tanks[num].speed = 0; } if (tanks[num].y > SCREEN_H-22) { tanks[num].y =SCREEN_H-22; tanks[num].speed = 0; } if (tanks[num].y < 22) { tanks[num].y = 22; tanks[num].speed = 0; } } // explode function. Display random boxes to simulate an explosion. void explode(int num, int x, int y) { int n; //retrieve the location of the enemy tank int tx = tanks[!num].x; int ty = tanks[!num].y; // Is bullet inside the boundary of the enemy tank? if (x > tx-16 && x < tx+16 && y > ty-16 && y < ty+16) score(num); // Draw some random circles for the "explosion" for (n = 0; n < 10; n++) { rectfill(screen, x-16, y-16, x+16, y+16, rand() % 16); rest(1); } // Clear the field of debris rectfill(screen, x-16, y-16, x+16, y+16, 0); } // updatebullet function Update the position of the bullet. void updatebullet(int num) { int x = bullets[num].x; int y = bullets[num].y; if (bullets[num].alive) { // erase bullet. rect(screen, x-1, y-1, x+1, y+1, 0); // move bullet bullets[num].x += bullets[num].xspd; bullets[num].y += bullets[num].yspd; x = bullets[num].x; y = bullets[num].y; // Stay within the screen. if (x<5 || x> SCREEN_W-5 || y<20 || y> SCREEN_H-5) { bullets[num].alive = 0; return; } // draw bullet x = bullets[num].x; y = bullets[num].y; rect(screen, x-1, y-1, x+1, y+1, 4); // look for a hit if (getpixel(screen, bullets[num].x, bullets[num].y)) { bullets[num].alive = 0; explode(num, x, y); } // print the bullet's position. textprintf_ex(screen, font, SCREEN_W/2-50,1,2,-1,"B1 %-3dx%-3d B2 %-3dx-3d",bullets[0].x, bullets[0].y, bullets[1].x,bullets[1].y); } } // checkpath function check to see if a point on the screen is black. int checkpath(int x1, int y1, int x2, int y2, int x3, int y3) { if (getpixel(screen, x1, y1) || getpixel(screen, x2, y2) || getpixel(screen, x3, y3)) return 1; else return 0; } // clearpath function verify that the tank can move in thte current direction void clearpath(int num) { // shortcut vars int dir = tanks[num].dir; int speed = tanks[num].speed; int x = tanks[num].x; int y = tanks[num].y; switch (dir) { // check pixels north case 0: if (speed > 0) { if (checkpath(x-16, y-20, x, y-20, x+16, y-20)) tanks[num].speed = 0; } else //if reverse direction, check south if (checkpath(x-16, y+20, x, y+20, x+16, y+20)) tanks[num].speed = 0; break; // check pixels east case 1: if (speed > 0) { if (checkpath(x+20, y-16, x+20, y, x+20, y+16)) tanks[num].speed = 0; } else // if reverse dir, check west if (checkpath(x-20, y-16, x-20, y, x-20, y+16)) tanks[num].speed = 0; break; // Check pixels south case 2: if (speed > 0) { if (checkpath(x-16, y-20, x, y-20, x+16, y-20)) tanks[num].speed = 0; } else // if reverse direction, check north if (checkpath(x-16, y-20, x, y-20, x+16, y-20)) tanks[num].speed = 0; break; //check pixels west case 3: if (speed > 0) { if (checkpath(x-20, y-16, x-20, y, x-20, y+16)) tanks[num].speed = 0; } else // if reverse dir, check east if (checkpath(x+20, y-16, x+20, y, x+20, y+16)) tanks[num].speed = 0; break; } } // Fireweapon function configure a bullet's direction and speed and activate it. void fireweapon(int num) { int x = tanks[num].x; int y = tanks[num].y; // ready to fire again? if (!bullets[num].alive) { bullets[num].alive = 1; //fire weaponin direction tank is facing switch (tanks[num].dir) { // north case 0: bullets[num].x = x; bullets[num].y = y-22; bullets[num].xspd = 0; bullets[num].yspd = -BULLETSPEED; break; //east case 1: bullets[num].x = x+22; bullets[num].y = y; bullets[num].xspd = BULLETSPEED; bullets[num].yspd = 0; break; //south case 2: bullets[num].x = x; bullets[num].y = y+22; bullets[num].xspd = 0; bullets[num].yspd = BULLETSPEED; break; //west case 3: bullets[num].x = x-22; bullets[num].y = y; bullets[num].xspd = -BULLETSPEED; bullets[num].yspd = 0; } } } // forward function increase the tank's speed void forward(int num) { tanks[num].speed++; if (tanks[num].speed > MAXSPEED) tanks[num].speed = MAXSPEED; } //reverse function decrease the tank's speed. void reverse(int num) { tanks[num].speed--; if (tanks[num].speed < -MAXSPEED) tanks[num].speed = -MAXSPEED; } // turnleft function rotate the tank counter-clockwise void turnleft(int num) { tanks[num].dir--; if (tanks[num].dir < 0) tanks[num].dir = 3; } // turnright function rotate the tank clockwise. void turnright(int num) { tanks[num].dir++; if (tanks[num].dir > 3) tanks[num].dir = 0; } //getinput function check for player input keys (2 player support) void getinput() { // hit esc to quit. if (key[KEY_ESC]) gameover = 1; // WASD / SPACE keys control tank 1 if (key[KEY_W]) forward(0); if (key[KEY_D]) turnright(0); if (key[KEY_A]) turnleft(0); if (key[KEY_S]) backward(0); if (key[KEY_SPACE]) fireweapon(0); // arrow / ENTER keys control tank 2 if (key[KEY_UP]) forward(1); if (key[KEY_RIGHT]) turnright(1); if (key[KEY_LEFT]) turnleft(1); if (key[KEY_DOWN]) backward(1); if (key[KEY_ENTER]) fireweapon(1); // short delay after keypress rest(10); } // score function add a point to the specified player's score void score(int player) { // update score int points = ++tanks[player].score; // display score textprintf_ex(screen, font, SCREEN_W-70*(player+1), 1, BURST, -1, "P%d", player+1, points); } // setuptanks function set up the starting condition of each tank void setuptanks() { // player 1 tanks[0].x = 30; tanks[0].y = 40; tanks[0].dir = 1; tanks[0].speed = 0; tanks[0].color = 9; tanks[0].score = 0; // player 2 tanks[1].x = SCREEN_W-30; tanks[1].y = SCREEN_H-30; tanks[1].dir = 3; tanks[1].speed = 0; tanks[1].color = 12; tanks[1].score = 0; } // setupdebris function set up the debris on the battlefield void setupdebris() { int n, x, y, size, color; // fill the battlefield with random debris for (n=0; n<BLOCKS; n++) { x = BLOCKSIZE + rand() % (SCREEN_W-BLOCKSIZE*2); y = BLOCKSIZE + rand() % (SCREEN_H-BLOCKSIZE*2); size = (10 + rand() % BLOCKSIZE)/2; color = makecol(rans()%255, rand()%255, rand()%255); rectfill(screen, x-size, y-size, x+size, y+size, color); } } // setupscreen function set up the graphics mode and game screen void setupscreen() { // set video mode int ret = set_gfx_mode(MODE, WIDTH, HEIGHT, 0, 0); if (ret != 0) { allegro_message(allegro_error); return; } // print title testprintf_ex(screen, font, 1, 1, BURST, 0, "Tank War - %dx%d", SCREEN_W, SCREEN_H); // draw screen border rect(screen, 0, 12, SCREEN_W -1, SCREEN_H-1, TAN); rect(screen, 1, 13, SCREEN_W-2, SCREEN_H-2, TAN); } //main function start point of the program int main(void) { // initialize everything allegro_init(); install_keyboard(); install_timer(); srand(time(NULL)); setupscreen(); setupdebris(); setuptanks(); // game loop while (!gameover) { // erase the tanks erasetank(0); erasetank(1); // check for collisions clearpath(0); clearpath(1); // move the tanks movetank(0); movetank(1); //draw the tanks drawtank(0); drawtank(1); //update the bullets updatebullet(0); updatebullet(1); //check for keypresses if (keypressed()) getinput(); // slow the game down, adjust as necessary rest(30); } // end program allegro_exit(); return 0; } END_OF_MAIN(); [/code] Header (seawar.h): [code] /* SeaWar.h This file contains basic information for the game SeaWar. Written by Bob Keane */ #ifndef _SEAWAR_H #define _SEAWAR_H #include <stdio.h> #include <stdlib.h> #include "allegro.h" // define some game constants #define MODE GFX_AUTODETECT_WINDOWED #define WIDTH 640 #define HEIGHT 480 #define BLOCKS 5 #define BLOCKSIZE 100 #define MAXSPEED 2 #define BULLETSPEED 10 #define TAN makecol(255,242,169) #define CAMO makecol (64,142,66) #define BURST makecol(255,189,73) // Define the tank structure struct tagTank { int x,y; int dir, speed; int color; int score; } tanks[2]; // define the bullet structure struct tagBullet { int x,y; int alive; int xspd,yspd; } bullets[2]; int gameover = 0; // function prototypes void drawtank(int num); void erasetank(int num); void movetank(int num); void explode(int num, int x, int y); void updatebullet(int num); int checkpath(int x1, int y1, int x2, int y2, int x3, int y3); void clearpath(int num); void fireweapon(int num); void forward(int num); void backward(int num); void turnleft(int num); void turnright(int num); void getinput(); void setuptanks(); void score(int); void print(const char *s, int c); void setupdebris(); void setupscreen(); #endif [/code] Errors (compile log): Compiler: Default compiler Building Makefile: "C:\Dev-Cpp\SeaWar\Makefile.win" Executing make... make.exe -f "C:\Dev-Cpp\SeaWar\Makefile.win" all gcc.exe main.o seawar_private.res -o "seawar.exe" -L"C:/Dev-Cpp/lib" -mwindows -lalleg_s -lkernel32 -luser32 -lgdi32 -lcomdlg32 -lole32 -ldinput -lddraw -ldxguid -lwinmm -ldsound main.o(.text+0x12bf):main.c: undefined reference to `backward' main.o(.text+0x1332):main.c: undefined reference to `backward' main.o(.text+0x1654):main.c: undefined reference to `rans' main.o(.text+0x17cb):main.c: undefined reference to `testprintf_ex' collect2: ld returned 1 exit status make.exe: *** [seawar.exe] Error 1 Execution terminated [edit] Sorry about that. By reading this sig, I, the reader, agree to render my soul to Bob Keane. I, the reader, understand this is a legally binding contract and freely render my soul. |
spunit262
Member #5,545
February 2005
|
Please put that in [code][/code] tags. |
gnolam
Member #2,030
March 2002
|
Solution: Quote: main.o(.text+0x1654):main.c: undefined reference to `rans'
Misspelling of rand. Quote: main.o(.text+0x17cb):main.c: undefined reference to `testprintf_ex'
Misspelling of textprintf_ex. Quote: main.o(.text+0x12bf):main.c: undefined reference to `backward'
Just plain doesn't exist. The "reverse()" function is probably what's intended. if (key[KEY_S]) backward(0); and if (key[KEY_DOWN]) backward(1);
-- |
BAF
Member #2,981
December 2002
|
Just what I said, just less detailed because I didn't have the source. |
Bob Keane
Member #7,342
June 2006
|
Looks like I need a new pair of glasses. Thanks. By reading this sig, I, the reader, agree to render my soul to Bob Keane. I, the reader, understand this is a legally binding contract and freely render my soul. |
|