Porting my game 7 Keys Saga to Haiku

I’ve created a game called 7 Keys Saga that is written in C and uses SDL2. I read the wiki page for SDL2 and didn’t remember the connection to BeOS. I was a user back in the days when you could install BeOS alongside Windows 98 and wanted to see if I could port the game to Haiku. I’ve got it working!

If you’d like to try it you can download the Haiku package. It is a 2D action RPG that kind of mixes Zelda: Link to the Past and Minecraft. The graphics are mostly generated through rectangle primitives, which gives the game a unique pixel art style.

The game is also on Steam for Windows and Linux.

I do need to find out how to get the fullscreen toggle working on Haiku. It starts in fullscreen mode, but F11 is not toggling to a windowed mode like on Windows and Linux.

12 Likes

Hi, and welcome! Glad to see developers porting their games in Haiku.

I usually don’t rely on window manager’s fullscreen mode, but use my graphics API functions to do the task. For SDL2, the simplest case is to just use SDL_SetWindowFullscreen(), so a simple toggle fullscreen function would be something like

void ToggleFullScreen(SDL_Window * win) {
  if ((SDL_GetWindowFlags(win) & SDL_WINDOW_FULLSCREEN) == 0)
    SDL_SetWindowFullscreen(win, SDL_WINDOW_FULLSCREEN);
  else SDL_SetWindowFullscreen(win, 0);
}

In a “real life” application, you will probably need error checking and other functions as well, such as SDL_SetWindowDisplayMode().

Edit: The above can be reduced to a one-liner using C’s ternary conditional ?, but I leave it as a function because you will probably need to add stuff there, to make it more robust.

Similarly, I would use GLFW’s fullscreen management in windows with OpenGL contexts.

1 Like

Thanks for your reply! My fullscreen toggle could definitely be more robust.

Here’s the section of the code where I am toggling fullscreen. I wasn’t using the SDL_SetWindowDisplayMode(), which I’ll look into.

  case SDLK_F11: {
       Uint32 flags = SDL_GetWindowFlags(state->window);
       SDL_SetWindowFullscreen(
           state->window,
           (flags & SDL_WINDOW_FULLSCREEN_DESKTOP) ? 0
                                                    : SDL_WINDOW_FULLSCREEN_DESKTOP);
       break;
     }

Do you have any ideas about why this would be working in Windows and Linux, but not Haiku?

Your code for toggling fullscreen is essentially identical to mine. In fact, you use the ternary operator ? instead of an if statement, something I mentioned before as an alternate way. And your code does work on Haiku. It worked as expected on my bare-metal installation, both with SDL_WINDOW_FULLSCREEN and SDL_WINDOW_FULLSCREEN_DESKTOP flags used. So the problem has to do with your particular installation.

My guess is SDL2 doesn’t toggle fullscreen because your GPU doesn’t cooperate well with SDL2. Your card probably ignores the code behind SDL_SetWindowFullscreen(). Are you using a VM? If so, try installing Haiku on a USB stick, boot from it, and see if the problem persists. That way Haiku will use your GPU instead of an emulated VM GPU, which causes issues to me even on other operating systems. Not to mention it is a better way to use Haiku anyway.
It’s pretty easy to use your VM installation to install on a USB stick without even needing to re-install your game, or whatever else you have installed.

1 Like

I highly doubt SDL2 on Haiku uses gpu fullscreen mode. We don’t even use that for our own applications. (It’s just a big window)

EDIT: I don’t actually need to guess. Here is the SDL3 code:

As you can see it moves the window and disables borders and or resizeable mode. I haven’t checked the older sdl2 code, but i reckon it works the same…

EDIT2:

Try debugging if the SDLK_F11 path is even hit in Haiku. Those are special keys in Haiku and not send as normal keypresses, but as function keys. It’s possible that codepath may be broken in the SDL port.

Consider also that the normal fullscreen shortcut on haiku is cmd(alt)+ Enter :slight_smile:

2 Likes

As a small feedback, It would be nice to not shove all stuff into Apps/.

If you want to make it a little bit more native you can use the finddir api, and put the stuff into data/7keys/ in the package, checking first in B_SYSTEM_DATA_DIRECTORY and then B_USER_DATA_DIRECTORY, of course that is just to get the A+ :wink:

It’s already very nice to see game devs with support for Haiku.

7keys

3 Likes

My guess is SDL2 doesn’t toggle fullscreen because your GPU doesn’t > cooperate well with SDL2. Your card probably ignores the code behind SDL_SetWindowFullscreen() . Are you using a VM? If so, try installing Haiku on a USB stick, boot from it, and see if the problem persists.

I’m running it on an ancient Thinkpad X220.

Try debugging if the SDLK_F11 path is even hit in Haiku. Those are special keys in Haiku and not send as normal keypresses, but as function keys. It’s possible that codepath may be broken in the SDL port.

Consider also that the normal fullscreen shortcut on haiku is cmd(alt)+ Enter

I’ll try this – the save button is F5, which is working. I’ll have to add Alt+S.

If you want to make it a little bit more native you can use the finddir api, and put the stuff into data/7keys/ in the package, checking first in B_SYSTEM_DATA_DIRECTORY and then B_USER_DATA_DIRECTORY, of course that is just to get the A+

Now that I’ve seen that icon I’m inspired to make it more Haiku native!

I thought of that too, but I didn’t mention it because I tried it, and SDLK_F11 is perfectly recognized. Why it works on my Haiku bare-metal installation but doesn’t work for @politebot, I don’t know. For clarity, the code for the main loop I used is as follows

  while (running) {
    SDL_WaitEvent(&event);
    switch (event.type) {
    case SDL_KEYUP:
      switch (event.key.keysym.sym) {
      case SDLK_F11: ToggleFullScreen(win); break;
      case SDLK_ESCAPE: running=SDL_FALSE; break;
      }
      break;
    case SDL_QUIT: running=SDL_FALSE;
    }
  }

where ToggleFullScreen() is as @politebot’s code above, and running is just a SDL_bool. It works as expected: F11 toggles fullscreen, Esc quits the main loop.

In general, I never had issues with SDL2 on Haiku. In fact, it seems more robust than other ported libraries. Even my own Fortran bindings for SDL2 work great on Haiku (despite the fact this adds another layer of “complexity”), to the point I don’t bother using C/C++ anymore. I didn’t try SDL3 yet, so I can’t tell.

I think not even that is needed. I just realized that, while running the program on Emacs, the command output makes it clear “full screen” is actually a BRect. In my case, once I hit F11 I get this:

screen frame: BRect(l:0.0, t:0.0, r:1365.0, b:767.0)

F11 was being recognized, but wasn’t toggling. I added

		        SDL_SetWindowBordered(state->window, SDL_TRUE);

After adding that it is working on my system.

		case SDLK_F11: {
		    Uint32 flags = SDL_GetWindowFlags(state->window);
		    if (flags & SDL_WINDOW_FULLSCREEN_DESKTOP) {
		        SDL_SetWindowFullscreen(state->window, 0);
		        SDL_SetWindowSize(state->window, SCREEN_WIDTH, SCREEN_HEIGHT);
		        SDL_SetWindowPosition(state->window, 
		                             SDL_WINDOWPOS_CENTERED, 
		                             SDL_WINDOWPOS_CENTERED);
		        SDL_SetWindowBordered(state->window, SDL_TRUE);
		    } else {
		        SDL_SetWindowFullscreen(state->window, SDL_WINDOW_FULLSCREEN_DESKTOP);
		    }
		    break;
		}

2 Likes

I think having application data contained in a subdir of apps is fine if nothing else is expected to use that data, TBH.

2 Likes

If you don’t do this you can use Tracker in icon mode to launch applications…

I wasn’t handling the assets very well on other systems either so I went back, made them a proper sprite-sheet, and embedded that in the executable.

7keys-1.10-1_x86_64.hpkg

3 Likes