locked
App resume in a ported MS-DOS app

    Question

  • Hi there

    I just ported an old, ancient DOS game to C#/Windows 8.1 store. It works pretty well. Being a very old game it contains several modal controls loops. They all look this way:

    while(!hasPressedEsc)
    {
        ProcessUserInput();
        RunTheGameForAFrame();
        WaitForVSync();
    }

    The problem is that this design doesn't work at all with app suspend/resume. The instruction pointer might be deep in some function (call stack of 10+ functions), and almost everything is stored in many, many, many global variables.

    Is there an easy way out to support app suspend/resume? Or do I have to rework the whole architecture? Serializing all global variables is certainly doable, but jumping inside an arbitrary function/call stack seems impossible.

    Cheers,
    Simon

    Saturday, July 26, 2014 4:03 PM

Answers

  • You're going to have to write your own stack implementation.  Suspend will occur asynchronously to your loop, so you'll have to find a way to store the current stack and reimplement it on resume.

    Matt Small - Microsoft Escalation Engineer - Forum Moderator
    If my reply answers your question, please mark this post as answered.

    NOTE: If I ask for code, please provide something that I can drop directly into a project and run (including XAML), or an actual application project. I'm trying to help a lot of people, so I don't have time to figure out weird snippets with undefined objects and unknown namespaces.

    • Marked as answer by deiruch Wednesday, July 30, 2014 7:19 AM
    Monday, July 28, 2014 6:19 PM
    Moderator

All replies

  • I would hove by saving the global variables you would be able to redraw the screen on app resume.  I would make sure ProcessUserInput would exit right away when the app resumes so the app can RunTheGameForAFrame so the user does not have to move before the screen draws
    Saturday, July 26, 2014 5:18 PM
  • Hi Ken

    Thanks for the reply.

    I probably haven't described the problem clearly enough. Games in those days were designed all in a similar way. The whole loop is run 60/70 times per second. Redrawing the screen also occurs at this rate - so that's no problem.

    The problem occurs when my app was tombstoned/terminated by the OS. In this case I should restore the previously saved state. Restoring global state is doable. But I don't see how I can let the execution continue at an arbitrary point without rewriting the whole game. Maybe the game was tombstoned in the middle of function A, which was called from function C, which was called from function B, which ... which was called from function X. How can I resume the execution in the middle of function A?

    Cheers,
    Simon

    Sunday, July 27, 2014 12:14 AM
  • There is no way to resume the app in the middle of a function. Typically in game framework like XNA or Mono Game you draw the whole screen in each game loop.
    Sunday, July 27, 2014 6:32 PM
  • I don't quite understand why you're talking about the drawing. Drawing is not the problem. Drawing works fine. It seems to me that my problem is still unclear.

    Do you know of code patterns that would let me resume the game at checkpoints? Something like "setjump" in C, or "goto" in Basic. For example, I have this code

    void Main()
    {
      RunMenu();
    }
    
    void RunMenu()
    {
      //setup setup
      //blah blah
    
      for(;;)
      {
        processUserInput();
        renderFrame();
        if(pressedEnter && selectedEntry==START_GAME)
          runTheGame();
        if(pressedEnter && selectedEntry==OPTIONS)
          openOptions();
        
        waitABit();
      }
    }
    
    
    void runTheGame()
    {
      //setup setup
      //blah blah
      setupLevel();
      startPlaying();
    }
    
    void startPlaying()
    {
      showLevelIntro();
      for(;;)
      {
        //FOR EXAMPLE, RETURN CONTROL HERE AFTER TOMBSTONING
      }
    }

    Now, I'd want to resume control inside the for-loop of startPlaying(). Or in the for-loop of runMenu(). Or in some dozen other places.

    Should I add if's all over the place to jump to the appropriate place? Should I replace all the method calls with my own stack implementation? What would you do?

    Simon

    Sunday, July 27, 2014 9:39 PM
  • You're going to have to write your own stack implementation.  Suspend will occur asynchronously to your loop, so you'll have to find a way to store the current stack and reimplement it on resume.

    Matt Small - Microsoft Escalation Engineer - Forum Moderator
    If my reply answers your question, please mark this post as answered.

    NOTE: If I ask for code, please provide something that I can drop directly into a project and run (including XAML), or an actual application project. I'm trying to help a lot of people, so I don't have time to figure out weird snippets with undefined objects and unknown namespaces.

    • Marked as answer by deiruch Wednesday, July 30, 2014 7:19 AM
    Monday, July 28, 2014 6:19 PM
    Moderator