handCraftedRadio
The Ultimate Samurai
Level 10
|
|
« Reply #40 on: January 21, 2009, 01:21:33 PM » |
|
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow) { strcpy(gEngine.cmdLine, lpCmdLine);
GameInit(&gEngine, hInstance);
GameStart(&gEngine);
MSG msg; ::ZeroMemory(&msg, sizeof(MSG));
while (msg.message != WM_QUIT) {
if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) { if (msg.message == WM_QUIT) { } else { TranslateMessage (&msg); DispatchMessage (&msg); } } else { gEngine.framelimit = (DWORD)70; while ((((gEngine.bfps-gEngine.efps))*gEngine.framelimit <= 1000.0)) { gEngine.bfps = timeGetTime(); } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); gEngine.fps = 1000.0f/((gEngine.bfps-gEngine.efps)); if (gEngine.bfps-gEngine.efps != 0) { gEngine.DrawText(20, 20, "%d", (int)gEngine.fps); }
gEngine.efps = gEngine.bfps;
HandleKeys(&gEngine); GameLoop(&gEngine); SwapBuffers (gEngine.hDC); } }
GameEnd(&gEngine); gEngine.ShutDown(); alutExit();
} My main functions are always gross so I write it once and try to never look at it ever again.
|
|
|
Logged
|
|
|
|
mjau
|
|
« Reply #41 on: January 21, 2009, 03:54:39 PM » |
|
Most of my main functions look like this: int main (int argc, char *argv[]) { (void)argc; (void)argv;
init(); loop(); return 0; } That one's from Trommel. Here's the loop function for that.. could've might as well put this in the main, don't know why I keep factoring it out.. static void loop (void) { unsigned int ltrigger = 0, logichz = lframe(); Uint32 now, then = SDL_GetTicks();
while (logichz) { while (logichz && ((ltrigger += ((now = SDL_GetTicks()) - then) * logichz) >= 1000)) { then = now; ltrigger -= 1000; logichz = lframe(); } then = now;
vframe(ltrigger); SDL_Delay(10); } } Try to ignore that while condition
|
|
|
Logged
|
|
|
|
Ivan
Owl Country
Level 10
alright, let's see what we can see
|
|
« Reply #42 on: January 21, 2009, 03:59:15 PM » |
|
(void)argc; (void)argv;
What's that about?
|
|
|
Logged
|
|
|
|
mjau
|
|
« Reply #43 on: January 21, 2009, 04:09:34 PM » |
|
It's just a way to tell the compiler to not warn about those variables being unused. It's easier to spot buggy stuff when the code compiles cleanly otherwise.
|
|
|
Logged
|
|
|
|
Ivan
Owl Country
Level 10
alright, let's see what we can see
|
|
« Reply #44 on: January 21, 2009, 04:12:37 PM » |
|
Ah nice, I didn't know about that trick.
|
|
|
Logged
|
|
|
|
Will Vale
|
|
« Reply #45 on: January 21, 2009, 05:26:22 PM » |
|
Great idea for a thread! A railway modelling forum I like had a similar one recently where we posted pictures of our workbenches - so much clutter! Here's WinMain from Space Effort. I'm trying to get out of the habit of making obvious comments but it's so ingrained that I'm not having much success yet: /** * Application entrypoint. Configure SIL and kick off the mainloop. */ int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { // Configure window graphics::Window::Options options; options.width = 640; options.height = 480; options.resizeable = false; options.title = SIL_LITERAL("Space Effort");
// Set it up. graphics::Window window; if ( window.Initialise( options ) ) { // Create device graphics::Device::Options options; options.max_renderers = 1; options.max_targets = 4; options.max_textures = 256; g_device = new graphics::Device(window); if ( g_device && g_device->Initialise( options ) ) { // Create renderer on the device if ( g_renderer = g_device->CreateRenderer() ) { // Initialise game g_resources = new Resources; if ( g_resources->Initialise() ) { // Execute game game_loop( window );
// Terminate game g_resources->Terminate(); }
// Clean up g_renderer->Delete(); g_renderer = NULL; } }
g_device->Terminate(); SIL_DELETE(g_device); }
return 0;
} // main The gameloop may also be of interest - it's in the same file. Pretty clunky, and uses a Screen abstraction as seen earlier in this thread: /** * Run the main game loop. */ static void game_loop( graphics::Window& window ) { // First frame Frame frame; Zero( frame );
// Hook mouse callback DXUTSetCallbackMouse( &mouse_callback, true );
// Create the world! const Galaxy galaxy(GALAXY_SEED); // Selected system const Galaxy::System *old_packed_system = NULL; const Galaxy::System *packed_system = NULL; const System::Body *packed_planet = NULL;
// Current system and planet (if any) System system(galaxy.systems[0]); Planet planet;
// The player Player player;
// HACK: Start new game player.Reset();
// Create screens IScreen *screens[SCREEN_COUNT] = { NULL, new BootScreen, new TitleScreen, new GalaxyMapScreen(galaxy, packed_system, player), // new SystemMapScreen(system, packed_planet), new PlanetMapScreen(planet, player), new OutdoorScreen(planet, player), };
// Allocate rendertarget graphics::Texture *target = g_device->CreateTarget( 320, 240 );
// Initialise screens for ( int i = 1; i < SCREEN_COUNT; ++i ) { if ( screens[i] ) screens[i]->Initialise(); }
// Start with active boot screen EScreen current_screen = BOOT_SCREEN; screens[current_screen]->Reset();
graphics::Texture *scanlines = g_device->CreateTexture( SIL_LITERAL("resources/raster.png") );
// While the window is open, update it. while ( window.Tick() ) { // If we have a screen... if ( screens[current_screen] ) { // Update frame frame.dt = DXUTGetElapsedTime();
// Don't allow really long frames - they mess things up. if ( frame.dt > 1.0f/20 ) frame.dt = 1.0f/20;
frame.time += frame.dt; ++frame.number;
// Update keys (HACK) update_button( frame.yoke.buttons[Yoke::SELECT], DXUTIsKeyDown( VK_RETURN ) ); update_button( frame.yoke.buttons[Yoke::CANCEL], DXUTIsKeyDown( VK_ESCAPE ) ); update_button( frame.yoke.buttons[Yoke::LEFT], DXUTIsKeyDown( VK_LEFT ) ); update_button( frame.yoke.buttons[Yoke::RIGHT], DXUTIsKeyDown( VK_RIGHT ) ); update_button( frame.yoke.buttons[Yoke::UP], DXUTIsKeyDown( VK_UP ) ); update_button( frame.yoke.buttons[Yoke::DOWN], DXUTIsKeyDown( VK_DOWN ) ); update_button( frame.yoke.buttons[Yoke::LMB], lmb ); update_button( frame.yoke.buttons[Yoke::RMB], rmb ); update_button( frame.yoke.buttons[Yoke::JETS], DXUTIsKeyDown( VK_SPACE ) );
// Update cursor frame.yoke.mouse_x = mouse_x; frame.yoke.mouse_y = mouse_y;
// Is this a big pixel screen? if ( target && screens[current_screen]->BigPixels() ) { // Scale input frame.yoke.mouse_x /= 2; frame.yoke.mouse_y /= 2; }
// Tick current screen const EScreen next_screen = screens[current_screen]->Tick( frame );
// Has the screen changed? if ( next_screen != current_screen ) { // If we're looking at a system on the map, unpack it on screen transition. if ( packed_system && packed_system != old_packed_system ) { system = System( *packed_system ); // Temp: Unpack planet. planet.Generate( system.bodies[0] );
old_packed_system = packed_system; }
// Change current_screen = next_screen;
// If we have one, wake it up. if ( screens[current_screen] ) { screens[current_screen]->Reset(); } else { // Otherwise, time to quit. window.Quit(); } } }
// If we still have a screen, draw it. if ( screens[current_screen] ) { if ( g_device->BeginFrame() ) { // For big pixel screens, capture to render target if ( target && screens[current_screen]->BigPixels() ) g_renderer->SetTarget( target );
// Normal drawing if ( g_renderer->BeginDrawing() ) { screens[current_screen]->Draw(); g_renderer->EndDrawing(); }
// For big pixel screens, copy render target over to double pixels if ( target && screens[current_screen]->BigPixels() ) { g_renderer->SetTarget( NULL );
if ( g_renderer->BeginDrawing() ) { // Draw the doubled pixels g_renderer->SetTexture( target ); graphics::DrawRectangle( *g_renderer, 0, 0, 640, 480 );
// Draw some scanlines with a mite of flicker. g_renderer->SetTexture( scanlines ); g_renderer->SetBlend( graphics::Renderer::ALPHA, graphics::Renderer::ONE_MINUS_ALPHA ); graphics::Colour black(0.0f, 0.0f, 0.0f); const Nat32 argb = black.ARGB(maths::Noise(frame.time * 3, 4) * 0.06f + 0.18f); graphics::DrawTiledRectangle( *g_renderer, 0, 0, 640, 480, *scanlines, argb ); g_renderer->EndDrawing(); } }
g_device->EndFrame(); } } }
// Destroy screens for ( int i = 0; i < SCREEN_COUNT; ++i ) { delete screens[i]; }
// Destroy target if ( target ) target->Delete();
} // game_loop
It's still pretty hacky, but I was in the middle of a big engine tidyup/rewrite and most of the things that should be there as standard were, well, not there. I've just started doing a bit more on the engine so maybe progress will be forthcoming this year... Cheers, Will
|
|
|
Logged
|
|
|
|
Bennett
Jinky Jonky and the Spell of the Advergamez 3
Level 10
|
|
« Reply #46 on: January 21, 2009, 05:44:07 PM » |
|
My main function is to bankroll my real-estate agent's Rolls Royce and provide a warm place for my cat to sit.
|
|
|
Logged
|
|
|
|
Mr. Yes
|
|
« Reply #47 on: January 21, 2009, 06:01:02 PM » |
|
Guys, forget my last main function, this is my real one: int main() { int muffin = 2;
beginning: muffin -= 1; goto end; getthefuckoutofthisplace: return muffin; middle: init(); game(); cleanup(); muffin -= 1; goto getthefuckoutofthisplace; end: muffin; muffin; muffin; goto middle; }
|
|
|
Logged
|
|
|
|
waruwaru
|
|
« Reply #48 on: January 21, 2009, 06:21:19 PM » |
|
It's just a way to tell the compiler to not warn about those variables being unused. It's easier to spot buggy stuff when the code compiles cleanly otherwise.
how about just int main(void)?
|
|
|
Logged
|
|
|
|
mjau
|
|
« Reply #49 on: January 22, 2009, 06:25:38 AM » |
|
Can't do that. SDL requires the main signature to be 'int main (int, char **)', because it replaces the main function on windows and some others with its own to handle platform-specific stuff (like WinMain).
|
|
|
Logged
|
|
|
|
Pigbuster
|
|
« Reply #50 on: January 22, 2009, 09:46:31 AM » |
|
// MAIN FUNCTION // int main(int argc, char *argv[]) { // INITIALIZE SDL // init(); // CREATE THE DRAWING SURFACE // //create_surface(0); // INITIALIZE OPEN GL // init_GL( SCREEN_WIDTH, SCREEN_HEIGHT ); SDL_ShowCursor(1); main_loop(); clean_up(0); //Should never get here return(0); } Dooby doop doo.
|
|
|
Logged
|
|
|
|
Gold Cray
|
|
« Reply #51 on: January 22, 2009, 11:25:46 AM » |
|
return(0);
Does that function contain anything other that just "return x;"?
|
|
|
Logged
|
|
|
|
curby
|
|
« Reply #52 on: January 22, 2009, 12:30:12 PM » |
|
This is my cleanest main yet! Normally they're quite a mess. int main( int argc, char* args[] ){ SDL_Init( SDL_INIT_EVERYTHING ); // Start SDL screenManager.Init(NULL); screenManager.Load(GAMESCREEN);
fps.start(); // Start the timer while(screenManager.Events()) // Wait for an escape key press { screenManager.Update((float)fps.elapsed()); screenManager.Render((float)fps.elapsed()); SDL_Delay(fps.TimeLeft()); // Maintain framerate fps.update(); // update the timer } //Quit SDL SDL_Quit(); return 0; }
|
|
|
Logged
|
|
|
|
waruwaru
|
|
« Reply #53 on: January 22, 2009, 04:46:18 PM » |
|
Can't do that. SDL requires the main signature to be 'int main (int, char **)', because it replaces the main function on windows and some others with its own to handle platform-specific stuff (like WinMain).
Ah, I see, thanks!
|
|
|
Logged
|
|
|
|
Kaelan
|
|
« Reply #54 on: January 23, 2009, 05:39:19 PM » |
|
This thread is lacking in primal evil, so here's the entry point and main gameloop function from my ancient (almost a decade old by now) game creation system... written in Visual Basic 6. Sub Main() On Error Resume Next Dim l_strFolder As String Dim l_bfBrowse As cBrowseForFolder Dim l_engEngine As Fury2Engine Dim l_strLoadError As String ChDrive Left(App.Path, 2) ChDir App.Path If Not UnpackResources Then Exit Sub End If If Not LoadLibraries Then Exit Sub End If If Not PerformUnzip Then Exit Sub End If DoEvents Load frmNull Err.Clear l_strFolder = Command$ If Len(GameName) > 0 Then l_strFolder = GetGameRoot() ElseIf FileExists("game.f2config") Then l_strFolder = CurDir() ElseIf FileExists("game\game.f2config") Then l_strFolder = CurDir() & "\game\" End If If (Trim(l_strFolder) = "") Then l_strFolder = App.Path Set l_bfBrowse = New cBrowseForFolder l_bfBrowse.EditBox = True l_bfBrowse.FileSystemOnly = True l_bfBrowse.InitialDir = App.Path l_bfBrowse.UseNewUI = True l_bfBrowse.Title = "Select Game" l_strFolder = l_bfBrowse.BrowseForFolder If Len(Trim(l_strFolder)) <= 0 Then End End If Err.Clear Fury2Load l_strFolder, EM_Normal, frmNull, , l_engEngine Else Err.Clear Fury2Load l_strFolder, EM_Normal, frmNull, , l_engEngine End If If (Err.Number <> 0) Or (frmNull.Loaded = False) Or (l_engEngine Is Nothing) Then l_strLoadError = Err.Description & "(" & Err.Number & ")" & vbCrLf l_strLoadError = l_strLoadError & Engine.LoadError MsgBox "Unable to load Fury�." & vbCrLf & l_strLoadError, vbCritical, "Error" Unload frmNull End End If End Sub
Friend Sub Game(Optional ByVal Name As String = "") On Error Resume Next Dim FrameStart As Double, FrameEnd As Double, Elapsed As Double Dim UpdateStart As Double, UpdateEnd As Double Dim UpdateMaxLength As Double, UpdateOverflowCount As Long Dim NextFrame As Double Dim FramesElapsed As Long, Frames As Long Dim l_lngThreadID As Long Halted = False SubthreadCount = SubthreadCount + 1 ReDim Preserve m_thrSubthreads(0 To SubthreadCount) l_lngThreadID = SubthreadCount With m_thrSubthreads(l_lngThreadID) .Name = Name .Running = True End With If m_sngLastFrameStart = 0 Then m_sngLastFrameStart = HiTimer If m_sngLastFrameEnd = 0 Then m_sngLastFrameEnd = HiTimer If m_sngLastSecond = 0 Then m_sngLastSecond = HiTimer UpdateMaxLength = 0.8 / DesiredFramerate If l_lngThreadID = 0 Then ContextLevelAdd "Game" Else ContextLevelAdd "Subthread #" & l_lngThreadID End If If Not m_booRanStartEvent Then m_booRanStartEvent = True m_objNotify.Start If Not (Debugger Is Nothing) Then Debugger.DebugGameStart ContextLevelAdd "Engine_Start" ScriptEngine.Exec "Engine_Start" ContextLevelRemove End If If Not (Debugger Is Nothing) Then Debugger.DebugSubthreadStart Do While Running If (m_booBreak = True) And (SubthreadCount > 0) Then m_booBreak = False m_booResetClock = True Exit Do End If If m_thrSubthreads(l_lngThreadID).Running = False Then m_booResetClock = True Exit Do End If If Terminating Then Exit Do m_sngLastFrameStart = FrameStart FrameStart = HiTimer m_sngFrameLength = 1# / CDbl(DesiredFramerate) NextFrame = m_sngLastFrameStart + m_sngFrameLength Elapsed = Elapsed + (FrameStart - m_sngLastFrameStart) If Elapsed < 0 Then Elapsed = 0 If BalanceFramerate Then FramesElapsed = FramesElapsed + Floor((Elapsed) / m_sngFrameLength) If m_booSubthreadStarted Then FramesElapsed = 1 End If If FramesElapsed > MaxFrameskip Then FramesElapsed = MaxFrameskip Elapsed = Elapsed - ((Floor((Elapsed) / m_sngFrameLength)) * m_sngFrameLength) If Elapsed < 0 Then Elapsed = 0 Else FramesElapsed = 1 Elapsed = 0 End If If m_booResetClock Then m_booResetClock = False m_sngLastSecond = HiTimer m_lngFPSAccumulator = 0 FramesElapsed = 1 Elapsed = 0 End If
If FramesElapsed >= 1 Then
m_booSubthreadStarted = False Do While FramesElapsed > 0 If Not (Debugger Is Nothing) Then Debugger.DebugFrameStart If Halted Then If Not (Debugger Is Nothing) Then Debugger.DebugHalted Do While Halted DoEvents Loop m_booResetClock = True If Not (Debugger Is Nothing) Then Debugger.DebugUnhalted End If FramesElapsed = FramesElapsed - 1 UpdateStart = HiTimer Update If Terminating Then Exit Do UpdateENet If Terminating Then Exit Do UpdateEnd = HiTimer If (UpdateEnd - UpdateStart) > UpdateMaxLength Then UpdateOverflowCount = UpdateOverflowCount + 1 End If UpdatePictures If Terminating Then Exit Do If Not (Debugger Is Nothing) Then Debugger.DebugFrameEnd If m_booSubthreadStarted Then Exit Do Loop
If Terminating Then Exit Do UpdateTimers If Terminating Then Exit Do Mouse.Update UpdateEvents UpdateKeyboard If Terminating Then Exit Do UpdateWindow If Terminating Then Exit Do
Redraw If Terminating Then Exit Do
FlipScreen If Terminating Then Exit Do
UpdateActionQueue If Terminating Then Exit Do
m_lngFPSAccumulator = m_lngFPSAccumulator + 1
End If
FrameEnd = HiTimer
If BalanceFramerate And (UpdateOverflowCount > DesiredFramerate) Then BalanceFramerate = False TextOut "Framerate balancing auto-disabled (game too slow)" End If
If (FrameEnd - m_sngLastSecond) >= 1# Then UpdateOverflowCount = 0 frmProfile.ProfileTextHeight = ProfileTextCurrentHeight frmProfile.Form_Resize m_sngLastSecond = FrameEnd FPS = m_lngFPSAccumulator m_lngFPSAccumulator = 0 If ShowFPS Then If Fullscreen Then SetWindowText m_objOutputPlugin.Window.hWnd, WindowCaption & " (" & FPS & " FPS)" Else m_objOutputPlugin.Window.Caption = WindowCaption & " (" & FPS & " FPS)" End If End If End If
DoEvents If Me.HarassCPU Then Else SleepEx 1, True
m_sngLastFrameEnd = FrameEnd Loop SubthreadCount = SubthreadCount - 1 ReDim Preserve m_thrSubthreads(0 To SubthreadCount) m_booBreak = False ContextLevelRemove If Not (Debugger Is Nothing) Then Debugger.DebugSubthreadEnd Err.Clear End Sub
(for the curious, when I finally stopped maintaining it there was around 120k lines of VB6 and another 15k lines of C++)
|
|
|
Logged
|
|
|
|
Massena
|
|
« Reply #55 on: January 26, 2009, 12:11:06 PM » |
|
return(0);
Does that function contain anything other that just "return x;"? I don't think it's a function, at least not one you have to define, but it does the same thing as return x.
|
|
|
Logged
|
|
|
|
Will Vale
|
|
« Reply #56 on: January 26, 2009, 12:36:54 PM » |
|
I don't think it's a function, at least not one you have to define, but it does the same thing as return x.
You're right, it's not a function, just a standard return statement. is the same as The parentheses are part of the return value expression and basically have no effect when used here since there's no ambiguity in the order of evaluation that you need to resolve. Personally I'd stay away from the usage since it's confusing.
|
|
|
Logged
|
|
|
|
Mr. Yes
|
|
« Reply #57 on: January 26, 2009, 01:06:04 PM » |
|
Plus, it's a reserved keyword - even if that odd syntax didn't exist you still wouldn't be able to make a function like that.
|
|
|
Logged
|
|
|
|
J. Kyle Pittman
|
|
« Reply #58 on: January 26, 2009, 01:25:39 PM » |
|
Even if you didn't use the reserved "return" keyword, that would only make sense if it were a macro, not a function. int MyReturn(int RetVal) { return RetVal; }
int SomeOtherFunction() { // ... MyReturn (x); // evaluates to "x" // And now SomeOtherFunction() doesn't return anything! } #define MyReturn(x) return(x)
int SomeOtherFunction() { // ... MyReturn (x); // evaluates to "return x" } But then....it's just the same as a return statement.
|
|
|
Logged
|
|
|
|
Pigbuster
|
|
« Reply #59 on: January 26, 2009, 09:36:24 PM » |
|
The parentheses are part of the return value expression and basically have no effect when used here since there's no ambiguity in the order of evaluation that you need to resolve. Personally I'd stay away from the usage since it's confusing. I suppose that's a good idea.
|
|
|
Logged
|
|
|
|
|