English Amiga Board

English Amiga Board (https://eab.abime.net/index.php)
-   Coders. Tutorials (https://eab.abime.net/forumdisplay.php?f=73)
-   -   C/C++ WB friendly fullscreen game startup code (https://eab.abime.net/showthread.php?t=61692)

NovaCoder 04 November 2011 03:49

C/C++ WB friendly fullscreen game startup code
 
I thought I'd post the start-up code that I'm now using for my PC ports (it would have saved me a quite few hours!).

I'll also include some WB friendly double buffering as a side-dish.

I code using GCC with the OS3.9 SDK.

Includes (OS 3.9 SDK)
Code:

#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/graphics.h>

Member variables:
Code:

    /** Hardware window */
    struct Window *_hardwareWindow;
  /** Hardware screen */
  struct Screen *_hardwareScreen;
    // Hardware double buffering.
    struct ScreenBuffer *_hardwareScreenBuffer[2];
    byte _currentScreenBuffer;
    struct MsgPort *_dispPort;
    struct MsgPort *_safePort;
    bool _safeToWrite;
    bool _safeToChange;


Init stuff.
Code:

    _hardwareWindow = NULL;
    _hardwareScreenBuffer[0] = NULL;
    _hardwareScreenBuffer[1] = NULL;
    _currentScreenBuffer = 0;
    _dispPort = _safePort = NULL;
    _safeToWrite = _safeToChange = true;
    _hardwareScreen = NULL;


Open your Screen (8 bit).
Code:

struct Screen* OSystem_AmigaOS3::createHardwareScreen(uint width, uint height) {
    // Create the hardware screen.
    struct Screen* screen = NULL;
    ULONG modeId = INVALID_ID;

    modeId = BestModeID(BIDTAG_NominalWidth, width,
                        BIDTAG_NominalHeight, height,
                    BIDTAG_DesiredWidth, width,
                    BIDTAG_DesiredHeight, height,
                    BIDTAG_Depth, 8,
                    BIDTAG_MonitorID, VGA_MONITOR_ID,
                    TAG_END);
    if (modeId == INVALID_ID) {
        modeId = BestModeID(BIDTAG_NominalWidth, width,
                            BIDTAG_NominalHeight, height,
                        BIDTAG_DesiredWidth, width,
                        BIDTAG_DesiredHeight, height,
                        BIDTAG_Depth, 8,
                        BIDTAG_MonitorID, PAL_MONITOR_ID,
                            TAG_END);
 }
    if (modeId == INVALID_ID) {
        modeId = BestModeID(BIDTAG_NominalWidth, width,
                            BIDTAG_NominalHeight, height,
                        BIDTAG_DesiredWidth, width,
                        BIDTAG_DesiredHeight, height,
                        BIDTAG_Depth, 8,
                        BIDTAG_MonitorID, NTSC_MONITOR_ID,
                            TAG_END);
 }

    if(modeId == INVALID_ID) {
  error("Could not find a valid screen mode");
 }

 screen = OpenScreenTags(NULL,
                    SA_Depth, 8,
                    SA_DisplayID, modeId,
                    SA_Width, width,
      SA_Height, height,
                    SA_Type, CUSTOMSCREEN,
                    SA_Overscan, OSCAN_TEXT,
      SA_ShowTitle, FALSE,
      SA_Draggable, FALSE,
                    SA_Exclusive, TRUE,
      SA_AutoScroll, FALSE,
                    TAG_END);
    return screen;
}

Setup double buffered stuff (and C2P etc)
Code:

    _dispPort = CreateMsgPort();
    _safePort = CreateMsgPort();
 
    _hardwareScreenBuffer[0] = AllocScreenBuffer(_hardwareScreen, NULL, SB_SCREEN_BITMAP);
    _hardwareScreenBuffer[1] = AllocScreenBuffer(_hardwareScreen, NULL, 0);

    for (uint i = 0; i < 2; i++) {
        _hardwareScreenBuffer[i]->sb_DBufInfo->dbi_DispMessage.mn_ReplyPort = _dispPort;
        _hardwareScreenBuffer[i]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort = _safePort;
    }
    _safeToWrite = _safeToChange = true;
    _currentScreenBuffer = 1;



Open your Window.
Code:

struct Window* OSystem_AmigaOS3::createHardwareWindow(uint width, uint height) {
    return OpenWindowTags(NULL,
                      WA_Left, 0,
              WA_Top, 0,
              WA_Width, width,
              WA_Height, height,
              WA_Title, NULL,
              WA_CustomScreen, (ULONG)_hardwareScreen,
              WA_Backdrop, TRUE,
              WA_Borderless, TRUE,
              WA_DragBar, FALSE,
              WA_Activate, TRUE,
              WA_SmartRefresh, TRUE,
              WA_NoCareRefresh, TRUE,
              WA_ReportMouse, TRUE,
              WA_RMBTrap, TRUE,
                      WA_IDCMP, IDCMP_RAWKEY|IDCMP_MOUSEMOVE|IDCMP_MOUSEBUTTONS|IDCMP_ACTIVEWINDOW|IDCMP_INACTIVEWINDOW,
                      TAG_END);
}


Render loop:
Code:

void OSystem_AmigaOS3::updateScreenInternal(UBYTE *buf) {

        // C2P the chunky back-buffer to the screen's bitmap.
        [SNIP]
 


      // Check whether the palette was changed.
      if (paletteChanged) {
            updatePalette();
      }




        if (ChangeScreenBuffer(hardwareScreen, hardwareScreenBuffer[currentScreenBuffer])) {
          // Flip.
          currentScreenBuffer = currentScreenBuffer ^ 1;
      }
}

Always clean up on exit like a good little coder ;)
Code:

void OSystem_AmigaOS3::deInitBackend() {
 
  if (hardwareWindow) {
        debug(1, "deleting window");
        ClearPointer(hardwareWindow);
        CloseWindow(hardwareWindow);
        hardwareWindow = NULL;
    }
 
    if (hardwareScreenBuffer[0]) {
        debug(1, "deleting screen buffer 1");
        WaitBlit();
        FreeScreenBuffer(hardwareScreen, hardwareScreenBuffer[0]);
    }

    if (hardwareScreenBuffer[1]) {
        debug(1, "deleting screen buffer 2");
        WaitBlit();
        FreeScreenBuffer(hardwareScreen, hardwareScreenBuffer[1]);
    }
    if (safePort) {
        debug(1, "deleting Message Port 1");
        if (!safeToWrite) {
            while(!GetMsg(safePort)) {
                Wait(1l<<(safePort->mp_SigBit));
            }
        }
        DeleteMsgPort(safePort);
        safePort = NULL;
    }
    if (dispPort) {
        debug(1, "deleting Message Port 2");
        if (!safeToChange) {
            while(!GetMsg(dispPort)) {
                Wait(1l<<(dispPort->mp_SigBit));
            }
        }
        DeleteMsgPort(dispPort);
        dispPort = NULL;
    }

    if (hardwareScreen) {
        debug(1, "deleting screen");
        CloseScreen(hardwareScreen);
        hardwareScreen = NULL;
    }
}


MartinW 20 August 2019 13:45

Do you have an implementation that uses this anywhere online? I know it's me being dumb but I'm struggling to join up the dots as it were.

The closest I got was to remove the C++ method names turning it into C, add a Main, open some libs that the compiler was complaining about and then it builds but blows up as soon as it gets to Allocating the first screen buffer which is pretty much the fist line of code from this startup sequence so I'm clearly missing some key concepts...


All times are GMT +2. The time now is 05:08.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.

Page generated in 0.07184 seconds with 11 queries