From b0b53409eecb696fb13f411ffde72e8f576feb09 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 9 Apr 2022 21:35:39 +0200 Subject: [PATCH] Cleanups --- Core/VideoRenderer.cpp | 34 +--- Libretro/Makefile.common | 3 - Utilities/AviRecorder.cpp | 108 ----------- Utilities/AviRecorder.h | 47 ----- Utilities/AviWriter.cpp | 273 -------------------------- Utilities/AviWriter.h | 57 ------ Utilities/ZmbvCodec.cpp | 398 -------------------------------------- Utilities/ZmbvCodec.h | 115 ----------- 8 files changed, 2 insertions(+), 1033 deletions(-) delete mode 100644 Utilities/AviRecorder.cpp delete mode 100644 Utilities/AviRecorder.h delete mode 100644 Utilities/AviWriter.cpp delete mode 100644 Utilities/AviWriter.h delete mode 100644 Utilities/ZmbvCodec.cpp delete mode 100644 Utilities/ZmbvCodec.h diff --git a/Core/VideoRenderer.cpp b/Core/VideoRenderer.cpp index 3f11646..2c43e5c 100644 --- a/Core/VideoRenderer.cpp +++ b/Core/VideoRenderer.cpp @@ -5,9 +5,6 @@ #include "Console.h" #include "EmuSettings.h" #include "MessageManager.h" -#include "../Utilities/IVideoRecorder.h" -#include "../Utilities/AviRecorder.h" -#include "../Utilities/GifRecorder.h" VideoRenderer::VideoRenderer(shared_ptr console) { @@ -62,11 +59,6 @@ void VideoRenderer::RenderThread() void VideoRenderer::UpdateFrame(void* frameBuffer, uint32_t width, uint32_t height) { - shared_ptr recorder = _recorder; - if(recorder) { - recorder->AddFrame(frameBuffer, width, height, _console->GetFps()); - } - if(_renderer) { _renderer->UpdateFrame(frameBuffer, width, height); _waitForRender.Signal(); @@ -89,39 +81,17 @@ void VideoRenderer::UnregisterRenderingDevice(IRenderingDevice *renderer) void VideoRenderer::StartRecording(string filename, VideoCodec codec, uint32_t compressionLevel) { - FrameInfo frameInfo = _console->GetVideoDecoder()->GetFrameInfo(); - - shared_ptr recorder; - if(codec == VideoCodec::GIF) { - recorder.reset(new GifRecorder()); - } else { - recorder.reset(new AviRecorder(codec, compressionLevel)); - } - - if(recorder->StartRecording(filename, frameInfo.Width, frameInfo.Height, 4, _console->GetSettings()->GetAudioConfig().SampleRate, _console->GetFps())) { - _recorder = recorder; - MessageManager::DisplayMessage("VideoRecorder", "VideoRecorderStarted", filename); - } } void VideoRenderer::AddRecordingSound(int16_t* soundBuffer, uint32_t sampleCount, uint32_t sampleRate) { - shared_ptr recorder = _recorder; - if(recorder) { - recorder->AddSound(soundBuffer, sampleCount, sampleRate); - } } void VideoRenderer::StopRecording() { - shared_ptr recorder = _recorder; - if(recorder) { - MessageManager::DisplayMessage("VideoRecorder", "VideoRecorderStopped", recorder->GetOutputFile()); - } - _recorder.reset(); } bool VideoRenderer::IsRecording() { - return _recorder != nullptr && _recorder->IsRecording(); -} \ No newline at end of file + return false; +} diff --git a/Libretro/Makefile.common b/Libretro/Makefile.common index ea6a28f..d5fd116 100644 --- a/Libretro/Makefile.common +++ b/Libretro/Makefile.common @@ -131,8 +131,6 @@ SOURCES_CXX := $(LIBRETRO_DIR)/libretro.cpp \ $(CORE_DIR)/WaveRecorder.cpp \ $(UTIL_DIR)/ArchiveReader.cpp \ $(UTIL_DIR)/AutoResetEvent.cpp \ - $(UTIL_DIR)/AviRecorder.cpp \ - $(UTIL_DIR)/AviWriter.cpp \ $(UTIL_DIR)/blip_buf.cpp \ $(UTIL_DIR)/BpsPatcher.cpp \ $(UTIL_DIR)/CamstudioCodec.cpp \ @@ -160,7 +158,6 @@ SOURCES_CXX := $(LIBRETRO_DIR)/libretro.cpp \ $(UTIL_DIR)/VirtualFile.cpp \ $(UTIL_DIR)/ZipReader.cpp \ $(UTIL_DIR)/ZipWriter.cpp \ - $(UTIL_DIR)/ZmbvCodec.cpp \ $(UTIL_DIR)/HQX/hq2x.cpp \ $(UTIL_DIR)/HQX/hq3x.cpp \ $(UTIL_DIR)/HQX/hq4x.cpp \ diff --git a/Utilities/AviRecorder.cpp b/Utilities/AviRecorder.cpp deleted file mode 100644 index ca0532f..0000000 --- a/Utilities/AviRecorder.cpp +++ /dev/null @@ -1,108 +0,0 @@ -#include "stdafx.h" -#include "AviRecorder.h" - -AviRecorder::AviRecorder(VideoCodec codec, uint32_t compressionLevel) -{ - _recording = false; - _stopFlag = false; - _frameBuffer = nullptr; - _frameBufferLength = 0; - _sampleRate = 0; - _codec = codec; - _compressionLevel = compressionLevel; -} - -AviRecorder::~AviRecorder() -{ - if(_recording) { - StopRecording(); - } - - if(_frameBuffer) { - delete[] _frameBuffer; - _frameBuffer = nullptr; - } -} - -bool AviRecorder::StartRecording(string filename, uint32_t width, uint32_t height, uint32_t bpp, uint32_t audioSampleRate, double fps) -{ - if(!_recording) { - _outputFile = filename; - _sampleRate = audioSampleRate; - _width = width; - _height = height; - _fps = fps; - _frameBufferLength = height * width * bpp; - _frameBuffer = new uint8_t[_frameBufferLength]; - - _aviWriter.reset(new AviWriter()); - if(!_aviWriter->StartWrite(filename, _codec, width, height, bpp, (uint32_t)(_fps * 1000000), audioSampleRate, _compressionLevel)) { - _aviWriter.reset(); - return false; - } - - _aviWriterThread = std::thread([=]() { - while(!_stopFlag) { - _waitFrame.Wait(); - if(_stopFlag) { - break; - } - - auto lock = _lock.AcquireSafe(); - _aviWriter->AddFrame(_frameBuffer); - } - }); - - _recording = true; - } - return true; -} - -void AviRecorder::StopRecording() -{ - if(_recording) { - _recording = false; - - _stopFlag = true; - _waitFrame.Signal(); - _aviWriterThread.join(); - - _aviWriter->EndWrite(); - _aviWriter.reset(); - } -} - -void AviRecorder::AddFrame(void* frameBuffer, uint32_t width, uint32_t height, double fps) -{ - if(_recording) { - if(_width != width || _height != height || _fps != fps) { - StopRecording(); - } else { - auto lock = _lock.AcquireSafe(); - memcpy(_frameBuffer, frameBuffer, _frameBufferLength); - _waitFrame.Signal(); - } - } -} - -void AviRecorder::AddSound(int16_t* soundBuffer, uint32_t sampleCount, uint32_t sampleRate) -{ - if(_recording) { - if(_sampleRate != sampleRate) { - auto lock = _lock.AcquireSafe(); - StopRecording(); - } else { - _aviWriter->AddSound(soundBuffer, sampleCount); - } - } -} - -bool AviRecorder::IsRecording() -{ - return _recording; -} - -string AviRecorder::GetOutputFile() -{ - return _outputFile; -} \ No newline at end of file diff --git a/Utilities/AviRecorder.h b/Utilities/AviRecorder.h deleted file mode 100644 index f79ecd4..0000000 --- a/Utilities/AviRecorder.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once -#include "stdafx.h" -#include -#include "AutoResetEvent.h" -#include "AviWriter.h" -#include "SimpleLock.h" -#include "IVideoRecorder.h" - -class Console; - -class AviRecorder : public IVideoRecorder -{ -private: - std::thread _aviWriterThread; - - unique_ptr _aviWriter; - - string _outputFile; - SimpleLock _lock; - AutoResetEvent _waitFrame; - - atomic _stopFlag; - bool _recording; - uint8_t* _frameBuffer; - uint32_t _frameBufferLength; - uint32_t _sampleRate; - - double _fps; - uint32_t _width; - uint32_t _height; - - VideoCodec _codec; - uint32_t _compressionLevel; - -public: - AviRecorder(VideoCodec codec, uint32_t compressionLevel); - virtual ~AviRecorder(); - - bool StartRecording(string filename, uint32_t width, uint32_t height, uint32_t bpp, uint32_t audioSampleRate, double fps) override; - void StopRecording() override; - - void AddFrame(void* frameBuffer, uint32_t width, uint32_t height, double fps) override; - void AddSound(int16_t* soundBuffer, uint32_t sampleCount, uint32_t sampleRate) override; - - bool IsRecording() override; - string GetOutputFile() override; -}; \ No newline at end of file diff --git a/Utilities/AviWriter.cpp b/Utilities/AviWriter.cpp deleted file mode 100644 index fdd63fc..0000000 --- a/Utilities/AviWriter.cpp +++ /dev/null @@ -1,273 +0,0 @@ -// This file is a part of Mesen -// It is a heavily modified version of the hardware.h/cpp file found in DOSBox's code. - -/* -* Copyright (C) 2002-2011 The DOSBox Team -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "stdafx.h" -#include -#include -#include "AviWriter.h" -#include "BaseCodec.h" -#include "RawCodec.h" -#include "ZmbvCodec.h" -#include "CamstudioCodec.h" - -void AviWriter::WriteAviChunk(const char *tag, uint32_t size, void *data, uint32_t flags) -{ - uint8_t chunk[8] = { (uint8_t)tag[0], (uint8_t)tag[1], (uint8_t)tag[2], (uint8_t)tag[3] }; - host_writed(&chunk[4], size); - _file.write((char*)chunk, 8); - - uint32_t writesize = (size + 1)&~1; - _file.write((char*)data, writesize); - - uint32_t pos = _written + 4; - _written += writesize + 8; - - _aviIndex.push_back(tag[0]); - _aviIndex.push_back(tag[1]); - _aviIndex.push_back(tag[2]); - _aviIndex.push_back(tag[3]); - _aviIndex.insert(_aviIndex.end(), 12, 0); - host_writed(_aviIndex.data() + _aviIndex.size() - 12, flags); - host_writed(_aviIndex.data() + _aviIndex.size() - 8, pos); - host_writed(_aviIndex.data() + _aviIndex.size() - 4, size); -} - -void AviWriter::host_writew(uint8_t* buffer, uint16_t value) -{ - buffer[0] = value & 0xFF; - buffer[1] = value >> 8; -} - -void AviWriter::host_writed(uint8_t* buffer, uint32_t value) -{ - buffer[0] = value; - buffer[1] = value >> 8; - buffer[2] = value >> 16; - buffer[3] = value >> 24; -} - -bool AviWriter::StartWrite(string filename, VideoCodec codec, uint32_t width, uint32_t height, uint32_t bpp, uint32_t fps, uint32_t audioSampleRate, uint32_t compressionLevel) -{ - _codecType = codec; - _file.open(filename, std::ios::out | std::ios::binary); - if(!_file) { - return false; - } - - switch(_codecType) { - default: - case VideoCodec::None: _codec.reset(new RawCodec()); break; - case VideoCodec::ZMBV: _codec.reset(new ZmbvCodec()); break; - case VideoCodec::CSCD: _codec.reset(new CamstudioCodec()); break; - } - - if(!_codec->SetupCompress(width, height, compressionLevel)) { - return false; - } - - _frameBuffer = new uint8_t[width*height*bpp]; - - _aviIndex.clear(); - _aviIndex.insert(_aviIndex.end(), 8, 0); - - _width = width; - _height = height; - _bpp = bpp; - _fps = fps; - - _audiorate = audioSampleRate; - - for(int i = 0; i < AviWriter::AviHeaderSize; i++) { - _file.put(0); - } - _frames = 0; - _written = 0; - _audioPos = 0; - _audiowritten = 0; - - return true; -} - -void AviWriter::EndWrite() -{ - /* Close the video */ - uint8_t avi_header[AviWriter::AviHeaderSize]; - uint32_t main_list; - uint32_t header_pos = 0; -#define AVIOUT4(_S_) memcpy(&avi_header[header_pos],_S_,4);header_pos+=4; -#define AVIOUTw(_S_) host_writew(&avi_header[header_pos], _S_);header_pos+=2; -#define AVIOUTd(_S_) host_writed(&avi_header[header_pos], _S_);header_pos+=4; - /* Try and write an avi header */ - AVIOUT4("RIFF"); // Riff header - AVIOUTd(AviWriter::AviHeaderSize + _written - 8 + (uint32_t)_aviIndex.size()); - AVIOUT4("AVI "); - AVIOUT4("LIST"); // List header - main_list = header_pos; - AVIOUTd(0); // TODO size of list - AVIOUT4("hdrl"); - - AVIOUT4("avih"); - AVIOUTd(56); /* # of bytes to follow */ - AVIOUTd((uint32_t)(1000000 / _fps)); /* Microseconds per frame */ - AVIOUTd(0); - AVIOUTd(0); /* PaddingGranularity (whatever that might be) */ - AVIOUTd(0x110); /* Flags,0x10 has index, 0x100 interleaved */ - AVIOUTd(_frames); /* TotalFrames */ - AVIOUTd(0); /* InitialFrames */ - AVIOUTd(2); /* Stream count */ - AVIOUTd(0); /* SuggestedBufferSize */ - AVIOUTd(_width); /* Width */ - AVIOUTd(_height); /* Height */ - AVIOUTd(0); /* TimeScale: Unit used to measure time */ - AVIOUTd(0); /* DataRate: Data rate of playback */ - AVIOUTd(0); /* StartTime: Starting time of AVI data */ - AVIOUTd(0); /* DataLength: Size of AVI data chunk */ - - /* Video stream list */ - AVIOUT4("LIST"); - AVIOUTd(4 + 8 + 56 + 8 + 40); /* Size of the list */ - AVIOUT4("strl"); - /* video stream header */ - AVIOUT4("strh"); - AVIOUTd(56); /* # of bytes to follow */ - AVIOUT4("vids"); /* Type */ - AVIOUT4(_codec->GetFourCC()); /* Handler */ - AVIOUTd(0); /* Flags */ - AVIOUTd(0); /* Reserved, MS says: wPriority, wLanguage */ - AVIOUTd(0); /* InitialFrames */ - AVIOUTd(1000000); /* Scale */ - AVIOUTd(_fps); /* Rate: Rate/Scale == samples/second */ - AVIOUTd(0); /* Start */ - AVIOUTd(_frames); /* Length */ - AVIOUTd(0); /* SuggestedBufferSize */ - AVIOUTd(~0); /* Quality */ - AVIOUTd(0); /* SampleSize */ - AVIOUTd(0); /* Frame */ - AVIOUTd(0); /* Frame */ - /* The video stream format */ - AVIOUT4("strf"); - AVIOUTd(40); /* # of bytes to follow */ - AVIOUTd(40); /* Size */ - AVIOUTd(_width); /* Width */ - AVIOUTd(_height); /* Height */ - // OUTSHRT(1); OUTSHRT(24); /* Planes, Count */ - AVIOUTw(1); //number of planes - AVIOUTw(24); //bits for colors - AVIOUT4(_codec->GetFourCC()); /* Compression */ - AVIOUTd(_width * _height * 4); /* SizeImage (in bytes?) */ - AVIOUTd(0); /* XPelsPerMeter */ - AVIOUTd(0); /* YPelsPerMeter */ - AVIOUTd(0); /* ClrUsed: Number of colors used */ - AVIOUTd(0); /* ClrImportant: Number of colors important */ - - /* Audio stream list */ - AVIOUT4("LIST"); - AVIOUTd(4 + 8 + 56 + 8 + 16); /* Length of list in bytes */ - AVIOUT4("strl"); - /* The audio stream header */ - AVIOUT4("strh"); - AVIOUTd(56); /* # of bytes to follow */ - AVIOUT4("auds"); - AVIOUTd(0); /* Format (Optionally) */ - AVIOUTd(0); /* Flags */ - AVIOUTd(0); /* Reserved, MS says: wPriority, wLanguage */ - AVIOUTd(0); /* InitialFrames */ - AVIOUTd(4); /* Scale */ - AVIOUTd(_audiorate * 4); /* Rate, actual rate is scale/rate */ - AVIOUTd(0); /* Start */ - if(!_audiorate) - _audiorate = 1; - AVIOUTd(_audiowritten / 4); /* Length */ - AVIOUTd(0); /* SuggestedBufferSize */ - AVIOUTd(~0); /* Quality */ - AVIOUTd(4); /* SampleSize */ - AVIOUTd(0); /* Frame */ - AVIOUTd(0); /* Frame */ - /* The audio stream format */ - AVIOUT4("strf"); - AVIOUTd(16); /* # of bytes to follow */ - AVIOUTw(1); /* Format, WAVE_ZMBV_FORMAT_PCM */ - AVIOUTw(2); /* Number of channels */ - AVIOUTd(_audiorate); /* SamplesPerSec */ - AVIOUTd(_audiorate * 4); /* AvgBytesPerSec*/ - AVIOUTw(4); /* BlockAlign */ - AVIOUTw(16); /* BitsPerSample */ - int nmain = header_pos - main_list - 4; - /* Finish stream list, i.e. put number of bytes in the list to proper pos */ - - int njunk = AviWriter::AviHeaderSize - 8 - 12 - header_pos; - AVIOUT4("JUNK"); - AVIOUTd(njunk); - /* Fix the size of the main list */ - header_pos = main_list; - AVIOUTd(nmain); - header_pos = AviWriter::AviHeaderSize - 12; - AVIOUT4("LIST"); - AVIOUTd(_written + 4); /* Length of list in bytes */ - AVIOUT4("movi"); - /* First add the index table to the end */ - memcpy(_aviIndex.data(), "idx1", 4); - host_writed(_aviIndex.data() + 4, (uint32_t)_aviIndex.size() - 8); - - _file.write((char*)_aviIndex.data(), _aviIndex.size()); - _file.seekp(std::ios::beg); - _file.write((char*)avi_header, AviWriter::AviHeaderSize); - _file.close(); -} - -void AviWriter::AddFrame(uint8_t *frameData) -{ - if(!_file) { - return; - } - - bool isKeyFrame = (_frames % 120 == 0) ? 1 : 0; - - uint8_t* compressedData = nullptr; - int written = _codec->CompressFrame(isKeyFrame, frameData, &compressedData); - if(written < 0) { - return; - } - - if(_codecType == VideoCodec::None) { - isKeyFrame = true; - } - WriteAviChunk(_codecType == VideoCodec::None ? "00db" : "00dc", written, compressedData, isKeyFrame ? 0x10 : 0); - _frames++; - - if(_audioPos) { - auto lock = _audioLock.AcquireSafe(); - WriteAviChunk("01wb", _audioPos, _audiobuf, 0); - _audiowritten += _audioPos; - _audioPos = 0; - } -} - -void AviWriter::AddSound(int16_t *data, uint32_t sampleCount) -{ - if(!_file) { - return; - } - - auto lock = _audioLock.AcquireSafe(); - memcpy(_audiobuf+_audioPos/2, data, sampleCount * 4); - _audioPos += sampleCount * 4; -} \ No newline at end of file diff --git a/Utilities/AviWriter.h b/Utilities/AviWriter.h deleted file mode 100644 index 0af99ca..0000000 --- a/Utilities/AviWriter.h +++ /dev/null @@ -1,57 +0,0 @@ -// This file is a part of Mesen -// It is a heavily modified version of the hardware.h/cpp file found in DOSBox's code. - -#pragma once -#include "stdafx.h" -#include "SimpleLock.h" -#include "BaseCodec.h" - -enum class VideoCodec -{ - None = 0, - ZMBV = 1, - CSCD = 2, - GIF = 3 -}; - -class AviWriter -{ -private: - static constexpr int WaveBufferSize = 16 * 1024; - static constexpr int AviHeaderSize = 500; - - std::unique_ptr _codec; - ofstream _file; - - VideoCodec _codecType; - - int16_t _audiobuf[WaveBufferSize]; - uint32_t _audioPos = 0; - uint32_t _audiorate = 0; - uint32_t _audiowritten = 0; - - uint32_t _frames = 0; - uint32_t _width = 0; - uint32_t _height = 0; - uint32_t _bpp = 0; - uint32_t _written = 0; - uint32_t _fps = 0; - - uint8_t* _frameBuffer = nullptr; - - vector _aviIndex; - - SimpleLock _audioLock; - -private: - void host_writew(uint8_t* buffer, uint16_t value); - void host_writed(uint8_t* buffer, uint32_t value); - void WriteAviChunk(const char * tag, uint32_t size, void * data, uint32_t flags); - -public: - void AddFrame(uint8_t* frameData); - void AddSound(int16_t * data, uint32_t sampleCount); - - bool StartWrite(string filename, VideoCodec codec, uint32_t width, uint32_t height, uint32_t bpp, uint32_t fps, uint32_t audioSampleRate, uint32_t compressionLevel); - void EndWrite(); -}; \ No newline at end of file diff --git a/Utilities/ZmbvCodec.cpp b/Utilities/ZmbvCodec.cpp deleted file mode 100644 index f6fadca..0000000 --- a/Utilities/ZmbvCodec.cpp +++ /dev/null @@ -1,398 +0,0 @@ -// This file is a part of Mesen -// It is a heavily modified version of the zmbv.h/cpp file found in DOSBox's code. - -/* - * Copyright (C) 2002-2011 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include "stdafx.h" -#include -#include -#include -#include - -#include "miniz.h" -#include "ZmbvCodec.h" - -#define DBZV_VERSION_HIGH 0 -#define DBZV_VERSION_LOW 1 - -#define COMPRESSION_NONE 0 -#define COMPRESSION_ZLIB 1 - -#define MAX_VECTOR 16 - -#define Mask_KeyFrame 0x01 -#define Mask_DeltaPalette 0x02 - -int ZmbvCodec::NeededSize( int _width, int _height, zmbv_format_t _format) { - int f; - switch (_format) { - case ZMBV_FORMAT_8BPP:f = 1;break; - case ZMBV_FORMAT_15BPP:f = 2;break; - case ZMBV_FORMAT_16BPP:f = 2;break; - case ZMBV_FORMAT_32BPP:f = 4;break; - default: - return -1; - } - f = f*_width*_height + 2*(1+(_width/8)) * (1+(_height/8))+1024; - return f + f/1000; -} - -bool ZmbvCodec::SetupBuffers(zmbv_format_t _format, int blockwidth, int blockheight) { - FreeBuffers(); - palsize = 0; - switch (_format) { - case ZMBV_FORMAT_8BPP: - pixelsize = 1; - palsize = 256; - break; - case ZMBV_FORMAT_15BPP: - pixelsize = 2; - break; - case ZMBV_FORMAT_16BPP: - pixelsize = 2; - break; - case ZMBV_FORMAT_32BPP: - pixelsize = 4; - break; - default: - return false; - }; - bufsize = (height+2*MAX_VECTOR)*pitch*pixelsize+2048; - - buf1 = new unsigned char[bufsize]; - buf2 = new unsigned char[bufsize]; - work = new unsigned char[bufsize]; - - int xblocks = (width/blockwidth); - int xleft = width % blockwidth; - if (xleft) xblocks++; - int yblocks = (height/blockheight); - int yleft = height % blockheight; - if (yleft) yblocks++; - blockcount=yblocks*xblocks; - blocks=new FrameBlock[blockcount]; - - if (!buf1 || !buf2 || !work || !blocks) { - FreeBuffers(); - return false; - } - int y,x,i; - i=0; - for (y=0;y -INLINE int ZmbvCodec::PossibleBlock(int vx,int vy,FrameBlock * block) { - int ret=0; - P * pold=((P*)oldframe)+block->start+(vy*pitch)+vx; - P * pnew=((P*)newframe)+block->start;; - for (int y=0;ydy;y+=4) { - for (int x=0;xdx;x+=4) { - int test=0-((pold[x]-pnew[x])&0x00ffffff); - ret-=(test>>31); - } - pold+=pitch*4; - pnew+=pitch*4; - } - return ret; -} - -template -INLINE int ZmbvCodec::CompareBlock(int vx,int vy,FrameBlock * block) { - int ret=0; - P * pold=((P*)oldframe)+block->start+(vy*pitch)+vx; - P * pnew=((P*)newframe)+block->start;; - for (int y=0;ydy;y++) { - for (int x=0;xdx;x++) { - int test=0-((pold[x]-pnew[x])&0x00ffffff); - ret-=(test>>31); - } - pold+=pitch; - pnew+=pitch; - } - return ret; -} - -template -INLINE void ZmbvCodec::AddXorBlock(int vx,int vy,FrameBlock * block) { - P * pold=((P*)oldframe)+block->start+(vy*pitch)+vx; - P * pnew=((P*)newframe)+block->start; - for (int y=0;ydy;y++) { - for (int x=0;xdx;x++) { - *((P*)&work[workUsed])=pnew[x] ^ pold[x]; - workUsed+=sizeof(P); - } - pold+=pitch; - pnew+=pitch; - } -} - -template -void ZmbvCodec::AddXorFrame(void) { - signed char * vectors=(signed char*)&work[workUsed]; - /* Align the following xor data on 4 byte boundary*/ - workUsed=(workUsed + blockcount*2 +3) & ~3; - for (int b=0;b(0,0, block); - int possibles=64; - for (int v=0;v(vx, vy, block) < 4) { - possibles--; - int testchange=CompareBlock

(vx,vy, block); - if (testchange(bestvx, bestvy, block); - } - } -} - -bool ZmbvCodec::SetupCompress( int _width, int _height, uint32_t compressionLevel ) { - width = _width; - height = _height; - pitch = _width + 2*MAX_VECTOR; - format = ZMBV_FORMAT_NONE; - if (deflateInit (&zstream, compressionLevel) != Z_OK) - return false; - - return true; -} - -bool ZmbvCodec::PrepareCompressFrame(int flags, zmbv_format_t _format, char * pal) -{ - int i; - unsigned char *firstByte; - - if (_format != format) { - if (!SetupBuffers( _format, 16, 16)) - return false; - flags|=1; //Force a keyframe - } - /* replace oldframe with new frame */ - unsigned char *copyFrame = newframe; - newframe = oldframe; - oldframe = copyFrame; - - compressInfo.linesDone = 0; - compressInfo.writeSize = _bufSize; - compressInfo.writeDone = 1; - compressInfo.writeBuf = (unsigned char *)_buf; - /* Set a pointer to the first byte which will contain info about this frame */ - firstByte = compressInfo.writeBuf; - *firstByte = 0; - //Reset the work buffer - workUsed = 0;workPos = 0; - if (flags & 1) { - /* Make a keyframe */ - *firstByte |= Mask_KeyFrame; - KeyframeHeader * header = (KeyframeHeader *)(compressInfo.writeBuf + compressInfo.writeDone); - header->high_version = DBZV_VERSION_HIGH; - header->low_version = DBZV_VERSION_LOW; - header->compression = COMPRESSION_ZLIB; - header->format = format; - header->blockwidth = 16; - header->blockheight = 16; - compressInfo.writeDone += sizeof(KeyframeHeader); - /* Copy the new frame directly over */ - if (palsize) { - if (pal) - memcpy(&palette, pal, sizeof(palette)); - else - memset(&palette,0, sizeof(palette)); - /* keyframes get the full palette */ - for (i=0;i(); - break; - case ZMBV_FORMAT_15BPP: - case ZMBV_FORMAT_16BPP: - AddXorFrame(); - break; - - default: - case ZMBV_FORMAT_32BPP: - AddXorFrame(); - break; - } - } - /* Create the actual frame with compression */ - zstream.next_in = (Bytef *)work; - zstream.avail_in = workUsed; - zstream.total_in = 0; - - zstream.next_out = (Bytef *)(compressInfo.writeBuf + compressInfo.writeDone); - zstream.avail_out = compressInfo.writeSize - compressInfo.writeDone; - zstream.total_out = 0; - - deflate(&zstream, Z_SYNC_FLUSH); - - *compressedData = _buf; - - return compressInfo.writeDone + zstream.total_out; -} - -void ZmbvCodec::FreeBuffers() -{ - delete[] blocks; - blocks = nullptr; - delete[] buf1; - buf1 = nullptr; - delete[] buf2; - buf2 = nullptr; - delete[] work; - work = nullptr; - delete[] _buf; - _buf = nullptr; -} - -ZmbvCodec::ZmbvCodec() -{ - CreateVectorTable(); - blocks = nullptr; - buf1 = nullptr; - buf2 = nullptr; - work = nullptr; - memset( &zstream, 0, sizeof(zstream)); -} - -int ZmbvCodec::CompressFrame(bool isKeyFrame, uint8_t *frameData, uint8_t** compressedData) -{ - if(!PrepareCompressFrame(isKeyFrame ? 1 : 0, ZMBV_FORMAT_32BPP, nullptr)) { - return -1; - } - - for(int i = 0; i < height; i++) { - void * rowPointer = frameData + i*width*4; - CompressLines(1, &rowPointer); - } - - return FinishCompressFrame(compressedData); -} - -const char* ZmbvCodec::GetFourCC() -{ - return "ZMBV"; -} \ No newline at end of file diff --git a/Utilities/ZmbvCodec.h b/Utilities/ZmbvCodec.h deleted file mode 100644 index 5e3c285..0000000 --- a/Utilities/ZmbvCodec.h +++ /dev/null @@ -1,115 +0,0 @@ -// This file is a part of Mesen -// It is a heavily modified version of the zmbv.h/cpp file found in DOSBox's code. - -/* - * Copyright (C) 2002-2011 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#pragma once - -#include "BaseCodec.h" -#include "miniz.h" - -#ifdef _MSC_VER -#define INLINE __forceinline -#else -#define INLINE inline -#endif - -typedef enum { - ZMBV_FORMAT_NONE = 0x00, - ZMBV_FORMAT_1BPP = 0x01, - ZMBV_FORMAT_2BPP = 0x02, - ZMBV_FORMAT_4BPP = 0x03, - ZMBV_FORMAT_8BPP = 0x04, - ZMBV_FORMAT_15BPP = 0x05, - ZMBV_FORMAT_16BPP = 0x06, - ZMBV_FORMAT_24BPP = 0x07, - ZMBV_FORMAT_32BPP = 0x08 -} zmbv_format_t; - -class ZmbvCodec : public BaseCodec -{ -private: - struct FrameBlock { - int start = 0; - int dx = 0,dy = 0; - }; - struct CodecVector { - int x = 0,y = 0; - int slot = 0; - }; - struct KeyframeHeader { - unsigned char high_version = 0; - unsigned char low_version = 0; - unsigned char compression = 0; - unsigned char format = 0; - unsigned char blockwidth = 0,blockheight = 0; - }; - - struct { - int linesDone = 0; - int writeSize = 0; - int writeDone = 0; - unsigned char *writeBuf = nullptr; - } compressInfo; - - CodecVector VectorTable[512] = {}; - int VectorCount = 0; - - unsigned char *oldframe=nullptr, *newframe=nullptr; - unsigned char *buf1=nullptr, *buf2=nullptr, *work=nullptr; - int bufsize = 0; - - int blockcount = 0; - FrameBlock * blocks = nullptr; - - int workUsed = 0, workPos = 0; - - int palsize = 0; - char palette[256*4] = {}; - int height = 0, width = 0, pitch = 0; - zmbv_format_t format = zmbv_format_t::ZMBV_FORMAT_NONE; - int pixelsize = 0; - - uint8_t* _buf = nullptr; - uint32_t _bufSize = 0; - - z_stream zstream = {}; - - // methods - void FreeBuffers(void); - void CreateVectorTable(void); - bool SetupBuffers(zmbv_format_t format, int blockwidth, int blockheight); - - template void AddXorFrame(void); - template INLINE int PossibleBlock(int vx,int vy,FrameBlock * block); - template INLINE int CompareBlock(int vx,int vy,FrameBlock * block); - template INLINE void AddXorBlock(int vx,int vy,FrameBlock * block); - - int NeededSize(int _width, int _height, zmbv_format_t _format); - - void CompressLines(int lineCount, void *lineData[]); - bool PrepareCompressFrame(int flags, zmbv_format_t _format, char * pal); - int FinishCompressFrame(uint8_t** compressedData); - -public: - ZmbvCodec(); - bool SetupCompress(int _width, int _height, uint32_t compressionLevel) override; - int CompressFrame(bool isKeyFrame, uint8_t *frameData, uint8_t** compressedData) override; - const char* GetFourCC() override; -};