====== Standalone Applications ====== ===== Setup ===== Alrighty, time to set up the next part of our system. Just for a quick reminder, we're creating a stand-alone project in "C:\MyProject\" for windows users (and this will be my default example) or "~/MyProject/" for Linux users. Okay, lets get to it! We're going to create a couple of new files first: StandAlone.cpp and StandAlone.h ===== Code ===== Okay, Step two, our code: Lets do some good old copy-paste for now, and afterward I'll explain what each piece does. Firstly, We'll create the header for our "StandAlone" class: ==== StandAlone.h (This is a new file!) ==== #ifndef __STANDALONE_H__ #define __STANDALONE_H__ We can also use a simple "#pragma once" line instead, however the vagaries of my mind suggest that this is not supported "everywhere" and as I'm hoping to give you guys a nice cross-platform engine, I won't be using it. #include "orx.h" // We want to interface with ORX, so including it is helpful! :) class StandAlone { public: static StandAlone* Instance(); Our "StandAlone" class is going to be a singleton, so instead of having a public constructor and deconstructor ( StandAlone() and ~StandAlone() ) we're instead only going to have an "Instance()" function. static orxSTATUS orxFASTCALL Init(); static orxSTATUS orxFASTCALL Run(); static void orxFASTCALL Exit(); Next are our static function definitions, Init, Run and Exit, I'll give some more details on these later. protected: StandAlone(); StandAlone(const StandAlone&); StandAlone& operator= (const StandAlone&); Here we create our private constructor, and a few other lovely functions for handling our singleton class. private: static StandAlone* m_Instance; }; #endif // __STANDALONE_H__ And finally we finish up with our private instance variable, and the required #endif to close out our header. Next on the menu, we cook up our class body. Stuff and bake some functions, and enjoy the tasty source... mmmm delicious! ==== StandAlone.cpp (This is a new file!) ==== #include "StandAlone.h" StandAlone* StandAlone::m_Instance = NULL; Okay to start us off, we need to include our header (but you all knew that already right? ^_^) and nullify our singleton instance, this ensures we've got a nice clean pointer to play with later. StandAlone* StandAlone::Instance () { // This is -NOT- a thread-safe function. I won't be covering thread safety as it is outside the scope of this tutorial. // (If this matters to you, you should be able to find resources anyway, good luck! ^_^) if( m_Instance != NULL ) { return m_Instance; } m_Instance = new StandAlone; return m_Instance; } Next, our instance function. This function is intended to make sure we only ever have one copy of our class, and never any more. It simply checks if we've got one already (m_instance) and if we do, it returns that, otherwise it creates a copy and puts it where we can access it. Neat hey! :) StandAlone::StandAlone() { } Our constructor, does nothing much so far... give it time ^_^. orxSTATUS orxFASTCALL StandAlone::Init() { orxViewport_CreateFromConfig( "Viewport" ); return orxSTATUS_SUCCESS; } Okay, The fun starts now! -- Our Init() function is a lovely little 'setup' call, essentially this is where we can do all sorts of fun things like loading config files, manually (in code) creating scenes, or just (as in our case) load up the viewport from the default configuration file. orxSTATUS orxFASTCALL StandAlone::Run() { return orxSTATUS_SUCCESS; } void orxFASTCALL StandAlone::Exit() { return; } These two functions, again don't do much yet, however 'Run' is a good place to add anything you want to run outside the default engine hierarchy... meaning anything you put in there will not conform to timing standards, won't run on the clocks, and will try to process as often as possible. Exit is called, you guessed it, on exit! Do clean-up calls and the ilk in here. Make sure your computer memory is as pristine as it was when you arrived ;) Righty-o... NEXT! ==== Main.cpp (This is a new file!)==== #include "StandAlone.h" int main( int argc, char** argv ) { orx_Execute( argc, argv, StandAlone::Init, StandAlone::Run, StandAlone::Exit ); return 0; } Huge file hey... orx_Execute is a nice little helper function that essentially sets up the orx internals. The "Init" function is called first, then each loop Run is called, followed by Exit when we're cleaning up afterwards. You are not required to use this function! And as it is fully implemented in the orx headers, you can take a look at exactly what it does, so you can implement your own version if you don't like it. ===== Config ===== This is a work in progress, so as yet, lacks details. First file is the "initialisation file" -- this should be named the same as your project's exe. In my case, this is "project.ini" and "project_d.ini" (for the debug version). This file is used to set up the subsystems of the orx engine. Things like the Window size and settings, the sound options and the physics. At this point, I believe these -need- to be set up in this file, else they won't work at any later stage. [happy to be corrected!] In our test case we do two things. First, we set up the game window to be 640x480, write the word "Project" on the window, and ask the game to load our second file, called "MainMenu.ini". //This file should be created in the same directory as your project's INI file.// **__//!! IMPORTANT !!//__** Remember you will need to name this file the same as your executable, "Project.exe" becomes "Project.ini" and our debug exe "Project_d.exe" becomes "Project_d.ini". These files should be created in the same directory as your project's exe: "C:\MyProject\bin\Project.ini" will be loaded by "C:\MyProject\bin\Project.exe". ==== Project.ini (This is a new file!) ==== ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ; This is the default initialisation configuration file. ; Display, Input, Locale, Physics and Sound go here. ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ; [Display] ; Title = ; Title for the main display. Will be empty if none is provided. ; Font = path/to/FontFile ; Specifies a default font when creating orxTEXT structures. If no value is specified, the arial font will be used by default on most systems. ; Decoration = ; In windowed mode, this will define if decorations (ie. window borders, buttons, …) will be used for the main display window. This property is enabled by default. ; FullScreen = ; Defines if the main display will be full screen or windowed. This property is set to false by default. ; ScreenWidth = ; Resolution width for the main display in pixels. Must be provided. ; ScreenHeight = ; Resolution height for the main display in pixels. Must be provided. ; ScreenDepth = ; Resolution depth for the main display in bits. Defaults to 32bit. ; Smoothing = ; Sets the default antialiasing mode (ie. with or without antialiasing). Defaults to false (ie. no antialiasing). ; VSync = ; Enables/disables the vertical synchronization. Will use system defaults if none is provided. Best results are usually achieved by enabling this property. [Display] ;=================================== Title = Project Decoration = true FullScreen = false ScreenWidth = 640 ScreenHeight = 480 ScreenDepth = 32 VSync = true Smoothing = false ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ; [Input] ; DefaultThreshold = ; Sets the threshold value under which joysticks' axis values are ignored. This property's default value is 0 (ie. any input, as small as it is, will be considered). ; SetList = ; Provides a list of all available input sets. All these sets need to be defined in their own config section so as to be considered valid. The first valid set of this list will be selected by default as the current input set. ; [InputSet1] ; Every input action can be linked to up to 4 different physical inputs. ;