View Single Post
Old 04 November 2011, 03:49   #1
NovaCoder
Registered User
NovaCoder's Avatar
 
Join Date: Sep 2007
Location: Melbourne/Australia
Posts: 4,120
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;
    }
}

Last edited by NovaCoder; 09 February 2015 at 04:32.
NovaCoder is offline  
 
Page generated in 0.04873 seconds with 11 queries