avi writer: more fixes & cleanups

This commit is contained in:
dinkc64 2015-10-11 03:08:26 +00:00
parent 3724b3acd5
commit ba8ef0b1a6
5 changed files with 83 additions and 117 deletions

View File

@ -1,38 +1,17 @@
/**************************************************************************
*
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
* KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
* PURPOSE.
*
* Copyright (C) 1992 - 1997 Microsoft Corporation. All Rights Reserved.
*
**************************************************************************/
/****************************************************************************
*
* WRITEAVI.C
*
* Creates the file OUTPUT.AVI, an AVI file consisting of a rotating clock
* face. This program demonstrates using the functions in AVIFILE.DLL
* to make writing AVI files simple.
*
* This is a stripped-down example; a real application would have a user
* INT32erface and check for errors.
*
***************************************************************************/
/////////////////////////////////////////////////////////////////////////////
//
// This code has been modified to work with FinalBurn Alpha.
//
//---------------------------------------------------------------------------
//
// AVI Recorder for FBA version 0.5 by Gangta
// AVI Recorder for FBA version 0.7 by Gangta
// - massive re-work by dink in fall 2015 -
//
// Limitations:
//
// - Supported bitdepths are 15, 16, 24, and 32.
//
// - Avi will be recorded at original game resolution.
// - Avi will be recorded at original game resolution w/double pixels.
//
// - Video effects will not be recorded.
// (i.e. stretch, scanline, 3D effects, software effects)
@ -43,6 +22,13 @@
//
// Version History:
//
// 0.7 - completely re-worked the image-conversion process, using
// burner/sshot.cpp as an example. as a result of this:
// + source data is now supplied to the encoder at 32bpp
// + fixes some crash issues in the previous 24bpp convertor when
// the source data is 16bpp or the blitter being forced to 16bit mode
// + fixes the skew problem when lines weren't a multiple of 4
//
// 0.6 - added flipped screen support, fixed a bunch of bugs
// added to FBAlpha 2.97.37
//
@ -94,7 +80,6 @@
#define TAVI_DIRECTORY ".\\avi\\"
unsigned char *pAviBuffer = NULL; // pointer to raw pixel data
INT32 nAviStatus = 0; // 1 (recording started), 0 (recording stopped)
INT32 nAviIntAudio = 1; // 1 (interleave audio), 0 (do not interleave)
@ -118,12 +103,12 @@ static struct FBAVI {
AVICOMPRESSOPTIONS opts; // compression options
// other
UINT32 nFrameNum; // frame number for each compressed frame
UINT8 flippedmode;
UINT8 nLastDest;
INT32 nWidth;
INT32 nHeight;
UINT8 nLastDest; // number of the last pBitmapBuf# written to - for chaining effects
UINT8 *pBitmap; // pointer for buffer for bitmap
UINT8 *pBitmapBuf1; // buffer #1
UINT8 *pBitmapBuf2; // buffer #2 (flippy)
INT32 (*MakeBitmap) (); // MakeBitmapNoRotate, MakeBitmapRotateCW, MakeBitmapRotateCCW
} FBAvi;
// Opens an avi file for writing.
@ -142,23 +127,10 @@ static INT32 AviCreateFile()
// construct our filename -> "romname-mm-dd-hms.avi"
sprintf(szFilePath, "%s%s-%.2d-%.2d-%.2d%.2d%.2d.avi", TAVI_DIRECTORY, BurnDrvGetTextA(DRV_NAME), tmTime->tm_mon + 1, tmTime->tm_mday, tmTime->tm_hour, tmTime->tm_min, tmTime->tm_sec);
// temporary fix for AVIFileOpen()
//
// AVIFileOpen() doesn't truncate file size to zero on
// existing files with OR_CREATE | OF_WRITE flags ?????
{
FILE *pFile = NULL;
pFile = fopen(szFilePath, "wb");
if (pFile) {
fclose(pFile);
}
pFile = NULL;
}
hRet = AVIFileOpenA(
&FBAvi.pFile, // returned file pointer
szFilePath, // file path
OF_CREATE | OF_WRITE /*| OF_SHARE_EXCLUSIVE*/, // mode
OF_CREATE | OF_WRITE, // mode
NULL); // use handler determined from file extension
if (hRet) {
#ifdef AVI_DEBUG
@ -190,16 +162,16 @@ static INT32 AviCreateFile()
return 0;
}
// Make a 32bit Bitmap of the gamescreen and flip it depending on orientation.
static INT MakeSSBitmap()
{
INT32 w,h;
INT32 w = FBAvi.nWidth, h = FBAvi.nHeight;
UINT8 *pTemp = FBAvi.pBitmapBuf1;
UINT8* pSShot = NULL;
if (pAviBuffer == NULL) {
if (pVidImage == NULL) {
return 1; // video buffer is empty
}
BurnDrvGetVisibleSize(&w, &h);
pSShot = pVidImage;
@ -207,8 +179,6 @@ static INT MakeSSBitmap()
// Convert the image to 32-bit
if (nVidImageBPP < 4) {
//UINT8* pTemp = (UINT8*)malloc(w * h * sizeof(INT32));
if (nVidImageBPP == 2) {
for (INT32 i = 0; i < h * w; i++) {
UINT16 nColour = ((UINT16*)pSShot)[i];
@ -235,7 +205,7 @@ static INT MakeSSBitmap()
*(pTemp + i * 4 + 2) |= *(pTemp + i * 4 + 2) >> 5;
}
}
} else {
} else { // 24-bit
memset(pTemp, 0, w * h * sizeof(INT32));
for (INT32 i = 0; i < h * w; i++) {
*(pTemp + i * 4 + 0) = *(pSShot + i * 3 + 0);
@ -297,8 +267,8 @@ static INT MakeSSBitmap()
// Flips the image the way the encoder expects it to be
static INT32 MakeBitmapFlippedForEncoder()
{
INT32 nWidth = FBAvi.bih.biWidth/2;
INT32 nHeight = FBAvi.bih.biHeight/2;
INT32 nWidth = FBAvi.nWidth;
INT32 nHeight = FBAvi.nHeight;
UINT8 *pDest = (FBAvi.nLastDest == 2) ? FBAvi.pBitmapBuf1 : FBAvi.pBitmapBuf2;
UINT8 *pSrc = (FBAvi.nLastDest == 2) ? FBAvi.pBitmapBuf2 : FBAvi.pBitmapBuf1;
FBAvi.pBitmap = pDest;
@ -322,14 +292,14 @@ static INT32 MakeBitmapFlippedForEncoder()
// Doubles the pixels on an already converted buffer
static INT32 MakeBitmapDoubled()
{
INT32 nWidth = FBAvi.bih.biWidth/2;
INT32 nHeight = FBAvi.bih.biHeight/2;
INT32 nWidth = FBAvi.nWidth;
INT32 nHeight = FBAvi.nHeight;
UINT8 *pSrc = (FBAvi.nLastDest == 2) ? FBAvi.pBitmapBuf2 : FBAvi.pBitmapBuf1;
UINT8 *pDest = (FBAvi.nLastDest == 2) ? FBAvi.pBitmapBuf1 : FBAvi.pBitmapBuf2;
UINT8 *pDestL2;
FBAvi.pBitmap = pDest;
INT32 lctr = 0;
UINT8 *pSrc = (FBAvi.nLastDest == 2) ? FBAvi.pBitmapBuf2 : FBAvi.pBitmapBuf1;
for (INT32 i = 0; i < nHeight * nWidth; i++) {
pDestL2 = pDest + (nWidth * (aviBPP * 2)); // next line down
memcpy(pDest, pSrc, aviBPP);
@ -347,7 +317,6 @@ static INT32 MakeBitmapDoubled()
pSrc += aviBPP; // source a new pixel
}
FBAvi.pBitmap = (FBAvi.nLastDest == 2) ? FBAvi.pBitmapBuf1 : FBAvi.pBitmapBuf2;
FBAvi.nLastDest = (FBAvi.pBitmap == FBAvi.pBitmapBuf1) ? 1 : 2;
return 0;
@ -360,10 +329,10 @@ static void AviSetVidFormat()
memset(&FBAvi.bih,0,sizeof(BITMAPINFOHEADER));
FBAvi.bih.biSize = sizeof(BITMAPINFOHEADER);
INT32 ww,hh;
BurnDrvGetVisibleSize(&ww, &hh);
FBAvi.bih.biWidth = ww*2;
FBAvi.bih.biHeight = hh*2;
//INT32 ww,hh;
BurnDrvGetVisibleSize(&FBAvi.nWidth, &FBAvi.nHeight);
FBAvi.bih.biWidth = FBAvi.nWidth * 2;
FBAvi.bih.biHeight = FBAvi.nHeight * 2;
FBAvi.pBitmap = FBAvi.pBitmapBuf1;
@ -683,8 +652,10 @@ void AviStop()
FreeBMP();
#ifdef AVI_DEBUG
if (nAviStatus) {
bprintf(0, _T(" ** AVI recording finished.\n"));
bprintf(0, _T(" total frames recorded = %u\n"),FBAvi.nFrameNum+1);
bprintf(0, _T(" total frames recorded = %u\n"), FBAvi.nFrameNum+1);
}
#endif
nAviStatus = 0;
nAviFlags = 0;
@ -720,7 +691,7 @@ INT32 AviStart()
// set video format
AviSetVidFormat();
// allocate memory for 2x 24bpp bitmap buffers
// allocate memory for 2x 32bpp bitmap buffers
FBAvi.pBitmapBuf1 = (UINT8 *)malloc(FBAvi.bih.biSizeImage);
if (FBAvi.pBitmapBuf1 == NULL) {
return 1; // not enough memory to create allocate bitmap
@ -737,7 +708,7 @@ INT32 AviStart()
return 1;
}
// interleave audio
// interleave audio / add audio to the stream
if (nAviIntAudio) {
// set audio format
AviSetAudFormat();

View File

@ -473,6 +473,5 @@ TCHAR* FormatCommasNumber(__int64);
INT32 AviStart();
INT32 AviRecordFrame(INT32 bDraw);
void AviStop();
extern unsigned char *pAviBuffer;
extern int nAviStatus;
extern INT32 nAviStatus;
#endif

View File

@ -179,7 +179,6 @@ static int RunFrame(int bDraw, int bPause)
nDoFPS = nFramesRendered + 30;
}
}
}
#ifdef INCLUDE_AVI_RECORDING
if (nAviStatus) {
@ -188,6 +187,7 @@ static int RunFrame(int bDraw, int bPause)
}
}
#endif
}
bPrevPause = bPause;
bPrevDraw = bDraw;

View File

@ -615,6 +615,9 @@ static void OnPaint(HWND hWnd)
static void OnClose(HWND)
{
#ifdef INCLUDE_AVI_RECORDING
AviStop();
#endif
PostQuitMessage(0); // Quit the program if the window is closed
}
@ -963,8 +966,9 @@ static void OnCommand(HWND /*hDlg*/, int id, HWND /*hwndCtl*/, UINT codeNotify)
case MENU_AVISTART:
if (AviStart()) {
AviStop();
}
} else {
VidSNewShortMsg(FBALoadStringEx(hAppInst, IDS_REC_AVI, true), 0x0000FF);
}
break;
case MENU_AVISTOP:
AviStop();

View File

@ -274,9 +274,6 @@ INT32 VidExit()
if (pVidTransImage) {
free(pVidTransImage);
pVidTransImage = NULL;
#ifdef INCLUDE_AVI_RECORDING
pAviBuffer = NULL;
#endif
}
return nRet;
@ -304,10 +301,8 @@ static INT32 VidDoFrame(bool bRedraw)
bVidRecalcPalette = false;
}
pBurnDraw = pVidTransImage;
#ifdef INCLUDE_AVI_RECORDING
pAviBuffer = pVidImage;
#endif
nBurnPitch = nVidImageWidth * 2;
nRet = pVidOut[nVidActive]->Frame(bRedraw);
@ -339,9 +334,6 @@ static INT32 VidDoFrame(bool bRedraw)
} else {
pBurnDraw = pVidImage;
nBurnPitch = nVidImagePitch;
#ifdef INCLUDE_AVI_RECORDING
pAviBuffer = pBurnDraw;
#endif
nRet = pVidOut[nVidActive]->Frame(bRedraw);