View Single Post
Old 28 February 2016, 09:32   #185
NovaCoder
Registered User
NovaCoder's Avatar
 
Join Date: Sep 2007
Location: Melbourne/Australia
Posts: 3,444
A few people have been asking me to show them the ScummVM RTG source code so I'll post it here before it's lost off my HD forever

The RTG code almost identical to the AGA code (99% the same).

amigaos3-graphics-cgx.cpp

Code:



  
#include <cybergraphics.h>
#include <inline/cybergraphics.h>


struct Library *CyberGfxBase;
  
        
static UWORD emptypointer[] = {
  0x0000, 0x0000,    /* reserved, must be NULL */
  0x0000, 0x0000,     /* 1 row of image data */
  0x0000, 0x0000    /* reserved, must be NULL */
};




/** Hardware screen */
static struct Screen *_hardwareGameScreen = NULL;

/** Hardware window */
static struct Window *_hardwareGameWindow = NULL;


/** Hardware screen */
static struct Screen *_hardwareOverlayScreen = NULL;

/** Hardware window */
static struct Window *_hardwareOverlayWindow = NULL;



#define CGX_VIDEO_DEPTH 8


static const OSystem::GraphicsMode s_supportedGraphicsModes[] = {
	{"1x", "Normal", GFX_NORMAL},
	{0, 0, 0}
};



void OSystem_AmigaOS3::beginGFXTransaction() {
#ifndef NDEBUG
    debug(4, "OSystem_AmigaOS3::beginGFXTransaction()");
    
	assert(_transactionMode == kTransactionNone);    
#endif
 

	_transactionMode = kTransactionActive;

	_transactionDetails.sizeChanged = false;

    // Store the current mode in the old mode.
	_oldVideoMode = _videoMode;
}

OSystem::TransactionError OSystem_AmigaOS3::endGFXTransaction() {
#ifndef NDEBUG
    debug(4, "OSystem_AmigaOS3::endGFXTransaction()");
    
    assert(_transactionMode != kTransactionNone);
#endif
  
    
	int errors = OSystem::kTransactionSuccess;

	if (_transactionMode == kTransactionRollback) {
    	errors |= OSystem::kTransactionSizeChangeFailed;

        // Revert to the last (working) mode.
		_videoMode.screenWidth = _oldVideoMode.screenWidth;
		_videoMode.screenHeight = _oldVideoMode.screenHeight;

		// Stop an endless loop if loadGFXMode() also fails with the old mode.
		_oldVideoMode.setup = false;
    }


    if (_transactionDetails.sizeChanged) {
        unloadGFXMode();
        if(!loadGFXMode()) {
           	if (_oldVideoMode.setup) {
                _transactionMode = kTransactionRollback;
				errors |= endGFXTransaction();
			} else {
                error("Could not switch to video mode (%d x %d)", _videoMode.screenWidth, _videoMode.screenHeight);
            }
        }
        

        if (_overlayVisible) {
            ScreenToFront(_hardwareOverlayScreen);
            ActivateWindow(_hardwareOverlayWindow);
            
            // Set current cursor position.
            _mouseCursor.x = _hardwareOverlayWindow->MouseX;
            _mouseCursor.y = _hardwareOverlayWindow->MouseY;            
        } else {
            ScreenToFront(_hardwareGameScreen);
            ActivateWindow(_hardwareGameWindow);

            // Set current cursor position.
            _mouseCursor.x = _hardwareGameWindow->MouseX;
            _mouseCursor.y = _hardwareGameWindow->MouseY;        
        }
               

            
        
        if (!_overlayPalette) {
            _overlayPalette = (byte *)calloc(3 * 256, sizeof(byte));
            loadOverlayPalette();
        }
        
        setPalette((byte*)_overlayPalette, 0, 256);

        if (!_overlayColorMap) {
            _overlayColorMap = (byte*)calloc(65536, sizeof(byte));
            loadOverlayColorMap();
        }
        
        _videoMode.setup = true;
        
        _screenChangeCount++;
    }

	_transactionMode = kTransactionNone;
	
	 
    return (OSystem::TransactionError)errors;
}



void OSystem_AmigaOS3::initSize(uint w, uint h, const Graphics::PixelFormat *format) {
#ifndef NDEBUG
    debug(4, "OSystem_AmigaOS3::initSize(%d, %d)", w, h);
    
	assert(_transactionMode == kTransactionActive);
#endif



	// Avoid redundant res changes
    /*if (_videoMode.aspectRatioCorrectionRequested) {
        if (w == _videoMode.screenWidth && real2Aspect(h) == _videoMode.scaledHeight) {
    		return;
        }
    } else {*/
         if (w == _videoMode.screenWidth && h == _videoMode.screenHeight) {
    		return;
        }
    //}

	_videoMode.screenWidth = w;
	_videoMode.screenHeight = h;

	_transactionDetails.sizeChanged = true;
}

bool OSystem_AmigaOS3::loadGFXMode() {    
#ifndef NDEBUG
    debug(4, "OSystem_AmigaOS3::loadGFXMode()");
    
    debug(5, "New video mode requested - width = %d, height = %d", _videoMode.screenWidth, _videoMode.screenHeight);
#endif    



    // Hack - should come from tooltypes 
    _videoMode.overlayWidth = _overlayWidth;
    _videoMode.overlayHeight = _overlayHeight;

    // Overlay cannot be smaller than the game screen.
    /*if ((_videoMode.overlayWidth < _videoMode.screenWidth) || (_videoMode.overlayHeight < _videoMode.screenHeight)) {
        _videoMode.overlayWidth = _videoMode.screenWidth;
        _videoMode.overlayHeight = _videoMode.screenHeight;        
    }*/

    

	
    // Create the hardware screen.
    _hardwareOverlayScreen = createHardwareScreen(_videoMode.overlayWidth, _videoMode.overlayHeight);
    if (!_hardwareOverlayScreen) {
		return false;
    }

    // Create the hardware window.
    _hardwareOverlayWindow = createHardwareWindow(_videoMode.overlayWidth, _videoMode.overlayHeight, _hardwareOverlayScreen);
    if (!_hardwareOverlayWindow) {
		return false;
    }

    SetPointer(_hardwareOverlayWindow, emptypointer, 1, 16, 0, 0); 
    
        
	
    // Create the hardware screen.
    _hardwareGameScreen = createHardwareScreen(_videoMode.screenWidth, (_videoMode.screenHeight < 240) ? 240: _videoMode.screenHeight);
    if (!_hardwareGameScreen) {
		return false;
    }
 
    // Create the hardware window.
    _hardwareGameWindow = createHardwareWindow(_videoMode.screenWidth, (_videoMode.screenHeight < 240) ? 240: _videoMode.screenHeight, _hardwareGameScreen);
    if (!_hardwareGameWindow) {
		return false;
    }
    
    SetPointer(_hardwareGameWindow, emptypointer, 1, 16, 0, 0);    
    
    
    
    // Create the surface that contains the 8 bit game data
    _screen.create(_videoMode.screenWidth, _videoMode.screenHeight, Graphics::PixelFormat::createFormatCLUT8());    

    // Create the screen used by the scaler/shaker.
    _tmpscreen.create(_videoMode.screenWidth, _videoMode.screenHeight, Graphics::PixelFormat::createFormatCLUT8());
    
    
    
    // Create the 8bit overlay surface
    _overlayscreen8.create(_videoMode.overlayWidth, _videoMode.overlayHeight, Graphics::PixelFormat::createFormatCLUT8());

	// Create the 16bit overlay surface
    _overlayscreen16.create(_videoMode.overlayWidth, _videoMode.overlayHeight, _overlayFormat);


    return true;
}

struct Screen* OSystem_AmigaOS3::createHardwareScreen(uint width, uint height) {

    // Create the hardware screen.
    struct Screen* screen = NULL;
    ULONG modeId = INVALID_ID;
    
	modeId = BestCModeIDTags(
        		CYBRBIDTG_Depth, CGX_VIDEO_DEPTH,
        		CYBRBIDTG_NominalWidth, width,
        		CYBRBIDTG_NominalHeight, height,
        		TAG_DONE);   


	// Verify the mode choosen.
	if (modeId != INVALID_ID) {
    	if (GetCyberIDAttr(CYBRIDATTR_DEPTH, modeId) != CGX_VIDEO_DEPTH) {
    		modeId = INVALID_ID;
    	}
    
    	if (GetCyberIDAttr(CYBRIDATTR_WIDTH, modeId) != width) {
    	   modeId = INVALID_ID;
    	}
    
    	if (GetCyberIDAttr(CYBRIDATTR_HEIGHT, modeId) != height) {
    	   modeId = INVALID_ID;
    	}
	}

	if (modeId == INVALID_ID) {
		warning("Couldn't find a Screen Mode for requested mode");
    }
    

    if (modeId != INVALID_ID) {
    	screen = OpenScreenTags(NULL,
                         SA_Depth, CGX_VIDEO_DEPTH,
                         SA_DisplayID, modeId,
                         SA_Width, width,
    					 SA_Height, height,
						 SA_Type, CUSTOMSCREEN,
                         SA_Quiet, TRUE,
    					 SA_ShowTitle, FALSE,
    					 SA_Draggable, FALSE,
                         SA_Exclusive, TRUE,
    					 SA_AutoScroll, FALSE,
						 TAG_END);
    }

    return screen;
}

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

    
void OSystem_AmigaOS3::unloadGFXMode() {

	_screen.free();
	_tmpscreen.free();
	
	_overlayscreen8.free();
	_overlayscreen16.free();
	
	
	
    if (_hardwareGameWindow) {
        ClearPointer(_hardwareGameWindow);
        CloseWindow(_hardwareGameWindow);
        _hardwareGameWindow = NULL;
    }

    if (_hardwareGameScreen) {
        CloseScreen(_hardwareGameScreen);
        _hardwareGameScreen = NULL;
    }
        
        
    if (_hardwareOverlayWindow) {
        ClearPointer(_hardwareOverlayWindow);
        CloseWindow(_hardwareOverlayWindow);
        _hardwareOverlayWindow = NULL;
    }

    if (_hardwareOverlayScreen) {
        CloseScreen(_hardwareOverlayScreen);
        _hardwareOverlayScreen = NULL;
    }   
}


void OSystem_AmigaOS3::setPalette(const byte *colors, uint start, uint num) {
#ifndef NDEBUG
	debug(4, "OSystem_AmigaOS3:setPalette()");

    debug(5, "setPalette() - start = %d", start);
	debug(5, "setPalette() - num = %d", num);

    assert(colors);
#endif


	byte *dst = (byte*)(_currentPalette + (3 * start));
    CopyMem((byte*)colors, dst, (num * 3));

	if (start < _paletteDirtyStart) {
		_paletteDirtyStart = start;
    }

    if (start + num > _paletteDirtyEnd) {
		_paletteDirtyEnd = start + num;
    }
}

void OSystem_AmigaOS3::grabPalette(byte *colors, uint start, uint num) {
#ifndef NDEBUG
	assert(colors);
#endif

    CopyMem(_currentPalette + (3 * start), colors, 3 * num);
}


void OSystem_AmigaOS3::updatePalette() {
#ifndef NDEBUG
    debug(4, "updatePalette()");

    debug(5, "updatePalette() - _paletteDirtyStart = %d", _paletteDirtyStart);
	debug(5, "updatePalette() - _paletteDirtyEnd = %d", _paletteDirtyEnd);
#endif

    uint j = 1;
    byte *color = (byte*)(_currentPalette + 3 * _paletteDirtyStart);

    for(uint i = _paletteDirtyStart; i < _paletteDirtyEnd; i++) {

        _agaPalette[j] = color[0] << 24;
    	_agaPalette[j+1] = color[1] << 24;
    	_agaPalette[j+2] = color[2] << 24;

    	j += 3;
    	color += 3;
    }

	uint numberOfEntries = (_paletteDirtyEnd - _paletteDirtyStart);

    _agaPalette[0] = (numberOfEntries << 16) + _paletteDirtyStart;

    // Terminator: NEEDED
    _agaPalette[((numberOfEntries * 3) + 1)] = 0x00000000;

    if (_overlayVisible) {
	   LoadRGB32(&_hardwareOverlayScreen->ViewPort, _agaPalette);
    } else {
        LoadRGB32(&_hardwareGameScreen->ViewPort, _agaPalette);        
    }

    // Reset.
    _paletteDirtyStart = 256;
    _paletteDirtyEnd = 0;
}




void OSystem_AmigaOS3::copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) {
#ifndef NDEBUG
    debug(4, "copyRectToScreen()");
    debug(5, "copyRectToScreen() - pitch = %d", pitch);
    debug(5, "copyRectToScreen() - x = %d", x);
    debug(5, "copyRectToScreen() - y = %d", y);
    debug(5, "copyRectToScreen() - w = %d", w);
    debug(5, "copyRectToScreen() - h = %d", h);

    assert(_transactionMode == kTransactionNone);
	assert(buf);
	
    	
	assert(x >= 0 && x < _videoMode.screenWidth);
	assert(y >= 0 && y < _videoMode.screenHeight);
	assert(h > 0 && y + h <= _videoMode.screenHeight);
	assert(w > 0 && x + w <= _videoMode.screenWidth);
#endif    
    

	byte *dst = (byte*)_screen.getBasePtr(x, y);

    if (_videoMode.screenWidth == pitch && pitch == w) {
        CopyMemQuick((byte*)buf, dst, w * h);
	} else {
		const byte *src = (const byte *)buf;
		do {
			CopyMem((void *)src, dst, w);
			src += pitch;
			dst += _videoMode.screenWidth;
		} while (--h);
	}      	
}





void OSystem_AmigaOS3::fillScreen(uint32 col) {
    if (_screen.pixels) {
        memset(_screen.pixels, (int)col, (_videoMode.screenWidth * _videoMode.screenHeight));
    }
}




void OSystem_AmigaOS3::updateScreen() {
#ifndef NDEBUG
    debug(9, "OSystem_AmigaOS3::updateScreen()");
#endif
        
    static UBYTE* src;
    
    
    if (_mouseCursor.visible) {
        drawMouse();
    }
    
    if (_overlayVisible) {
        UBYTE *base_address;
        APTR video_bitmap_handle = LockBitMapTags(_hardwareOverlayScreen->ViewPort.RasInfo->BitMap,
        									 LBMI_BASEADDRESS, (ULONG)&base_address,
        									 TAG_DONE);										 
        if (video_bitmap_handle) {
            CopyMemQuick((UBYTE*)_overlayscreen8.pixels, base_address, (_videoMode.overlayWidth * _videoMode.overlayHeight));
        	UnLockBitMap (video_bitmap_handle);
        	video_bitmap_handle = NULL;
        }      
    } else {
        if (_currentShakePos != _newShakePos) {
            // Set the 'dirty area' to black.
            memset(_tmpscreen.getBasePtr(0, (_videoMode.screenHeight - _newShakePos)), 0, (_videoMode.screenWidth * _newShakePos)); 
            
            src = (UBYTE*)_screen.getBasePtr(0, _newShakePos);
            byte *dst = (byte*)_tmpscreen.getBasePtr(0, 0);
            
            CopyMemQuick(src, dst, (_videoMode.screenWidth * (_videoMode.screenHeight - _newShakePos)));
            
            // Reset.
	        _currentShakePos = _newShakePos;
	        
	        src = (UBYTE*)_tmpscreen.pixels;
        } else {
            src = (UBYTE*)_screen.pixels;
        }
        

        UBYTE *base_address;
        APTR video_bitmap_handle = LockBitMapTags(_hardwareGameScreen->ViewPort.RasInfo->BitMap,
        									 LBMI_BASEADDRESS, (ULONG)&base_address,
        									 TAG_DONE);
        if (video_bitmap_handle) {
            CopyMemQuick(src, base_address, (_videoMode.screenWidth * _videoMode.screenHeight));
        	UnLockBitMap (video_bitmap_handle);
        	video_bitmap_handle = NULL;
        }            
    }
    


    // Check whether the palette was changed.
	if (_paletteDirtyEnd != 0) {
        updatePalette();
	}	
    
    
    if (_mouseCursor.visible) {
        undrawMouse();
    }	
}
 


void OSystem_AmigaOS3::setShakePos(int shakeOffset) {
#ifndef NDEBUG
	assert (_transactionMode == kTransactionNone);
#endif

	_newShakePos = shakeOffset;
}













#pragma mark -
#pragma mark --- Overlays ---
#pragma mark -

void OSystem_AmigaOS3::loadOverlayPalette() {
 
	// Load overlay palette file.
   	FILE *paletteFile;
    
    paletteFile = fopen("overlay.pal", "r");
    if (paletteFile == NULL) {
        error("Could not load the palette file");
    } else {
        // Skip forward 3 rows.
        char temp[100];
        fgets(temp, 100, paletteFile);
        fgets(temp, 100, paletteFile);
        fgets(temp, 100, paletteFile);

        // Read the palette data.
        int red, green, blue;        
        
        byte *color = _overlayPalette;
        
        while (fscanf(paletteFile, "%d %d %d", &red, &green, &blue) != EOF) {
           color[0] = red;
    	   color[1] = green;
    	   color[2] = blue;

    	   color += 3;
        }
        
        fclose(paletteFile);
    }
}

void OSystem_AmigaOS3::loadOverlayColorMap() {
#ifndef NDEBUG
    debug(4, "generateOverlayColorMap()");
#endif

    int color8;
   
    // Load overlay map file.
   	FILE *mapFile;

    mapFile = fopen("overaly.map", "r");
    if (mapFile == NULL) {
        error("Could not load the overaly map file");
    } 
    
    
    int i = 0;
    
    while (fscanf(mapFile, "%d", &color8) != EOF) {
        _overlayColorMap[i] = color8; 
        i++;
    }
    
    fclose(mapFile);
}

void OSystem_AmigaOS3::showOverlay() {
#ifndef NDEBUG
	assert (_transactionMode == kTransactionNone);
#endif

	if (_overlayVisible) {
		return;
    }


    ScreenToFront(_hardwareOverlayScreen);
    ActivateWindow(_hardwareOverlayWindow);


	_overlayVisible = true;
}

void OSystem_AmigaOS3::hideOverlay() {
#ifndef NDEBUG
	assert (_transactionMode == kTransactionNone);
#endif
    APTR video_bitmap_handle;
    UBYTE *base_address;
    
	if (!_overlayVisible) {
		return;
    }


    clearOverlay();


    video_bitmap_handle = LockBitMapTags(_hardwareOverlayScreen->ViewPort.RasInfo->BitMap,
    									 LBMI_BASEADDRESS, (ULONG)&base_address,
    									 TAG_DONE);
    if (video_bitmap_handle) {
        CopyMemQuick((UBYTE*)_overlayscreen8.pixels, base_address, (_videoMode.overlayWidth * _videoMode.overlayHeight));
    	UnLockBitMap (video_bitmap_handle);
    	video_bitmap_handle = NULL;
    }
    
    ScreenToFront(_hardwareGameScreen);
    ActivateWindow(_hardwareGameWindow);    

	_overlayVisible = false;
}

void OSystem_AmigaOS3::clearOverlay() {

	if (!_overlayVisible) {
		return;
    }

    // Set the background to black.
    byte *src = (byte*)_overlayscreen8.pixels;
    memset(src, 0, (_videoMode.overlayWidth * _videoMode.overlayHeight));
}

void OSystem_AmigaOS3::grabOverlay(void *buf, int pitch) {
#ifndef NDEBUG
	assert (_transactionMode == kTransactionNone);
#endif

    // Grab the overlay.
    memcpy(buf, _overlayscreen16.pixels, (_videoMode.overlayWidth * _videoMode.overlayHeight) * _overlayscreen16.format.bytesPerPixel);  
}

void OSystem_AmigaOS3::copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) {
#ifndef NDEBUG
    debug(4, "copyRectToOverlay()");
    
   	assert (_transactionMode == kTransactionNone);
#endif

	// Clip the coordinates
    if (x < 0) {
		return;
	}

	if (y < 0) {
		return;
	}

	if (w > _videoMode.overlayWidth - x) {
		w = _videoMode.overlayWidth - x;
	}

	if (h > _videoMode.overlayHeight - y) {
		h = _videoMode.overlayHeight - y;
	}

	if (w <= 0 || h <= 0) {
		return;
    }


    const OverlayColor *src = (const OverlayColor *)buf;
    byte *dst = (byte*)_overlayscreen8.getBasePtr(x, y);

    OverlayColor color16;
    byte color8;

    for(uint r = 0; r < h; r++) {
        for(uint c = 0; c < w; c++) {
            color16 = *src;

            color8 = _overlayColorMap[color16];

            *dst = color8;

            // Add a column.
            src++;
            dst++;
        }

        // add a row.
        dst += (_videoMode.overlayWidth - w);
        src += (_videoMode.overlayWidth - w);
    } 
}

struct Window* OSystem_AmigaOS3::getHardwareWindow() {
    if (_overlayVisible) {
        return _hardwareOverlayWindow;
    }

    return _hardwareGameWindow;
}


Attached Files
File Type: c amigaos3-graphics-cgx.c (25.4 KB, 43 views)

Last edited by NovaCoder; 08 June 2016 at 14:10.
NovaCoder is offline  
 
Page generated in 0.08852 seconds with 10 queries