04 November 2011, 03:49 | #1 |
Registered User
Join Date: Sep 2007
Location: Melbourne/Australia
Posts: 4,458
|
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> 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; } 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; } } 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. |
20 August 2019, 13:45 | #2 |
Registered User
Join Date: Mar 2017
Location: Minehead / UK
Posts: 608
|
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... |
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 |
|
|