Hello.
I am reading "Advanced 2D Game Development" by Jonathan S. Harbour and I am
attempting to follow along. I have created the three .h files and the three
.cpp files as he lays out (I am using the bloodshed IDE Version 4.9.9.2) and
have created the test program as it is written in the book:
[code]#include<iostream>#include"..\Engine\DeathChicken.h"boolgame_preload(){//engine version displayg_engine->message(g_engine->getVersionText(),"Test Engine");//return fail to terminate enginereturn0;}boolgame_init(HWNDhwnd){return0;}boolgame_update(){return0;}boolgame_end(){return0;}[/code]
Everything is mostly working, but I am getting a series of Linker errors that
I do not understand. I have been doing some searches, but nothing that looks
like it will help. Here are the linker errors:
[code][Linker error] undefined reference to `DeathChicken::Engine::getVersionText()' [Linker error] undefined reference to `DeathChicken::Engine::message(std::string, std::string)' [Linker error] undefined reference to `DeathChicken::Engine::Engine()' [Linker error] undefined reference to `DeathChicken::Engine::Init(int, int, int, bool)' [Linker error] undefined reference to `DeathChicken::Engine::Update()' [Linker error] undefined reference to `DeathChicken::Engine::Close()' [/code]
What I am finding is weird, is that these are some of the methods from
DeathChicken.h and DeathChicken.cpp, but not all of them. What should I be
looking for to get this to work?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I zipped my files in case someone needs to look at them to help. I do not see
a way to attach them to the forum, but if you mail me at DIntentGmailcom I
will send the zip file to you. (it is only 829KB)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Post the complete build log text from the "Compile Log" tab not the
"Compiler" tab. It is plain text so is a simple copy and paste, and it
contains all the necessary diagnostic information including how your project
is setup.
Note that you do need to create a project for a multi-module build, and add all your source files to the project, otherwise the linker will not know
what to include in the build. I strongly suspect that that is your problem.
The "Compile Log" will have told us if that were the case, which is why in the PLEASE READ BEFORE POSTING A QUESTION thread, you are requested to post
it!
What I am finding is weird, is that these are some of the methods from
DeathChicken.h and DeathChicken.cpp, but not all of them.
The linker will only attempt to resolve references to symbols actually
referenced in the compiled code. If there were no references to the other
symbols, there is nothing to resolve!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
It would appear that ../../Engine/lib/libDeathChicken.a does not contain the
DeathChicken::Engine:: member functions you have made reference to or indeed
the members it makes reference to itself. Are these implementatuions that you
have provided in separate modules? The only Object file you are linking is
main.o; you said tehre were three .cpp files, but you have only compiled and
linked one. So as I said, you need to use a 'project' (File->New->Project),
and add all the .cpp sources to it as well as setting up the library paths and
libraries to be linked.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The six other files are supposed to collapse down into DeathChicken.a, as for
DeathChicken.h, it is supposed to reference the other files. Maybe I
configured the project wrong?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
For that to work you must have had a separate project to build
libDeathChicken.a; perhaps you need to post the log from that (from a Rebuild
All), to see what it is composed of. That said, why bother with creating a
static library for this? You could just include all the sources in this
project.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
When I get home I will post that.
The intent is that that the DeathChicken.a will eventually be an Engine, and
comes from a book called "Advanced 2D Game Development" by Jonathan S.
Harbour.
The program I am attempting to write here is just to initialize the engine and
make sure it works. (LOL! I'm not doing too good!)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Here is that log when I compile WinMain.cpp from engine project:
Compiler: Default compiler
Building Makefile: "D:\Dev-Cpp\Engine\Devcpp\Makefile.win"
Executing make...
make.exe -f "D:\Dev-Cpp\Engine\Devcpp\Makefile.win" all
ar r ../lib/libDeathChicken.a ./obj/WinMain.o
ar: creating ../lib/libDeathChicken.a
ranlib ../lib/libDeathChicken.a
Execution terminated
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
//The Death Chicken Engine//Ethan Roberts, 2010//Main source file//includes#include"DeathChicken.h"#include<cstdlib>#include<ctime>#include<string>#include<sstream>#include<list>#include"winmain.h"namespaceDeathChicken{Engine::Engine(){srand((unsignedint)time(NULL));p_maximizeProcessor=false;p_frameCount_core=0;p_frameRate_core=0;p_frameCount_real=0;p_frameRate_real=0;p_ambientColor=D3DCOLOR_RGBA(255,255,255,0);p_windowHandle=0;p_pauseMode=false;p_versionMajor=VERSION_MAJOR;p_versionMinor=VERSION_MINOR;p_revision=REVISION;//set default valuesthis->setAppTitle("DeathChicken");this->setScreenWidth(640);this->setScreenHeight(480);this->setColorDepth(32);this->setFullscreen(false);//window handle must be set later on for directX!this->setWindowHandle(0);}Engine::~Engine(){if(this->p_device)this->p_device->Release();if(this->p_d3d)this->p_d3d->Release();}std::stringEngine::getVersionText(){std::ostringstreams;s<<"DeathChicken Engine v"<<p_versionMajor<<"."<<p_versionMinor<<"."<<p_revision;returns.str();}voidEngine::message(std::stringmessage,std::stringtitle){MessageBox(0,message.c_str(),title.c_str(),0);}voidEngine::fatalerror(std::stringmessage,std::stringtitle){this->message(message,title);Shutdown();}intEngine::Init(intwidth,intheight,intcolordepth,boolfullscreen){//initialize Direct3Dthis->p_d3d=Direct3DCreate9(D3D_SDK_VERSION);if(this->p_d3d==NULL){return0;}//get system desktop color depthD3DDISPLAYMODEdm;this->p_d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&dm);//set configuration optionsD3DPRESENT_PARAMETERSd3dpp;ZeroMemory(&d3dpp,sizeof(d3dpp));d3dpp.Windowed=(!fullscreen);d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD;d3dpp.EnableAutoDepthStencil=TRUE;d3dpp.AutoDepthStencilFormat=D3DFMT_D16;d3dpp.PresentationInterval=D3DPRESENT_INTERVAL_IMMEDIATE;d3dpp.BackBufferFormat=dm.Format;d3dpp.BackBufferCount=1;d3dpp.BackBufferWidth=width;d3dpp.BackBufferHeight=height;d3dpp.hDeviceWindow=p_windowHandle;//create direct3d devicethis->p_d3d->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,this->p_windowHandle,D3DCREATE_HARDWARE_VERTEXPROCESSING,&d3dpp,&this->p_device);if(this->p_device==NULL)return0;//clear the backbuffer to blackthis->ClearScene(D3DCOLOR_XRGB(0,0,0));//create pointer to the back bufferthis->p_device->GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO,&this->p_backbuffer);//use ambient lighting and z-bufferingthis->p_device->SetRenderState(D3DRS_ZENABLE,TRUE);this->p_device->SetRenderState(D3DRS_FILLMODE,D3DFILL_SOLID);this->SetAmbient(this->p_ambientColor);//initialize the 2D rendererHRESULTresult=D3DXCreateSprite(this->p_device,&this->p_sprite_handler);if(result!=D3D_OK)return0;//call game initialization extern functionif(!game_init(this->getWindowHandle()))return0;//set a default materialSetDefaultMaterial();return1;}voidEngine::SetDefualtMaterial(){D3DMATERIAL9mat;memset(&mat,0,sizeof(mat));mat.Diffuse.r=1.0f;mat.Diffuse.g=1.0f;mat.Diffuse.b=1.0f;mat.Diffuse.a=1.0f;p_device->SetMaterial(&mat);}voidEngine::ClearScene(D3DCOLORcolor){this->p_device->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,color,1.0f,0);}voidEngine::SetAmbient(D3DCOLORcolorvalue){this->p_ambientColor=colorvalue;this->p_device->SetRenderState(D3DRS_AMBIENT,this->p_ambientColor);}intEngine::RenderStart(){if(!this->p_device)return0;if(this->p_device->BeginScene()!=D3D_OK)return0lreturn1;}intEngine::RenderStop(){if(!this->p_device)return0;if(this->p_device->EndScene()!=D3D_OK)return0;if(p_device->Present(NULL,NULL,NULL,NULL)!=D3D_OK)return0;return1}voidEngine::Shutdown(){gameover=true;}voidEngine::Update(){staticTimertimedUpdate;//calculate core frameratep_frameCount_core++;if(p_coreTimer.stopwatch(999)){p_frameRate_core=p_frameCount_core;p_frameCount_core=0;}//fast update with no timinggame_update();//update with 60fps timingif(timedUpdate.stopwatch(14)){if(!this->getMaximizeProcessor()){Sleep(1);}}else{//calculate real frameratep_frameCount_real++;if(p_realTimer,stopwatch(999)){p_frameRate_real=p_frameCount_real;p_frameCount_real=0;}//begin renderingthis->RenderStart();//done Renderingthis->RenderStop)();}}voidEngine::Close(){game_end();}}//Namespace end
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
#include<sstream>#include"WinMain.h"#include"DeathChicken.h"//Macro to read key-states#define KEY_DOWN(vk) ((GetAsyncKeyState(vk) & 00x8000)?1:0)HINSTANCEg_hInstance;HWNDg_hWnd;intg_nCmdShow;//declare global game engine objectDeathChicken::Engine*g_engine;boolgameover;//window event callback functionLRESULTWINAPIWinProc(HWNDhWnd,UINTmsg,WPARAMwParam,LPARAMlParam){switch(msg){caseWM_QUIT:caseWM_CLOSE:caseWM_DESTROY:gameover=true;break;}returnDefWindowProc(hWnd,msg,wParam,lParam);}intWINAPIWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPSTRlpCmdLine,intnCmdShow){MSGmsg;srand((unsignedint)time(NULL));g_hInstance=hInstance;g_nCmdShow=nCmdShow;DWORDdwStyle,dwExStyle;RECTwindowRect;/** *Create engine object **/g_engine=newDeathChicken::Engine();//Let main program have a crack at things before window is createdif(!game_preload()){MessageBox(g_hWnd,"Error in game preload!","Error",MB_OK);return0;}//get window caption string from enginechartitle[255];sprintf(title,"% s",g_engine->getAppTitle().c_str());//set window dimensionswindowRect.left=(long)0;windowRect.right=(long)g_engine->getScreenWidth();windowRect.top=(long)0;windowRect.bottom=(long)g_engine->getScreenHeight();//create the window class structureWNDCLASSEXwc;wc.cbSize=sizeof(WNDCLASSEX);//fill the structure with infowc.style=CS_HREDRAW|CS_VREDRAW;wc.lpfnWndProc=(WNDPROC)WinProc;wc.cbClsExtra=0;wc.cbWndExtra=0;wc.hInstance=hInstance;wc.hIcon=NULL;wc.hCursor=LoadCursor(NULL,IDC_ARROW);wc.hbrBackground=NULL;wc.lpszMenuName=NULL;wc.lpszClassName=NULL;wc.hIconSm=NULL;//setup window with class infoRegisterClassEx(&wc);//setup the screen in window mode or full screen?if(g_engine->getFullscreen()){DEVMODEdm;memset(&dm,0,sizeof(dm));dm.dmSize=sizeof(dm);dm.dmPelsWidth=g_engine->getScreenWidth();dm.dmPelsHeight=g_engine->getScreenHeight();dm.dmBitsPerPel=g_engine->getColorDepth();dm.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;if(ChangeDisplaySettings(&dm,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL){MessageBox(NULL,"Display mode failed",NULL,MB_OK);g_engine->setFullscreen(false);}dwStyle=WS_POPUP;dwExStyle=WS_EX_APPWINDOW;ShowCursor(FALSE);}else{dwStyle=WS_OVERLAPPEDWINDOW;dwExStyle=WS_EX_APPWINDOW|WS_EX_WINDOWEDGE;}//adust window to true requested sizeAdjustWindowRectEx(&windowRect,dwStyle,FALSE,dwExStyle);//create the program windowg_hWnd=CreateWindowEx(0,title,//window classtitle,//title bardwStyle|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,0,0,//w, y coordswindowRect.right-windowRect.left,//width of the windowwindowRect.bottom-windowRect.top,//height of the window0,//parent window0,//menug_hInstance,//game's app instance0);//window parameters//window creation error?if(!g_hWnd){MessageBox(g_hWnd,"Error creating program window!","Error",MB_OK);return0;}//display the windowShowWindow(g_hWnd,g_nCmdShow);UpdateWindow(g_hWnd);//initialize game-engineg_engine->setWindowHandle(g_hWnd);if(!g_engine->Init(g_engine->getScreenWidth(),g_engine->getScreenHeight(),g_engine->getColorDepth(),g_engine->getFullscreen())){MessageBox(g_hWnd,"Engine Initialization is buggered","Error",MB_OK);return0;}//main message loopgameover=false;while(!gameover){while(PeekMessage(&msg,NULL,0,0,PM_REMOVE)){TranslateMessage(&msg);DispatchMessage(&msg);}g_engine->Update();}if(g_engine->getFullscreen()){ShowCursor(TRUE);}g_engine->Close();deleteg_engine;return1;}
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Here is that log when I compile WinMain.cpp from engine project:
That does not look like a log from a "Rebuild All" as I requested.
However what I can tell from your logs is that the ChknTest project compiles
main.cpp and links it to libDeathChicken.a. The libDeathChicken project
compiles WinMain.cpp and places it in the libDeathChicken.a archive (library).
What is clearly evident is that _nowhere _are either Timer.cpp or
DeathChicken.cpp compiled and linked or archived. Which brings us back to the
answer I gave in post #5 of this thread; these files must be added to the
project to be compiled; presumably they are part of the engine so need to be
added to the libDeathChicken project?
I figured I might as well post the rest of it
Since these are linker errors, the code is largely irrelevant. A list of files
would have been useful however, so what you posted serves that purpose at
least. The full logs from a rebuild all would also have provided more
information, but I believe I have managed to infer all that was necessary from
what you have posted.
You need to add timer.cpp and DeathChicken.cpp to your library project,
rebuild it and then link the _new _library to your test project. Good luck.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I think you will find that ability to operate a computer is a prerequisite to
being able to program one. The natural curiosity that would make you an
effective programmer should also have caused you to at least browse the
Dev-C++ menu strip and context (right-click) menus, in which case the answer
to your question should be obvious.
Either:
1) Project->Add file
2) Right click on the project name in the project pane, and select "Add files"
As I said in post #3; you do have to create a project to compile and link
multiple sources. If you have not done so, then the above menus will not be
available. Perhaps less obvious is that fact that once you have created a
project, you should set it up via the Project->Project Options... dialog, not the Tools->Compiler... dialog; the latter are the starting options for
new projects (unless overridden by a template), and should be generic and not
project specific; so for example do not add third-part libraries there unless
they will be used in all your projects, and even then a template may be a
better solution.
The actual menu names may differ; I do not recall exactly since I no longer
bother to install Dev-C++ - it is no longer maintained, and its debugger
sucks, and there are better alternatives, there are few compelling reasons to
continue using it.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hello.
I am reading "Advanced 2D Game Development" by Jonathan S. Harbour and I am
attempting to follow along. I have created the three .h files and the three
.cpp files as he lays out (I am using the bloodshed IDE Version 4.9.9.2) and
have created the test program as it is written in the book:
Everything is mostly working, but I am getting a series of Linker errors that
I do not understand. I have been doing some searches, but nothing that looks
like it will help. Here are the linker errors:
What I am finding is weird, is that these are some of the methods from
DeathChicken.h and DeathChicken.cpp, but not all of them. What should I be
looking for to get this to work?
I zipped my files in case someone needs to look at them to help. I do not see
a way to attach them to the forum, but if you mail me at DIntentGmailcom I
will send the zip file to you. (it is only 829KB)
Post the complete build log text from the "Compile Log" tab not the
"Compiler" tab. It is plain text so is a simple copy and paste, and it
contains all the necessary diagnostic information including how your project
is setup.
Note that you do need to create a project for a multi-module build, and add
all your source files to the project, otherwise the linker will not know
what to include in the build. I strongly suspect that that is your problem.
The "Compile Log" will have told us if that were the case, which is why in the
PLEASE READ BEFORE POSTING A QUESTION thread, you are requested to post
it!
The linker will only attempt to resolve references to symbols actually
referenced in the compiled code. If there were no references to the other
symbols, there is nothing to resolve!
Sorry.
Here is the compile log:
Compiler: Default compiler
Building Makefile: "D:\Dev-Cpp\ChknTest\Devcpp\Makefile.win"
Executing make...
make.exe -f "D:\Dev-Cpp\ChknTest\Devcpp\Makefile.win" all
g++.exe ./obj/main.o -o "..\bin\ChknTest.exe" -L"D:/Dev-Cpp/lib"
-L"../../Engine/lib/" -mwindows -lDeathChicken -ld3d9 -ld3dx9 -ldxguid -lwinmm
-luser32 -lgdi32
./obj/main.o(.text+0x184):main.cpp: undefined reference to
DeathChicken::Engine::getVersionText()' ./obj/main.o(.text+0x1ac):main.cpp: undefined reference to
DeathChicken::Engine::message(std::string, std::string)'../../Engine/lib//libDeathChicken.a(WinMain.o)(.text+0x1e8):WinMain.cpp:
undefined reference to
DeathChicken::Engine::Engine()' ../../Engine/lib//libDeathChicken.a(WinMain.o)(.text+0x6d9):WinMain.cpp: undefined reference to
DeathChicken::Engine::Init(int, int, int, bool)'../../Engine/lib//libDeathChicken.a(WinMain.o)(.text+0x795):WinMain.cpp:
undefined reference to
DeathChicken::Engine::Update()' ../../Engine/lib//libDeathChicken.a(WinMain.o)(.text+0x7d8):WinMain.cpp: undefined reference to
DeathChicken::Engine::Close()'collect2: ld returned 1 exit status
make.exe: *** Error 1
Execution terminated
It would appear that ../../Engine/lib/libDeathChicken.a does not contain the
DeathChicken::Engine:: member functions you have made reference to or indeed
the members it makes reference to itself. Are these implementatuions that you
have provided in separate modules? The only Object file you are linking is
main.o; you said tehre were three .cpp files, but you have only compiled and
linked one. So as I said, you need to use a 'project' (File->New->Project),
and add all the .cpp sources to it as well as setting up the library paths and
libraries to be linked.
"implementatuions" !!! -> implementations
The six other files are supposed to collapse down into DeathChicken.a, as for
DeathChicken.h, it is supposed to reference the other files. Maybe I
configured the project wrong?
For that to work you must have had a separate project to build
libDeathChicken.a; perhaps you need to post the log from that (from a Rebuild
All), to see what it is composed of. That said, why bother with creating a
static library for this? You could just include all the sources in this
project.
When I get home I will post that.
The intent is that that the DeathChicken.a will eventually be an Engine, and
comes from a book called "Advanced 2D Game Development" by Jonathan S.
Harbour.
The program I am attempting to write here is just to initialize the engine and
make sure it works. (LOL! I'm not doing too good!)
Here is that log when I compile WinMain.cpp from engine project:
Compiler: Default compiler
Building Makefile: "D:\Dev-Cpp\Engine\Devcpp\Makefile.win"
Executing make...
make.exe -f "D:\Dev-Cpp\Engine\Devcpp\Makefile.win" all
ar r ../lib/libDeathChicken.a ./obj/WinMain.o
ar: creating ../lib/libDeathChicken.a
ranlib ../lib/libDeathChicken.a
Execution terminated
I figured I might as well post the rest of it. DeathChicken.h:
Timer.h:
WinMain.h:
DeathChicken.cpp:
Timer.cpp:
WinMain.cpp:
That does not look like a log from a "Rebuild All" as I requested.
However what I can tell from your logs is that the ChknTest project compiles
main.cpp and links it to libDeathChicken.a. The libDeathChicken project
compiles WinMain.cpp and places it in the libDeathChicken.a archive (library).
What is clearly evident is that _nowhere _are either Timer.cpp or
DeathChicken.cpp compiled and linked or archived. Which brings us back to the
answer I gave in post #5 of this thread; these files must be added to the
project to be compiled; presumably they are part of the engine so need to be
added to the libDeathChicken project?
Since these are linker errors, the code is largely irrelevant. A list of files
would have been useful however, so what you posted serves that purpose at
least. The full logs from a rebuild all would also have provided more
information, but I believe I have managed to infer all that was necessary from
what you have posted.
You need to add timer.cpp and DeathChicken.cpp to your library project,
rebuild it and then link the _new _library to your test project. Good luck.
So how do I add these to the project?
I think you will find that ability to operate a computer is a prerequisite to
being able to program one. The natural curiosity that would make you an
effective programmer should also have caused you to at least browse the
Dev-C++ menu strip and context (right-click) menus, in which case the answer
to your question should be obvious.
Either:
1) Project->Add file
2) Right click on the project name in the project pane, and select "Add files"
As I said in post #3; you do have to create a project to compile and link
multiple sources. If you have not done so, then the above menus will not be
available. Perhaps less obvious is that fact that once you have created a
project, you should set it up via the Project->Project Options... dialog,
not the Tools->Compiler... dialog; the latter are the starting options for
new projects (unless overridden by a template), and should be generic and not
project specific; so for example do not add third-part libraries there unless
they will be used in all your projects, and even then a template may be a
better solution.
The actual menu names may differ; I do not recall exactly since I no longer
bother to install Dev-C++ - it is no longer maintained, and its debugger
sucks, and there are better alternatives, there are few compelling reasons to
continue using it.