Jump to content
  • Advertisement
Sign in to follow this  
BanzaiKen

Linker Error's

This topic is 4232 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi everyone, I am getting linker errors to undefined reference to WinMain@16 For my parameters I have ../../../Dev-Cpp/lib/liballeg.a ../Dev-Cpp/lib/liballeg_s.a -lalleg Code follows:
[source}
//include files
#include <stdio.h>
#include <allegro.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <dir.h>
//#include "TBLOCK_H.h"
#define DEFAULT_BLOCK_SPRITE(i) (Bwomp.dat)
//LOADS DATAFILE! ALWAYS LOAD THE DATA FILE!
//CAUSES PAIN AND HEADACHE!
DATAFILE *Bwomp;
int start_level;					  //start from level selected under options
int block[4][4];					  //current block
int next_block;					  //next block to be put
int map[10][20];					  //map
int block_x, block_y;			  //location of the block
int x_size, y_size;				  //size of the block 
volatile int timer;				  //timer of the game
int current_block;				  //current block type
int speed;						  
BITMAP *map_buffer;				  //double buffer for map displaying
DATAFILE *graphics;				  //data file with graphics and sounds
BITMAP *temp_bitmap;				  //temp 640x480 bitmap used by options and initial screens

//function prototypes
//int Random (int x);
void IncrementTimer (...);
void DeleteRow (void);
int CanPut (void);
void NewGame (void);
void SetVolume (void);
void PlayGame (void);
void DrawVolume (int pos);
void SetVolume (void);
void Error (char *);
void InitGame (void);
void ClearBlock (void);
void GenerateBlock (int);
void DrawFrame (void);
void GenerateNew (void);
void PutBlock (void);
void RotateBlock (void);
void DrawMap (void);
void NewGame (void);
void DrawMenu (void);
//void MainMenu (void);
void PlayGame (void);

//returns random number up to x-1
//int Random (int x)
//{
//	return Random () % x;
//}
void IncrementTimer (...)
{
	timer++;
}
END_OF_FUNCTION (IncrementTimer);
void Error (char *string)
{
	allegro_exit ();
	printf ("Error: %s\n", string);
	exit (1);
}

void InitGame (void)
{
	allegro_init ();				  //initialize allegro
	install_keyboard ();			  //install keyboard handler
	install_timer ();				  //install timer
	set_gfx_mode (GFX_AUTODETECT, 640, 480, 0, 0);	//set graphics mode to 640x480x256
   // initialize randomizer thing from the Borland book
//	srandom((int) time (NULL));
   // load data file
	if (!file_exists ("Bwomp.dat", FA_RDONLY | FA_ARCH, NULL))
		Error ("Cannot find Bwomp.dat file.");
	   graphics = load_datafile ("Bwomp.dat");		//load graphics
   	   Bwomp = load_datafile ("Bwomp.dat");	
   // create double buffer for the game screen
	map_buffer = create_bitmap (200, 400);
   //Done because MSDN says that my screen flickers if I use a timer that 
   //affects a bitmap
	temp_bitmap = create_bitmap (640, 480);
   // start game timer with 0
	timer = 0;
   // Locking Movement Timer
	LOCK_VARIABLE (timer);
	LOCK_FUNCTION (IncrementTimer);
   // timer is incremented every 20 miliseconds
	int install_int;
	
    //install_int (IncrementTimer, 20);
   // initial speed of the moving blocks is 10
	speed = 10;
	//Clips the bitmap so I dont get that stupid infinite boundries bug anymore
//	set_clip (map_buffer, 0, 0, 200, 400);
	start_level = 0;
	set_pallete (black_pallete);
}

// draws the frame around playing area in the game
// GRAWW! HULK MAKE BORDER TINY PIXELS!
void DrawFrame (void)
     {
     int it; 
     int gradline[20];
         // I cant figure out how to do pretty borders, maybe this code tutorial will work
     for( it = 0 ; it < 5 ; it++ )
          gradline[it] = makecol( 100 , 0 , 0 );
          // draw each border
          for( it = 0; it < 20 ; it++ )
               rect( temp_bitmap , it , it , temp_bitmap -> w - it , temp_bitmap -> h - it , gradline[20]);
}

// clears the current block
void ClearBlock (void)
{
	for (int i = 0; i < 4; i++)
		for (int j = 0; j < 4; j++)
			block[j] = 0;
}

// generates block depending on the kind of block to be generated
/* types of blocks: there are 7 kinds of blocks, and there can be
   4 different rotations of each block. To distinguish blocks
   block[][] holds the layout of the block and the blocks are:
   (x means 1..4 depending of the rotation of the block)
   X1: ÛÛ X2: ÛÛ   X3: ÛÛ  X4:  Û  X5:   Û  X6: Û   X7: ÛÛÛÛ
      ÛÛ       ÛÛ      ÛÛ      ÛÛÛ     ÛÛÛ      ÛÛÛ
*/
//I had a really nasty for loop probably spawned in hell here that I took out after I saw
//this while I was reading a tutorial about "blinting"
//It's hard grasping that even graphics can be manipulated in an array, I never thought of that
void GenerateBlock (int kind)
{
	ClearBlock ();
	switch (kind) {
	case 1:
		block[1][0] = block[2][0] = block[0][1] = block[1][1] = 1;
		break;
	case 11:
		block[0][0] = block[0][1] = block[1][1] = block[1][2] = 1;
		break;
	case 21:
		block[1][0] = block[2][0] = block[0][1] = block[1][1] = 1;
		break;
	case 31:
		block[0][0] = block[0][1] = block[1][1] = block[1][2] = 1;
		break;

	case 2:
		block[0][0] = block[1][0] = block[1][1] = block[2][1] = 2;
		break;
	case 12:
		block[1][0] = block[1][1] = block[0][1] = block[0][2] = 2;
		break;
	case 22:
		block[0][0] = block[1][0] = block[1][1] = block[2][1] = 2;
		break;
	case 32:
		block[1][0] = block[1][1] = block[0][1] = block[0][2] = 2;
		break;

	case 3:
		block[0][0] = block[0][1] = block[1][0] = block[1][1] = 3;
		break;
	case 13:
		block[0][0] = block[0][1] = block[1][0] = block[1][1] = 3;
		break;
	case 23:
		block[0][0] = block[0][1] = block[1][0] = block[1][1] = 3;
		break;
	case 33:
		block[0][0] = block[0][1] = block[1][0] = block[1][1] = 3;
		break;

	case 4:
		block[1][0] = block[0][1] = block[1][1] = block[2][1] = 4;
		break;
	case 14:
		block[0][0] = block[0][1] = block[0][2] = block[1][1] = 4;
		break;
	case 24:
		block[0][0] = block[1][0] = block[2][0] = block[1][1] = 4;
		break;
	case 34:
		block[0][1] = block[1][0] = block[1][1] = block[1][2] = 4;
		break;

	case 5:
		block[2][0] = block[0][1] = block[1][1] = block[2][1] = 5;
		break;
	case 15:
		block[0][0] = block[0][1] = block[0][2] = block[1][2] = 5;
		break;
	case 25:
		block[0][0] = block[1][0] = block[2][0] = block[0][1] = 5;
		break;
	case 35:
		block[0][0] = block[1][0] = block[1][1] = block[1][2] = 5;
		break;

	case 6:
		block[0][0] = block[0][1] = block[1][1] = block[2][1] = 6;
		break;
	case 16:
		block[0][0] = block[1][0] = block[0][1] = block[0][2] = 6;
		break;
	case 26:
		block[0][0] = block[1][0] = block[2][0] = block[2][1] = 6;
		break;
	case 36:
		block[1][0] = block[1][1] = block[1][2] = block[0][2] = 6;
		break;

	case 7:
		block[0][0] = block[1][0] = block[2][0] = block[3][0] = 7;
		break;
	case 17:
		block[0][0] = block[0][1] = block[0][2] = block[0][3] = 7;
		break;
	case 27:
		block[0][0] = block[1][0] = block[2][0] = block[3][0] = 7;
		break;
	case 37:
		block[0][0] = block[0][1] = block[0][2] = block[0][3] = 7;
		break;
	default:
		Error ("Unknown element to be generated.");
		break;
	}

	if ((kind == 7) || (kind == 27)) {
		x_size = 4;
		y_size = 1;
	}
	else if ((kind == 17) || (kind == 37)) {
		x_size = 1;
		y_size = 4;
	}
	else if (kind % 10 == 3) {
		x_size = 2;
		y_size = 2;
	}
	else if ((kind / 10 == 0) || (kind / 10 == 2)) {
		x_size = 3;
		y_size = 2;
	}
	else if ((kind / 10 == 1) || (kind / 10 == 3)) {
		x_size = 2;
		y_size = 3;
	}
	current_block = kind;
}

// this function generates new block when the current one has been put
void GenerateNew (void)
{
 	// next_block holds the value of the block that was shown as next last time,
   	//so save it and later use it as a current one
	int temp = next_block;
	next_block = 2 + 1; /* not get the next block */
   /* Now generate a next block depening on the value returned by random
      there can be 7 different kinds of block */
	GenerateBlock (next_block);
   // Loops through a for loop and puts out squares for the next block :)
	for (int i = 0; i < 4; i++) {
		for (int j = 0; j < 2; j++) {
			if (block[j] != 0) {
                            //This Case statement have made my program phenomenally faster
				switch (next_block) {
				case 1:
					draw_sprite (screen, (BITMAP *) DEFAULT_BLOCK_SPRITE(i), 360 + i * 20, 160 + j * 20);
					break;
				case 2:
					draw_sprite (screen, (BITMAP *) DEFAULT_BLOCK_SPRITE(i), 360 + i * 20, 160 + j * 20);
					break;
				case 3:
					draw_sprite (screen, (BITMAP *) DEFAULT_BLOCK_SPRITE(i), 360 + i * 20, 160 + j * 20);
					break;
				case 4:
					draw_sprite (screen, (BITMAP *) DEFAULT_BLOCK_SPRITE(i), 360 + i * 20, 160 + j * 20);
					break;
				case 5:
					draw_sprite (screen, (BITMAP *) DEFAULT_BLOCK_SPRITE(i), 360 + i * 20, 160 + j * 20);
					break;
				case 6:
					draw_sprite (screen, (BITMAP *) DEFAULT_BLOCK_SPRITE(i), 360 + i * 20, 160 + j * 20);
					break;
				case 7:
					draw_sprite (screen, (BITMAP *) DEFAULT_BLOCK_SPRITE(i), 360 + i * 20, 160 + j * 20);
					break;
				}
			}
//			else
//				draw_sprite (screen, (BITMAP *) graphics[EMPTY].dat, 360 + i * 20, 160 + j * 20);
		}
	}
	/* now generate the current block using the value used by the next_block last time */
	GenerateBlock (temp);
   /* set current locations of the block */
	block_x = 3;
	block_y = 0;
   /* if can't put block the game is over */
}

/* this function puts current block onto map[][] double array
	using block_x and block_y location. It is called when a block
   cannot move anymore downwards */
void PutBlock (void)
{
	for (int i = 0; i < 4; i++) {
		for (int j = 0; j < 4; j++) {
			if (block[j] != 0)
				map[block_x + i][block_y + j] = block[j];
		}
	}
}

/* this function rotates the block. It's called when the rotate button
   is pressed. It uses the GenerateBlock function using the same type of
   block but different rotation */
void RotateBlock (void)
{
 	/* save block so that when can't rotate block it can be restored */
	int old_block = current_block;
   /* set next rotation type */
	current_block += 10;
   /* there can be only four rotations so set block to first one if
      greater than 4th one */
	if (current_block > 40)
		current_block -= 40;
   /* generate new rotated block */
	GenerateBlock (current_block);

   /* if can't put block (could be out of map) restore old one */
	if (!CanPut ()) {
		current_block = old_block;
		GenerateBlock (current_block);
	}
}

/* this function checks if the current map fits onto map.
	Used by rotate */
int CanPut (void)
{
 	/* go through all parts of the block and check if they
      are in the map range */
	for (int i = 0; i < 4; i++) {
		for (int j = 0; j < 4; j++) {
			if (block[j] != 0) {
				if (block_x + i > 9)
					return FALSE;
				if (block_x + i < 0)
					return FALSE;
				if (block_y + j > 19)
					return FALSE;
				if (map[block_x + i][block_y + j] != 0)
					return FALSE;
			}
		}
	}
	/* block is in the range of map */
	return TRUE;
}


/* this function draws the map to map_buffer which is later
   blit to screen (Double buffering).  It goes through
   map double array and depending on the type of block there
   it draws the correspoding color box, these colors are picked up by me in the grabber
   sorry for the bad quality of the graphics Prof. B, but Im not too well into working
   with the compression feature yet.*/
void DrawMap (void)
{
	clear (map_buffer);
	for (int i = 0; i < 10; i++) {
		for (int j = 0; j < 20; j++) {
			if (map[j] != 0) {
				switch (map[j]) {
				case 1:
					draw_sprite (screen, (BITMAP *) DEFAULT_BLOCK_SPRITE(i), i * 20, j * 20);
					break;
				case 2:
					draw_sprite (screen, (BITMAP *) DEFAULT_BLOCK_SPRITE(i), i * 20, j * 20);
					break;
				case 3:
					draw_sprite (screen, (BITMAP *) DEFAULT_BLOCK_SPRITE(i), i * 20, j * 20);
					break;
				case 4:
					draw_sprite (screen, (BITMAP *) DEFAULT_BLOCK_SPRITE(i), i * 20, j * 20);
					break;
				case 5:
					draw_sprite (screen, (BITMAP *) DEFAULT_BLOCK_SPRITE(i), i * 20, j * 20);
					break;
				case 6:
					draw_sprite (screen, (BITMAP *) DEFAULT_BLOCK_SPRITE(i), i * 20, j * 20);
					break;
				case 7:
					draw_sprite (screen, (BITMAP *) DEFAULT_BLOCK_SPRITE(i), i * 20, j * 20);
					break;
				}
			}
		}
	}
	/* this function draws the current box onto map_buffer */
	for (int i = 0; i < 4; i++) {
		for (int j = 0; j < 4; j++) {
			if (block[j] != 0) {
				switch (block[j]) {
				case 1:
					draw_sprite (screen, (BITMAP *) DEFAULT_BLOCK_SPRITE(i), block_x * 20 + i * 20, block_y * 20 + j * 20);
					break;
				case 2:
					draw_sprite (screen, (BITMAP *) DEFAULT_BLOCK_SPRITE(i), block_x * 20 + i * 20, block_y * 20 + j * 20);
					break;
				case 3:
					draw_sprite (screen, (BITMAP *) DEFAULT_BLOCK_SPRITE(i), block_x * 20 + i * 20, block_y * 20 + j * 20);
					break;
				case 4:
					draw_sprite (screen, (BITMAP *) DEFAULT_BLOCK_SPRITE(i), block_x * 20 + i * 20, block_y * 20 + j * 20);
					break;
				case 5:
				     draw_sprite (screen, (BITMAP *) DEFAULT_BLOCK_SPRITE(i), block_x * 20 + i * 20, block_y * 20 + j * 20);
					break;
				case 6:
					draw_sprite (screen, (BITMAP *) DEFAULT_BLOCK_SPRITE(i), block_x * 20 + i * 20, block_y * 20 + j * 20);
					break;
				case 7:
					draw_sprite (screen, (BITMAP *) DEFAULT_BLOCK_SPRITE(i), block_x * 20 + i * 20, block_y * 20 + j * 20);
					break;
				}
			}
		}
	}
	//keep updating to avoid the seizure attacks that happen during updates
	blit (map_buffer, screen, 0, 0, 100, 40, 200, 400);
}

// Row deleter
void DeleteRow (void)
{
	int sum, i, j, del = 0;
   //Twenty rows total, so -1 cause of that stupid arrays start at zero thing
   //Yay I learn from tests!
	for (i = 19; i >= 0; i--) {
		sum = 0;	/* sum holds number of non-empty cells */
      /* loop through all columns of the row */
		for (j = 0; j < 10; j++) {
			if (map[j] != 0)
				sum++; /* if cell not empty increment sum */
		}
   	/* if sum == 10 it means that the row is full so move
         all rows above it down */
		if (sum == 10) {
			for (j = i; j >= 1; j--)
				for (int k = 0; k < 10; k++)
					map[k][j] = map[k][j - 1];
			i += 2;
			del++;	/* incremente number of deleted rows */
		}
	}

}
/* initializes stuff for new game */
void NewGame (void)
{
	for (int i = 0; i < 20; i++)
		for (int j = 0; j < 10; j++)
			map[j] = 0;
	next_block = 1 + 1;
	GenerateNew ();
	DrawMap ();
	timer = 0;
}

/* this function just draws the main menu */
//void DrawMenu (int pos)
//{
//	clear (temp_bitmap);
//	rectfill (temp_bitmap, 0, 0, 640, 480, 0);
//	dtextout (temp_bitmap, font, "N E W  G A M E", 100, 200, 0, 136);
//	dtextout (temp_bitmap, font, "O P T I O N S", 100, 250, 0, 136);
//	dtextout (temp_bitmap, font, "H I G H  S C O R E S", 100, 300, 0, 136);
//   dtextout (temp_bitmap, font, "H E L P", 100, 350, 0, 136);
//	dtextout (temp_bitmap, font, "E X I T", 100, 400, 0, 136);
//
//	draw_sprite (temp_bitmap, (BITMAP *) graphics[CURSOR].dat, 80, (pos - 1) * 50 + 200);
//   solid_mode();
//   rect(temp_bitmap, 0, 0, 639, 479, 143);
//	blit (temp_bitmap, screen, 0, 0, 0, 0, 640, 480);
//}

/* event handling for main menu */
//void MainMenu ()
//{
//	int ch;
//	int pos = 1;
//	DrawMenu (1);
//	fade_in ((RGB *) graphics[GAME_PALLETE].dat, 2);	//fade in slowly

//	do {
//		if (keypressed ()) {
//			ch = readkey ();
//			if ((ch >> 8) == KEY_UP) {
//				pos--;
//				if (pos == 0)
//					pos = 5;
//			}
//			else if ((ch >> 8) == KEY_DOWN) {
//				pos++;
//				if (pos == 6)
//					pos = 1;
//			}
//			else if ((ch >> 8) == KEY_ENTER) {
//				if (pos == 1) {
//					PlayGame ();
//				}
//				else if (pos == 2)
//					SetVolume ();
//            else if (pos == 4)
 //              Help();
//				else if (pos == 5)
//					break;
//				else if (pos == 3)
//					ViewHighScores ();
//			}
//			else if ((ch >> 8) == KEY_ESC)
//				break;
//			DrawMenu (pos);
//		}								  // end if keypressed

//	} while (1 == 1);
//	fade_out (1);
//	if (musicOn)
//		stop_midi ();
//}

// this is a game loop function, heart and soul of my game right here
void PlayGame (void)
{
	int ch;
	int loop, loop2;
//	drawing_mode (DRAW_MODE_COPY_PATTERN, (BITMAP *) graphics[PATTERN].dat, 0, 0);
	rectfill (screen, 0, 0, 640, 480, 0);
	DrawFrame ();
   solid_mode();
	rectfill (screen, 360, 40, 580, 100, 0);
   rect(screen, 0, 0, 639, 479, 143);
	NewGame ();
	while (1 == 1) {
		if (keypressed ()) {
                       //I guess C++ has some problems with keys being held in memory,
                       //so I gotta use the keyboard function that comes with Allegro
			ch = readkey ();
         // if it's one of the arrow keys move the block in correspoding
          //  direction checking if it can be moved there first
			if ((ch >> 8) == KEY_LEFT) {
				block_x--;
				if (!CanPut ())
					block_x++;
			}
			if ((ch >> 8) == KEY_RIGHT) {
				block_x++;
				if (!CanPut ())
					block_x--;
			}
			if ((ch >> 8) == KEY_UP)
				RotateBlock ();
			if ((ch >> 8) == KEY_DOWN) {
				if (CanPut ()) {
				while (CanPut ()) {
					DrawMap ();
					block_y++;
				}
				block_y--;
			}
      	// Eject Button!
			else if ((ch >> 8) == KEY_ESC) {
					break;
			}
			clear_keybuf ();
		}
   	// If the block hits, a new one is formed
		if (!CanPut ()) {
			PutBlock ();
			GenerateNew ();
		}
   	// draw the map, again...
		DrawMap ();
	}
}

}
int Main()
{
	InitGame ();
	allegro_exit ();
        return 0;
}


I have worked with other languages, but this is my second time to ever use c++ and I had to get a tutorial on how to install it all. I am using Dev-C++ with Allegro, and the linker error I guess isn't my codes fault, but something to do with linking those Allegro libraries or something? I keep getting mangled_main messages whenever I try to take the int off Main(). Any help would be appreciated greatly.

Share this post


Link to post
Share on other sites
Advertisement
Well that's because C++ is case sensitive, and the standard entry point for a C++ application is int main() or int main( int argc, char * argv [] ), not int Main()


jfl.

Share this post


Link to post
Share on other sites
Holy schnikes that fixed all of it.
Thanks everyone. It's hard getting used to a language that doesn't have a GUI interface and is case sensitive, I'm going to have to try to pay more attention...

But again thank you!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!