Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411491 Posts in 69377 Topics- by 58433 Members - Latest Member: graysonsolis

April 29, 2024, 10:49:02 AM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)Post your main function(s)
Pages: 1 [2] 3 4 5
Print
Author Topic: Post your main function(s)  (Read 16549 times)
Movius
Guest
« Reply #20 on: January 20, 2009, 01:04:54 AM »

int main(int argc, char *argv[]) {   
   Engine e;
   int rtn = e.go();
   cout << rtn << endl;
}
Logged
Mr. Yes
Level 5
*****



View Profile WWW
« Reply #21 on: January 20, 2009, 02:42:10 AM »

We need more of these kinds of threads. I'm seeing all these awesome ways of doing the same thing.

Like, we need a series of threads in the same style. "Post your collision function", "Post your <whatever> function"

Logged

bateleur
Level 10
*****



View Profile
« Reply #22 on: January 20, 2009, 03:27:59 AM »

OK, so it's not called "main()", but that's what it is really...

Code:
public function go() {

 FilePlatform.wantFilePlatform();
 // WebPlatform.wantWebPlatform();
 // SWFPlatform.wantSWFPlatform();

 var baseScreen:Sprite = new Sprite();
 addChild(baseScreen);
 var launcher:GameLauncher = new GameLauncher(baseScreen);

 launcher.devMode(true);
 // DemoManager.setDemoInstance(launcher);
 trace("[game name removed].go() - Synchronous init complete.");

}
Logged

Trevor Dunbar
Level 10
*****


Working on unannouned fighting game.


View Profile
« Reply #23 on: January 20, 2009, 03:39:46 AM »

Code:
void MainLoop()
{
//create game objects
InitGame(Players);

    while(HandleMessages())
    {
Input(&InputData);
        Logic(&GameGlob, Players, &InputData);
        Render(&GameGlob, Players, &InputData);
    }
}
Logged

Toucantastic.
Madgarden
Level 1
*


C=


View Profile
« Reply #24 on: January 20, 2009, 04:24:00 AM »

Code:
int main (void)
{
int logic_updated = TRUE;
int skip = 0;
int alt = 0;
char* foo = ALLEGRO_VERSION_STR;
unsigned int frames;

allegro_init();

#ifdef OPENGL
install_allegro_gl();
{
foo = AGL_VERSION_STR;
}
#endif

install_keyboard();
install_joystick(JOY_TYPE_AUTODETECT);
install_sound(DIGI_AUTODETECT, MIDI_NONE, NULL);

install_timer();
install_int_ex(ticker, BPS_TO_TIMER (LOGIC_SPEED));
install_int_ex(fps_ticker, BPS_TO_TIMER (1));

set_config_file("saucelifter.cfg");

load_config();

if(!sounds_load())
{
sounds_unload();
allegro_message("Problem loading the sound files, check your "
"installation");
return -1;
}

if(!try_video_mode())
{
allegro_message("Unable to set a video mode");
return -1;
}

set_display_switches();
set_close_button_callback(close_window_callback);

calibrate_joystick(0);

three_finger_flag = FALSE;

main_seed = time(NULL);

timer_ticks = 0;
frames = 0;
logic_ticks = 0;

turtle_init();
set_coords_scale((double)buffer->w / x_units, (double)buffer->h / y_units);
flip_y(TRUE);

if(!option_windowed.value)
{
clear_to_color(screen, makecol(32, 32, 32));
rest(2000);
}

scroller_reset();

state_switch(&title_state);

while(!quit && !close_window)
{
if(bg == TRUE)
{
rest(10);
continue;
}

while(frames < timer_ticks)
{
frames++;
skip++;

input_poll();

pressed_key = input_key;
pressed_char = input_char;

/*
if(pressed_key == KEY_T)
{
state_switch(&test_state);
}

if(pressed_key == KEY_E)
{
level_score = 50007;
pressed_key = 0;
highscores_entry();
}
*/
if(input_alt == KEY_ENTER << 8)
{
option_windowed.value = !option_windowed.value;
if(!try_video_mode())
{
allegro_message("Unable to set a video mode");
quit = TRUE;
}

alt = 0;
frames = timer_ticks;
continue;
}

state_update();

logic_updated = TRUE;

if(!game_pause)
{
logic_ticks++;
}

if(timer_ticks - frames > MAX_FRAMESKIP)
{
frames = timer_ticks;
break;
}
}

if(logic_updated && (skip > option_frameskip.value))
{
fps_ticks++;
skip = 0;

acquire_bitmap(buffer);
state_render();
draw_fps();
release_bitmap(buffer);

logic_updated = 0;

#ifdef OPENGL
allegro_gl_flip();
#else
if(page_flip)
{
tmp = buffer;
buffer = page;
page = tmp;
show_video_bitmap(page);
}
else
{
blit(buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
}
#endif
}
else
{
rest(1);
}
}

clean_up();
sounds_unload();
save_config();

return 0;
}
END_OF_MAIN()
Logged
BorisTheBrave
Level 10
*****


View Profile WWW
« Reply #25 on: January 20, 2009, 04:29:46 AM »

A flash project of mine. It uses Flash's events, so the init code and game loop code are separate.

Game loop:
Code:
public function step(dt:Number) : void {
//Adjust dt
//Update things
onStep.dispatchEvent(new Event(STEP));
//Apply gravity
applyGravity(dt);
//Update world
_world.Step(dt, iterations);
//Update timing
_currentTime += dt;
while (timers.length > 0) {
var timer:Object = timers[0];
if (timer.time > _currentTime)
break;
timer.call();
timers.shift();
}
//Cleanup
cleanup();
//Update graphics
updateGraphics();
}

Init (at the moment, it's only loading some demo stuff, as I don't have resource loading done yet).
Code:
public function Main() {
world = new World(this);
world.addXML(<level>
<!--Walls-->
<box right=".1" width="5" top="-1" bottom="21"/>
<box left="19.9" width="5" top="-1" bottom="21"/>
<box left="-1" right="21" bottom=".1" height="5"/>
<box left="-1" right="21" top="19.9" height="5"/>
<!--Ball-->
<body x="15" y="7">
<circle radius="1"/>
<group>ball</group>
</body>
<!--Paddle-->
<box x="10" y="18" width="3" height="0.5"/>
<map x="3" y="3" width="5" height="5" tilewidth="15" tileheight="15">
<tileset>
  <tile><body><box x="0" y="0" width=".5" height=".5" density="0"/><group>brick</group></body></tile>
  <tile><body><circle radius=".25" density="0"/><group>brick</group></body></tile>
</tileset>
<layer name="Layer 0" width="17" height="17">
  <data encoding="base64">
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAABAAAAAAAAAAIAAAACAAAAAQAAAAAAAAABAAAAAAAAAAIAAAACAAAAAQAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAEAAAAAAAAAAgAAAAIAAAABAAAAAAAAAAEAAAAAAAAAAgAAAAIAAAABAAAAAAAAAAEAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAABAAAAAQAAAAEAAAABAAAAAQAAAAAAAAABAAAAAQAAAAEAAAABAAAAAQAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAABAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAEAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAEAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
  </data>
</layer>
</map>
</level>);
world.onMouseDown.addEventListener(Actor, function(event:MouseEvent) {
event.target.groups.add("dragged");
event.target.startDrag(event.shiftKey?0:1,event.altKey);
} );
stage.addEventListener(MouseEvent.MOUSE_UP, function(event:MouseEvent) {
if(!event.ctrlKey)
for each(var actor:Actor in world.getActors("dragged"))
{
actor.groups.remove("dragged");
actor.stopDrag();
}
});
//world.onMouseUp.addEventListener(Pattern.any, function(event:MouseEvent) { trace(event.target) } );

world.onContactAdd.addEventListener("ball", "brick", handleHit);

}
Logged
Zaknafein
Level 4
****



View Profile WWW
« Reply #26 on: January 20, 2009, 06:33:52 AM »

XNA main functions are kinda boring...

Code:
        [STAThread]
        static void Main(string[] args)
        {
            Logger.Clear();

            if(args.Length == 0)
                Logger.Try(MainInternal, null as string);
            else
                Logger.Try(MainInternal, args[0]);
        }

        static void MainInternal(string forcedLevelName)
        {
            using (var game = new Fez(forcedLevelName))
            {
                game.Run();
            }
        }
Logged

nihilocrat
Level 10
*****


Full of stars.


View Profile WWW
« Reply #27 on: January 20, 2009, 08:20:13 AM »

Endless Cavern

Code:
main :: IO()
main = do
 initializeGame
 mainLoop

Wait, you wrote that game in Haskell? Props. Gentleman

Some of this stuff might be overkill:
Code:
if __name__ == '__main__':
    pyglet.resource.path.append('data')
    pyglet.resource.path.append('data/img')
    pyglet.resource.path.append('data/sound')
    pyglet.font.add_directory('data')
    pyglet.resource.reindex()
   
    main = View()

    map(main.register_event_type, globals.EVENT_TYPES)

    # catch all exceptions if this is a release build and just print them to
    # the screen. This will make the app more "fault-tolerant" :)
    # things will simply fail, rather than cause the game to crash.
    if globals.DEBUG:
        pyglet.app.run()
    else:
        try:
            try:
                import psyco
                psyco.full()
            except ImportError:
                print "WARNING: Couldn't import psyco, performance might be bad."     
            pyglet.app.run()
        except:
            print "[%s] ERROR : " % (time.ctime(time.time())),
            traceback.print_exc()
       
« Last Edit: January 20, 2009, 08:24:33 AM by nihilocrat » Logged

mirosurabu
Guest
« Reply #28 on: January 20, 2009, 08:29:06 AM »

Here's the main loop from "Uneksians" source code:

Code:
int main()
{
Game *game = new Game;

game->Init();
game->Run();

delete game;

return 0;
}
END_OF_MAIN()

And some plain WinAPI mess from old game editor I was working on.

Code:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nCmdShow)
{
MSG msg;
HANDLE hAccelTable;
HDC hDC;
short err;

hInst = hInstance;

InitCommonControls();

InitDatabase();

if (CreateWindowClass()) { FatalError(ERR_MAINCLASS); return 0; }
RegisterTableClass();

hAccelTable = LoadAccelerators(hInst,MAKEINTRESOURCE(IDACCEL));

if (!(hwndMain = CreateMainWindow())) { FatalError(ERR_WND); return 0; }

if (CreateListBox()) { FatalError(ERR_LISTBOX); return 0; }
if (err = CreateCitiesWindow()) { FatalError(err); return 0; }
if (CreateCustomComboBox()) { FatalError(ERR_CCB); return 0; }
if (CreateSortComboBox()) { FatalError(ERR_CB_SORTBY); return 0; }
CreateSearchWindow();
CreateButtons();
CreateCountriesWindow();
CreateBusinessesWindow();

if (LoadDatabase()) IO_Error("data\\city.gam");

ShowWindow(hwndMain, SW_SHOW);

while (GetMessage(&msg,NULL,0,0)) {
if (!TranslateAccelerator(msg.hwnd,hAccelTable,&msg)) {
  TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
« Last Edit: January 20, 2009, 08:45:57 AM by mirosurabu » Logged
Pishtaco
Level 10
*****


View Profile WWW
« Reply #29 on: January 20, 2009, 09:20:08 AM »

These are from game maker, so I'm posting the main block of code that gets executed each step rather than the main() function as such.

S.T.A.C.K.E.R. - this is mostly code for handing the actual gameplay loop. The game ended up messy enough that I didn't fix some things that would have been simple if I had organized it properly.
Code:
if ((paused == false) and (front_end == false)) {

do_effects();

switch(game_state) {
   
case Moving_Piece_State:
   
    if (active_piece != noone) {
        if (poltergeist_attacking and poltergeist_time==0) {
            poltergeist_throwing_piece();
            }
        else {
            if (overburdened_count = 0) control_piece_with_keys(active_piece);
        }
        if cheating do_cheats();
        }

    if (next_tick <= 0) {  // actions on tick go here
               
        if (active_piece != noone) {   //(piece might already have gone)
            if (movedown == 0 and not(poltergeist_attacking))
                    move_down_piece(active_piece);
            //i.e. if player hasn't moved it already this frame
        }
       
        if (active_piece == noone) {
       

            process_grid();
           
            if (number_full_lines>0) {
                change_state(Display_Clearing_Grid_State,6);
            }
            else end_turn();
        }
    }
    break;
   
case Display_Clearing_Grid_State:

    if (next_tick <= 0) {
        with (obj_fader) instance_destroy();
        remove_dead_pieces();
        collapse_grid();
        number_full_lines = 0;
        end_turn();
    }
    break;
   
case Enemy_Attacking_State:
    //if keyboard_check_pressed(vk_anykey) next_tick = 0;
    if (next_tick <= 0) {
        with (obj_exploder) instance_destroy();
        with (obj_fader) instance_destroy();
        with (obj_pulser) instance_destroy();
        with (obj_burner) instance_destroy();
        with (obj_flamer) instance_destroy();
        if (poltergeist_piece != noone)
            finish_fading_piece_from_grid(poltergeist_piece);
        if (water_level == water_one_line)
            finish_clearing_water_line();
        message_string = "";
        damage = 0; raddamage =0;
        //check_for_empty_lines();
        //collapse_grid();
        start_new_turn();
    }
    break;
   
case Entering_Area_State:
    if (next_tick <= 0) {
        message_string = "";
        start_new_turn();
    }
    break;

case Overburdened_State:
    damage = 0;
    message_string = "OVER-#BURDENED!";
    message_colour = c_black;
    message_background_colour = c_red;
    if (next_tick == 1) {
        message_string += "#PRESS ENTER";
        flickerpoint = false;
        }
    if (next_tick <=0) {
        finish_action();
        front_end_state = "OVERBURDENED";
        front_end_time = 0;
    }
    break;
   
case Dead_State:
    damage = 0;
   message_string = "YOU HAVE#DIED!";
    message_colour = c_black;
    message_background_colour = c_red;
    if (next_tick == 1) {
        message_string += "#PRESS ENTER";
        flickerpoint = false;
        }
    if (next_tick <=0) {
        finish_action();
        front_end_state = "DEAD";
        front_end_time = 0;
    }
    break;
   
case Target_Not_Met_State:
   message_string = "TARGET SCORE#NOT MET!";
    message_colour = c_white;
    //message_background_colour = c_red;
    if (next_tick == 1) {
        message_string += "#PRESS ENTER";
        flickerpoint = false;
        }
    if (next_tick <=0) {
        finish_action();
        front_end_state = "TARGET_NOT_MET";
        front_end_time = 0;
    }
    break;
   
case Level_Completed_State:
   message_string = "LEVEL#COMPLETED!";
    message_colour = c_white;
    if (next_tick == 1) {
        message_string += "#PRESS ENTER";
        flickerpoint = false;
        }
    if (next_tick <=0) {
        finish_action();
        switch(current_level_number) {
            case 0:
                if (highest_level_unlocked == 0) highest_level_unlocked = 1;
                save_score_table();
                front_end_state = "LEVEL1_COMPLETED";
                front_end_time = 0;
                break;
            case 1:
                if (highest_level_unlocked == 1) highest_level_unlocked = 2;
                save_score_table();
                front_end_state = "LEVEL2_COMPLETED";
                front_end_time = 0;
                break;
            case 2:
                front_end_state = "LEVEL3_COMPLETED";
                front_end_time = 0;
                break;
        }
    }
    break;
   
case Poltergeist_Message_State:
    if (next_tick <= 0) {
        message_string = "";
        damage = 0;
        poltergeist_attacking = false;
        change_state(Moving_Piece_State,0);
    }
    break;

   
   
default:
   
}

if not(dead) check_life();

if (next_tick > 0) next_tick -= 1
 else next_tick = 30/game_speed;
 
}
else {
if (front_end == true) front_end_handler();
}

The Clatter of the Keys - this is code to do timing so vsync works correctly, and the high-level structure of the whole game; the actual gameplay is in case 2. It has some redundancy but it feels fairly sensibly laid out to me, for a game of this size. I'm curious to know how people usually lay out the code for the gameplay versus the code for the front end menus.
Code:
// game_state
// 0 - splash screen
// 5 - instructions
// 6 - setup keys   
// 1 - waiting to start
// 2 - normal gameplay
// 3 - game over
// 4 - typing name



screen_wait_vsync();
ms_bottom_of_screen = hrt_time_now() + ms_to_bottom_of_screen;

run_clock();

switch (game_state)
{
    case 0: //splash screen
        draw_background(scr_splash,0,0);

        if (keyboard_check(vk_anykey) and not(wait_for_release))
        {   
            fader_state = 1;
            fader_speed = 1/10;
            wait_for_release = true;
        }
       
        if (wait_for_release and
                fader_state == 2  and not(keyboard_check(vk_anykey)))
        {
            draw_clear(c_black);
            game_state = 5;
            wait_for_release = false;
            fader_state = 3;
        }
        break;

    case 5: //instructions screen
        draw_background(bkg_instructions,0,0);
       
        if (keyboard_check(vk_anykey) and not(wait_for_release))
        {   
            fader_state = 1;            //fade to black
            fader_speed = 1/10;
            wait_for_release = true;
            if keyboard_check(vk_f1) next_state = 6;
            else
            {   
                next_state = 1;   
                if file_exists("data\keys.dat") load_keys();
            }         
        }
       
        if (wait_for_release and
                fader_state == 2  and not(keyboard_check(vk_anykey)))
        {
            game_state = next_state;
            script_step = 0;
            wait_for_release = false;
            fader_state = 3;
            fader_speed = 1/40;
        }
        break;
       
    case 6: //setup keyboard
        setup_keyboard_script();
        break;
   
    case 1: //waiting for game to start
        draw_all();
        fader_speed = 1/40;

        if keyboard_check(vk_anykey)
        {
            game_state = 2;
            accept_keys = true;
        }
        break;
       
    case 2: //in normal game
        typewriter_step();
        phrases_step();
        do_progress();
        update_scores();
        draw_all();
       
        if (time_second == max_time or end_now)
        {
            finish_up_game();
            end_now = false;
            time_ended = time;
            accept_keys = false;
            script_step = 0;
            game_state =3;
        }
        break;
    case 3:
        typewriter_step();
        phrases_step();
        do_progress();
        update_scores();
        end_game_script();
        draw_all();
        break;
    case 4:
        typewriter_step();
        get_name_script();
        draw_all();
}

fader_handler();

ms_taken = hrt_time_now() - ms_bottom_of_screen+ms_to_bottom_of_screen;
while (hrt_time_now() < ms_bottom_of_screen)
{
    sleep(1); //wait until redrawing bottom
}

screen_refresh();    //then refresh


if keyboard_check_pressed(vk_f10)
{
end_now = true;
}
Logged

Massena
Level 4
****


Satisfied.


View Profile
« Reply #30 on: January 20, 2009, 09:58:19 AM »


all my main functions look exactly the same:

Code:
int main(int argc, char *argv[]) {	
GameApp *app = new GameApp();
while(app->Update()){}
return 1;
}


Why not?

Code:
int main(int argc, char *argv[]) {	
GameApp app();
while(app.Update()){}
return 1;
}

Is it the same thing?
Logged

mirosurabu
Guest
« Reply #31 on: January 20, 2009, 10:17:08 AM »

I guess allocating on heap is better because you may run out of stack with statically created object.
Logged
Ivan
Owl Country
Level 10
*


alright, let's see what we can see


View Profile
« Reply #32 on: January 20, 2009, 11:29:31 AM »

I don't think it makes any difference really. I tend to prefer dynamic allocation almost everywhere because I can shift things around as I code without worrying about scope.
Logged

http://polycode.org/ - Free, cross-platform, open-source engine.
BorisTheBrave
Level 10
*****


View Profile WWW
« Reply #33 on: January 20, 2009, 11:32:31 AM »

I don't think it makes any difference really. I tend to prefer dynamic allocation almost everywhere because I can shift things around as I code without worrying about scope.
Well you're fine in that example as the program exits afterwards, but don't you find having to keep track of finalization a pain if you shift things around though different scopes?
Logged
Ivan
Owl Country
Level 10
*


alright, let's see what we can see


View Profile
« Reply #34 on: January 20, 2009, 11:36:27 AM »

I don't think it makes any difference really. I tend to prefer dynamic allocation almost everywhere because I can shift things around as I code without worrying about scope.
Well you're fine in that example as the program exits afterwards, but don't you find having to keep track of finalization a pain if you shift things around though different scopes?

Most dynamically allocated stuff in my code is usually kept track of by various managers, (and a lot of it is created by factory patterns which assign the instances to proper managers), which are responsible for cleaning up after themselves, so it works out well.
Logged

http://polycode.org/ - Free, cross-platform, open-source engine.
Flink
Level 1
*


Visiontrick


View Profile WWW
« Reply #35 on: January 20, 2009, 12:17:14 PM »

Main function for not yet named The Caffeine Lab game...

Code:
int main()
{
/*! Create engine */
Engine::getInstance()->Create();

/*! Set state */
Engine::getInstance()->SetEngineState(Engine::ProcessFlag::PF_UPDATE_PHYSICS, true);
        Engine::getInstance()->SetEngineState(Engine::ProcessFlag::PF_UPDATE, true);
        Engine::getInstance()->SetEngineState(Engine::ProcessFlag::PF_RENDER, true);

/*! Update/Render while engine is running */
while ( !Engine::getInstance()->GetEngineState( Engine::PF_EXIT_ENGINE ) )
{
/*! Update engine */
Engine::getInstance()->Update();

/*! Render engine */
Engine::getInstance()->Render();
}

// Destroy engine
Engine::getInstance()->Destroy();


return EXIT_SUCCESS;
}
Logged

Bob le Moche
Level 0
***



View Profile WWW
« Reply #36 on: January 20, 2009, 02:24:13 PM »

I usually use C++/OpenGL (with GLFW).
I decouple the rendering from the game ticks, so that if some frames take too long to render, they're skipped and the whole game doesn't slow down.
It also allows me to easily choose any length I want for a game tick.
Code:
#define TICKTIME 1/60.0

int main()
{
//Initialization ---------------
        //This is where I initialize opengl, load resources, load the game world, etc...
        //[...]

//Start Game ---------------------
double t0 = 0;
double t1 = 0;
glfwSetTime(0.0); //Initialize the timer
while(!glfwGetKey( GLFW_KEY_ESC ) && glfwGetWindowParam( GLFW_OPENED ))
{
//TICKS--------------------------
while(t1-t0 > 0) {
//Do game TICK
thegame.doTick();
t0 += TICKTIME;
}
//Do IO
thegame.renderGame();

//update timer
t1 = glfwGetTime();
}
        //Terminate graphics, sound etc...
        //[...]
exit(0); // Exit program
}

I also wrote a main loop that is actually like a multi-threaded job scheduler, it's so I can make an event-based game engine, where each individual object has its own variable rate of update instead of having a fixed global tick system.
There's a main rendering thread that keeps looping and halts on vsync, and then one thread for each processor you have that simultaneously process game object "jobs" by priority.
 I haven't made anything using it yet, though...
Logged
Bennett
Jinky Jonky and the Spell of the Advergamez 3
Level 10
*



View Profile
« Reply #37 on: January 20, 2009, 02:49:49 PM »

My new game doesn't have a main loop. The initialization function sets up separate actionscript timer functions for everything - player 1 animation, player 2 animation, scrolling, drawing, physics, and keyboard input. This is radical because you can change the duration of an AS3 timer anytime you like, so I can change the frame rate for each player independently while the game is running.
Logged
J. Kyle Pittman
Level 6
*


PostCount++;


View Profile WWW
« Reply #38 on: January 20, 2009, 11:03:05 PM »

I got fed up with my usual tendencies to allow my main() to get bloated with random initialization crap, so I resolved to whittle it down to a single line:

Code:
#include "MayflyGame.h"

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR cmdLine, int cmdShow)
{
NBaseGame::RunGame<MayflyGame>(hInst, hPrevInst, cmdLine, cmdShow);
}

RunGame() is implemented in my engine project:

Code:
class NBaseGame;

extern NBaseGame* gGame;

class NBaseGame
{

...

public:
template <class T> static void RunGame(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR cmdLine, int cmdShow)
{
T game;
gGame = &game;
game.run(hInst, hPrevInst, cmdLine, cmdShow);
gGame = NULL;
}
};

And finally, run() looks like this:

Code:
void NBaseGame::run(HINSTANCE _hInst, HINSTANCE _hPrevInst, LPSTR _cmdLine, int _cmdShow)
{
hInst = _hInst;
hPrevInst = _hPrevInst;
cmdLine = _cmdLine;
cmdShow = _cmdShow;

init();

while (update())
{
}

deinit();
}

So then init(), update(), and deinit() are virtual, and my derived game class implements those.
Logged

Guillaume
Level 7
**



View Profile
« Reply #39 on: January 21, 2009, 02:45:35 AM »

Quote
int main ( int argc, char** argv ){
    game=new Engine;

    game->loop();
    delete game;

    // all is well Wink
    cout << "Exited cleanly" << endl;
    return 0;
}

OMG, source code leaked!
Logged
Pages: 1 [2] 3 4 5
Print
Jump to:  

Theme orange-lt created by panic