English Amiga Board


Go Back   English Amiga Board > Coders > Coders. General > Coders. Tutorials

 
 
Thread Tools
Old 04 November 2011, 03:49   #1
NovaCoder
Registered User
NovaCoder's Avatar
 
Join Date: Sep 2007
Location: Melbourne/Australia
Posts: 3,806
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 online now  
Old 20 August 2019, 13:45   #2
MartinW
Registered User

 
Join Date: Mar 2017
Location: Minehead / UK
Posts: 561
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...
MartinW is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
Source code for game in C? Leandro Jardim Coders. General 2 17 February 2013 00:27
Problem starting game via startup-sequence steveggz support.Games 3 14 June 2012 06:43
68k & 060 friendly code... korruptor Coders. Tutorials 5 05 February 2011 15:46
Assembler System Friendly code redblade Coders. General 3 29 July 2008 12:15
vsync+fullscreen+sound=crash (but only at startup?!) gary support.WinUAE 0 25 June 2004 05:17

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 03:45.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2020, vBulletin Solutions Inc.
Page generated in 0.07011 seconds with 13 queries