Integration of GetVideo().

Part 1.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
This commit is contained in:
Andrea Odetti 2020-12-28 19:42:04 +00:00
parent 577a997003
commit 247b51b2ab
19 changed files with 182 additions and 124 deletions

View file

@ -59,7 +59,7 @@ add_library(appleii SHARED
linux/version.cpp
linux/registry.cpp
linux/keyboard.cpp
linux/videobuffer.cpp
linux/linuxvideo.cpp
linux/linuxframe.cpp
linux/duplicates/Debug.cpp

View file

@ -1,5 +1,7 @@
#pragma once
#include "Video.h"
// Globals (Public)
extern uint16_t g_nVideoClockVert;
extern uint16_t g_nVideoClockHorz;

View file

@ -2,7 +2,6 @@
#include "linux/data.h"
#include "linux/interface.h"
#include "linux/videobuffer.h"
#include "StdAfx.h"
#include "SaveState.h"
@ -82,8 +81,8 @@ void initialiseEmulator()
SpkrInitialize();
MemInitialize();
VideoBufferInitialize();
VideoSwitchVideocardPalette(RGB_GetVideocard(), GetVideoType());
GetVideo().Initialize();
VideoSwitchVideocardPalette(RGB_GetVideocard(), GetVideo().GetVideoType());
GetCardMgr().GetDisk2CardMgr().Reset();
HD_Reset();
@ -99,7 +98,7 @@ void uninitialiseEmulator()
pMouseCard->Reset();
}
MemDestroy();
VideoBufferDestroy();
GetVideo().Destroy();
SpkrDestroy();
MB_Destroy();

View file

@ -65,12 +65,17 @@ Game::Game()
initialiseEmulator();
myBorderlessWidth = GetFrameBufferBorderlessWidth();
myBorderlessHeight = GetFrameBufferBorderlessHeight();
const size_t borderWidth = GetFrameBufferBorderWidth();
const size_t borderHeight = GetFrameBufferBorderHeight();
const size_t width = GetFrameBufferWidth();
myHeight = GetFrameBufferHeight();
Video & video = GetVideo();
myBorderlessWidth = video.GetFrameBufferBorderlessWidth();
myBorderlessHeight = video.GetFrameBufferBorderlessHeight();
const size_t borderWidth = video.GetFrameBufferBorderWidth();
const size_t borderHeight = video.GetFrameBufferBorderHeight();
const size_t width = video.GetFrameBufferWidth();
myHeight = video.GetFrameBufferHeight();
myFrameBuffer = video.GetFrameBuffer();
myPitch = width * sizeof(bgra_t);
myOffset = (width * borderHeight + borderWidth) * sizeof(bgra_t);
@ -276,26 +281,26 @@ void Game::keyboardEmulation()
{
if (ourInputDevices[0] != RETRO_DEVICE_NONE)
{
Video & video = GetVideo();
if (checkButtonPressed(RETRO_DEVICE_ID_JOYPAD_R))
{
g_eVideoType++;
if (g_eVideoType >= NUM_VIDEO_MODES)
g_eVideoType = 0;
video.IncVideoType();
Config_Save_Video();
VideoReinitialize();
video.Config_Save_Video();
video.VideoReinitialize();
GetFrame().VideoRedrawScreen();
updateWindowTitle();
}
if (checkButtonPressed(RETRO_DEVICE_ID_JOYPAD_L))
{
VideoStyle_e videoStyle = GetVideoStyle();
VideoStyle_e videoStyle = video.GetVideoStyle();
videoStyle = VideoStyle_e(videoStyle ^ VS_HALF_SCANLINES);
SetVideoStyle(videoStyle);
video.SetVideoStyle(videoStyle);
Config_Save_Video();
VideoReinitialize();
video.Config_Save_Video();
video.VideoReinitialize();
GetFrame().VideoRedrawScreen();
updateWindowTitle();
}
@ -318,7 +323,7 @@ void Game::drawVideoBuffer()
// but for now, there is no alternative
for (size_t row = 0; row < myHeight; ++row)
{
const uint8_t * src = g_pFramebufferbits + row * myPitch;
const uint8_t * src = myFrameBuffer + row * myPitch;
uint8_t * dst = myVideoBuffer.data() + (myHeight - row - 1) * myPitch;
memcpy(dst, src, myPitch);
}

View file

@ -36,6 +36,7 @@ private:
size_t myHeight;
size_t myBorderlessWidth;
size_t myBorderlessHeight;
uint8_t* myFrameBuffer;
std::vector<int> myButtonStates;

View file

@ -5,6 +5,7 @@
#include "StdAfx.h"
#include "Common.h"
#include "Video.h"
#include "Interface.h"
#include "linux/version.h"
#include "linux/paddle.h"
@ -77,10 +78,12 @@ void retro_get_system_av_info(retro_system_av_info *info)
{
log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
info->geometry.base_width = GetFrameBufferBorderlessWidth();
info->geometry.base_height = GetFrameBufferBorderlessHeight();
info->geometry.max_width = GetFrameBufferBorderlessWidth();
info->geometry.max_height = GetFrameBufferBorderlessHeight();
Video & video = GetVideo();
info->geometry.base_width = video.GetFrameBufferBorderlessWidth();
info->geometry.base_height = video.GetFrameBufferBorderlessHeight();
info->geometry.max_width = video.GetFrameBufferBorderlessWidth();
info->geometry.max_height = video.GetFrameBufferBorderlessHeight();
info->geometry.aspect_ratio = 0;
info->timing.fps = Game::FPS;

View file

@ -15,6 +15,7 @@
#include "Memory.h"
#include "Core.h"
#include "RGBMonitor.h"
#include "Interface.h"
#include "linux/interface.h"
#include "linux/paddle.h"
@ -49,14 +50,6 @@ namespace
LPBYTE g_pHiresBank1;
LPBYTE g_pHiresBank0;
#define SW_80COL (g_uVideoMode & VF_80COL)
#define SW_DHIRES (g_uVideoMode & VF_DHIRES)
#define SW_HIRES (g_uVideoMode & VF_HIRES)
#define SW_80STORE (g_uVideoMode & VF_80STORE)
#define SW_MIXED (g_uVideoMode & VF_MIXED)
#define SW_PAGE2 (g_uVideoMode & VF_PAGE2)
#define SW_TEXT (g_uVideoMode & VF_TEXT)
bool g_bTextFlashState = false;
void sig_handler_pass(int signo)
@ -72,7 +65,7 @@ namespace
g_stop = true;
}
chtype mapCharacter(BYTE ch)
chtype mapCharacter(Video & video, BYTE ch)
{
const char low = ch & 0x7f;
const char high = ch & 0x80;
@ -93,7 +86,7 @@ namespace
break;
case 3: // 60 - 7F
// LOWERCASE
if (high == 0 && g_nAltCharSetOffset == 0)
if (high == 0 && !video.VideoGetSWAltCharSet())
{
result -= 0x40;
}
@ -107,7 +100,7 @@ namespace
if (!high)
{
if ((g_nAltCharSetOffset == 0) && (low >= 0x40))
if (!video.VideoGetSWAltCharSet() && (low >= 0x40))
{
// result |= A_BLINK; // does not work on my terminal
if (g_bTextFlashState)
@ -137,9 +130,9 @@ namespace
}
}
typedef bool (*VideoUpdateFuncPtr_t)(int, int, int, int, int);
typedef bool (*VideoUpdateFuncPtr_t)(Video &, int, int, int, int, int);
bool NUpdate40ColCell (int x, int y, int xpixel, int ypixel, int offset)
bool NUpdate40ColCell (Video & video, int x, int y, int xpixel, int ypixel, int offset)
{
frame->init(24, 40);
asciiArt->init(1, 1);
@ -148,13 +141,13 @@ namespace
WINDOW * win = frame->getWindow();
const chtype ch2 = mapCharacter(ch);
const chtype ch2 = mapCharacter(video, ch);
mvwaddch(win, 1 + y, 1 + x, ch2);
return true;
}
bool NUpdate80ColCell (int x, int y, int xpixel, int ypixel, int offset)
bool NUpdate80ColCell (Video & video, int x, int y, int xpixel, int ypixel, int offset)
{
frame->init(24, 80);
asciiArt->init(1, 2);
@ -164,16 +157,16 @@ namespace
WINDOW * win = frame->getWindow();
const chtype ch12 = mapCharacter(ch1);
const chtype ch12 = mapCharacter(video, ch1);
mvwaddch(win, 1 + y, 1 + 2 * x, ch12);
const chtype ch22 = mapCharacter(ch2);
const chtype ch22 = mapCharacter(video, ch2);
mvwaddch(win, 1 + y, 1 + 2 * x + 1, ch22);
return true;
}
bool NUpdateLoResCell (int x, int y, int xpixel, int ypixel, int offset)
bool NUpdateLoResCell (Video &, int x, int y, int xpixel, int ypixel, int offset)
{
BYTE val = *(g_pTextBank0+offset);
@ -195,12 +188,12 @@ namespace
return true;
}
bool NUpdateDLoResCell (int x, int y, int xpixel, int ypixel, int offset)
bool NUpdateDLoResCell (Video &, int x, int y, int xpixel, int ypixel, int offset)
{
return true;
}
bool NUpdateHiResCell (int x, int y, int xpixel, int ypixel, int offset)
bool NUpdateHiResCell (Video &, int x, int y, int xpixel, int ypixel, int offset)
{
const BYTE * base = g_pHiresBank0 + offset;
@ -230,7 +223,7 @@ namespace
return true;
}
bool NUpdateDHiResCell (int x, int y, int xpixel, int ypixel, int offset)
bool NUpdateDHiResCell (Video &, int x, int y, int xpixel, int ypixel, int offset)
{
return true;
}
@ -375,22 +368,24 @@ void NVideoRedrawScreen()
VideoUpdateFlash();
FrameRefresh();
const int displaypage2 = (SW_PAGE2) == 0 ? 0 : 1;
Video & video = GetVideo();
const int displaypage2 = video.VideoGetSWPAGE2() == 0 ? 0 : 1;
g_pHiresBank1 = MemGetAuxPtr (0x2000 << displaypage2);
g_pHiresBank0 = MemGetMainPtr(0x2000 << displaypage2);
g_pTextBank1 = MemGetAuxPtr (0x400 << displaypage2);
g_pTextBank0 = MemGetMainPtr(0x400 << displaypage2);
VideoUpdateFuncPtr_t update = SW_TEXT
? SW_80COL
VideoUpdateFuncPtr_t update = video.VideoGetSWTEXT()
? video.VideoGetSW80COL()
? NUpdate80ColCell
: NUpdate40ColCell
: SW_HIRES
? (SW_DHIRES && SW_80COL)
: video.VideoGetSWHIRES()
? (video.VideoGetSWDHIRES() && video.VideoGetSW80COL())
? NUpdateDHiResCell
: NUpdateHiResCell
: (SW_DHIRES && SW_80COL)
: (video.VideoGetSWDHIRES() && video.VideoGetSW80COL())
? NUpdateDLoResCell
: NUpdateLoResCell;
@ -401,7 +396,7 @@ void NVideoRedrawScreen()
int x = 0;
int xpixel = 0;
while (x < 40) {
update(x, y, xpixel, ypixel, offset + x);
update(video, x, y, xpixel, ypixel, offset + x);
++x;
xpixel += 14;
}
@ -409,8 +404,8 @@ void NVideoRedrawScreen()
ypixel += 16;
}
if (SW_MIXED)
update = SW_80COL ? NUpdate80ColCell
if (video.VideoGetSWMIXED())
update = video.VideoGetSW80COL() ? NUpdate80ColCell
: NUpdate40ColCell;
while (y < 24) {
@ -418,7 +413,7 @@ void NVideoRedrawScreen()
int x = 0;
int xpixel = 0;
while (x < 40) {
update(x, y, xpixel, ypixel, offset + x);
update(video, x, y, xpixel, ypixel, offset + x);
++x;
xpixel += 14;
}

View file

@ -6,6 +6,7 @@
#include "Common.h"
#include "Video.h"
#include "NTSC.h"
#include "Interface.h"
#include <cmath>
@ -28,7 +29,7 @@ void Emulator::updateVideo()
void Emulator::redrawScreen()
{
NTSC_SetVideoMode( g_uVideoMode );
NTSC_SetVideoMode( GetVideo().GetVideoMode() );
NTSC_VideoRedrawWholeScreen();
refreshScreen();
}

View file

@ -23,10 +23,8 @@
#include "Riff.h"
#include "RGBMonitor.h"
#include "Utilities.h"
#include "Windows/WinVideo.h"
#include "linux/data.h"
#include "linux/videobuffer.h"
#include "linux/benchmark.h"
#include "linux/version.h"
#include "linux/paddle.h"
@ -110,8 +108,8 @@ namespace
MB_Initialize();
SpkrInitialize();
MemInitialize();
VideoBufferInitialize();
VideoSwitchVideocardPalette(RGB_GetVideocard(), GetVideoType());
GetVideo().Initialize();
VideoSwitchVideocardPalette(RGB_GetVideocard(), GetVideo().GetVideoType());
emulator->displayLogo();
@ -132,7 +130,7 @@ namespace
PrintDestroy();
MemDestroy();
SpkrDestroy();
VideoBufferDestroy();
GetVideo().Destroy();
MB_Destroy();
DSUninit();
CpuDestroy();
@ -583,15 +581,14 @@ void QApple::on_actionLoad_state_from_triggered()
void QApple::on_actionNext_video_mode_triggered()
{
g_eVideoType++;
if (g_eVideoType >= NUM_VIDEO_MODES)
g_eVideoType = 0;
Video & video = GetVideo();
video.IncVideoType();
GetAppleWindowTitle();
myEmulatorWindow->setWindowTitle(QString::fromStdString(g_pAppTitle));
Config_Save_Video();
VideoReinitialize();
video.Config_Save_Video();
video.VideoReinitialize();
GetFrame().VideoRedrawScreen();
}

View file

@ -4,7 +4,6 @@
#include <iostream>
#include "linux/videobuffer.h"
#include "linux/paddle.h"
#include "linux/keyboard.h"
@ -16,7 +15,6 @@
#include "Disk.h"
#include "CPU.h"
#include "Video.h"
#include "Windows/WinVideo.h"
#include "NTSC.h"
#include "Mockingboard.h"
#include "Speaker.h"
@ -37,12 +35,11 @@ namespace
void cycleVideoType(const std::shared_ptr<SDL_Window> & win)
{
g_eVideoType++;
if (g_eVideoType >= NUM_VIDEO_MODES)
g_eVideoType = 0;
Video & video = GetVideo();
video.IncVideoType();
Config_Save_Video();
VideoReinitialize();
video.Config_Save_Video();
video.VideoReinitialize();
GetFrame().VideoRedrawScreen();
updateWindowTitle(win);
@ -50,13 +47,15 @@ namespace
void cycle50ScanLines(const std::shared_ptr<SDL_Window> & win)
{
VideoStyle_e videoStyle = GetVideoStyle();
Video & video = GetVideo();
VideoStyle_e videoStyle = video.GetVideoStyle();
videoStyle = VideoStyle_e(videoStyle ^ VS_HALF_SCANLINES);
SetVideoStyle(videoStyle);
video.SetVideoStyle(videoStyle);
Config_Save_Video();
VideoReinitialize();
video.Config_Save_Video();
video.VideoReinitialize();
GetFrame().VideoRedrawScreen();
updateWindowTitle(win);
@ -156,11 +155,15 @@ Emulator::Emulator(
, myFullscreen(false)
, mySpeed(fixedSpeed)
{
myRect.x = GetFrameBufferBorderWidth();
myRect.y = GetFrameBufferBorderHeight();
myRect.w = GetFrameBufferBorderlessWidth();
myRect.h = GetFrameBufferBorderlessHeight();
myPitch = GetFrameBufferWidth() * sizeof(bgra_t);
Video & video = GetVideo();
myRect.x = video.GetFrameBufferBorderWidth();
myRect.y = video.GetFrameBufferBorderHeight();
myRect.w = video.GetFrameBufferBorderlessWidth();
myRect.h = video.GetFrameBufferBorderlessHeight();
myPitch = video.GetFrameBufferWidth() * sizeof(bgra_t);
myFrameBuffer = video.GetFrameBuffer();
}
void Emulator::execute(const size_t next)
@ -183,7 +186,7 @@ void Emulator::execute(const size_t next)
void Emulator::updateTexture()
{
SDL_UpdateTexture(myTexture.get(), nullptr, g_pFramebufferbits, myPitch);
SDL_UpdateTexture(myTexture.get(), nullptr, myFrameBuffer, myPitch);
}
void Emulator::refreshVideo()
@ -265,9 +268,10 @@ void Emulator::processKeyDown(const SDL_KeyboardEvent & key, bool & quit)
}
else if (key.keysym.mod & KMOD_CTRL)
{
Video & video = GetVideo();
myMultiplier = myMultiplier == 1 ? 2 : 1;
const int sw = GetFrameBufferBorderlessWidth();
const int sh = GetFrameBufferBorderlessHeight();
const int sw = video.GetFrameBufferBorderlessWidth();
const int sh = video.GetFrameBufferBorderlessHeight();
SDL_SetWindowSize(myWindow.get(), sw * myMultiplier, sh * myMultiplier);
}
else if (!(key.keysym.mod & KMOD_SHIFT))

View file

@ -38,4 +38,5 @@ private:
SDL_Rect myRect;
int myPitch;
uint8_t* myFrameBuffer;
};

View file

@ -23,6 +23,7 @@
#include "CPU.h"
#include "NTSC.h"
#include "SaveState.h"
#include "Interface.h"
// comment out to test / debug init / shutdown only
#define EMULATOR_RUN
@ -119,10 +120,12 @@ void run_sdl(int argc, const char * argv [])
initialiseEmulator();
applyOptions(options);
const int width = GetFrameBufferWidth();
const int height = GetFrameBufferHeight();
const int sw = GetFrameBufferBorderlessWidth();
const int sh = GetFrameBufferBorderlessHeight();
Video & video = GetVideo();
const int width = video.GetFrameBufferWidth();
const int height = video.GetFrameBufferHeight();
const int sw = video.GetFrameBufferBorderlessWidth();
const int sh = video.GetFrameBufferBorderlessHeight();
std::cerr << std::fixed << std::setprecision(2);
@ -167,8 +170,8 @@ void run_sdl(int argc, const char * argv [])
}
};
const auto refresh = [redraw]{
NTSC_SetVideoMode( g_uVideoMode );
const auto refresh = [redraw, &video]{
NTSC_SetVideoMode( video.GetVideoMode() );
NTSC_VideoRedrawWholeScreen();
redraw();
};

View file

@ -9,6 +9,7 @@
#include "NTSC.h"
#include "Disk.h"
#include "CPU.h"
#include "Interface.h"
#include "linux/benchmark.h"
@ -16,6 +17,7 @@
void VideoBenchmark(std::function<void()> redraw, std::function<void()> refresh)
{
Video & video = GetVideo();
// PREPARE TWO DIFFERENT FRAME BUFFERS, EACH OF WHICH HAVE HALF OF THE
// BYTES SET TO 0x14 AND THE OTHER HALF SET TO 0xAA
int loop;
@ -30,7 +32,7 @@ void VideoBenchmark(std::function<void()> redraw, std::function<void()> refresh)
// SEE HOW MANY HIRES FRAMES PER SECOND WE CAN PRODUCE WITH NOTHING ELSE
// GOING ON, CHANGING HALF OF THE BYTES IN THE VIDEO BUFFER EACH FRAME TO
// SIMULATE THE ACTIVITY OF AN AVERAGE GAME
g_uVideoMode = VF_HIRES;
video.SetVideoMode(VF_HIRES);
memset(mem+0x2000,0x14,0x2000);
redraw();

View file

@ -3,6 +3,7 @@
#include "Interface.h"
#include "linux/duplicates/PropertySheet.h"
#include "linux/linuxframe.h"
#include "linux/linuxvideo.h"
IPropertySheet& GetPropertySheet()
{
@ -15,3 +16,9 @@ FrameBase& GetFrame()
static LinuxFrame sg_LinuxFrame;
return sg_LinuxFrame;
}
Video& GetVideo()
{
static LinuxVideo sg_LinuxVideo;
return sg_LinuxVideo;
}

View file

@ -2,7 +2,7 @@
#include "linux/linuxframe.h"
#include "Video.h"
#include "Windows/WinVideo.h"
#include "Interface.h"
#include "NTSC.h"
void LinuxFrame::FrameDrawDiskLEDS(HDC hdc)
@ -28,7 +28,7 @@ void LinuxFrame::FrameSetCursorPosByMousePos()
void LinuxFrame::VideoRedrawScreen()
{
// NB. Can't rely on g_uVideoMode being non-zero (ie. so it can double up as a flag) since 'GR,PAGE1,non-mixed' mode == 0x00.
VideoRefreshScreen(g_uVideoMode, true);
GetVideo().VideoRefreshScreen(GetVideo().GetVideoMode(), true);
}
void LinuxFrame::SetFullScreenShowSubunitStatus(bool /* bShow */)

View file

@ -0,0 +1,49 @@
#include "StdAfx.h"
#include "linux/linuxvideo.h"
#include "NTSC.h"
void LinuxVideo::Initialize()
{
static_assert(sizeof(bgra_t) == 4, "Invalid size of bgra_t");
VideoResetState();
const int numberOfPixels = GetFrameBufferWidth() * GetFrameBufferHeight();
g_pFramebufferbits = static_cast<uint8_t *>(calloc(sizeof(bgra_t), numberOfPixels));
NTSC_VideoInit(g_pFramebufferbits);
}
void LinuxVideo::Destroy()
{
free(g_pFramebufferbits);
g_pFramebufferbits = nullptr;
NTSC_Destroy();
}
void LinuxVideo::VideoRedrawScreenDuringFullSpeed(DWORD dwCyclesThisFrame, bool bInit)
{
}
void LinuxVideo::VideoRedrawScreenAfterFullSpeed(DWORD dwCyclesThisFrame)
{
}
void LinuxVideo::VideoRefreshScreen(uint32_t uRedrawWholeScreenVideoMode, bool bRedrawWholeScreen)
{
}
void LinuxVideo::Video_RedrawAndTakeScreenShot(const char* pScreenshotFilename)
{
}
void LinuxVideo::ChooseMonochromeColor()
{
}
void LinuxVideo::Benchmark()
{
}
void LinuxVideo::DisplayLogo()
{
}

18
source/linux/linuxvideo.h Normal file
View file

@ -0,0 +1,18 @@
#pragma once
#include "Video.h"
class LinuxVideo : public Video
{
public:
virtual void Initialize();
virtual void Destroy();
virtual void VideoRedrawScreenDuringFullSpeed(DWORD dwCyclesThisFrame, bool bInit = false);
virtual void VideoRedrawScreenAfterFullSpeed(DWORD dwCyclesThisFrame);
virtual void VideoRefreshScreen(uint32_t uRedrawWholeScreenVideoMode = 0, bool bRedrawWholeScreen = false);
virtual void Video_RedrawAndTakeScreenShot(const char* pScreenshotFilename);
virtual void ChooseMonochromeColor();
virtual void Benchmark();
virtual void DisplayLogo();
};

View file

@ -1,22 +0,0 @@
#include "linux/videobuffer.h"
#include "StdAfx.h"
#include "Video.h"
#include "NTSC.h"
void VideoBufferInitialize()
{
static_assert(sizeof(bgra_t) == 4, "Invalid size of bgra_t");
VideoResetState();
const int numberOfPixels = GetFrameBufferWidth() * GetFrameBufferHeight();
g_pFramebufferbits = static_cast<uint8_t *>(calloc(sizeof(bgra_t), numberOfPixels));
NTSC_VideoInit(g_pFramebufferbits);
}
void VideoBufferDestroy()
{
free(g_pFramebufferbits);
g_pFramebufferbits = nullptr;
NTSC_Destroy();
}

View file

@ -1,7 +0,0 @@
#pragma once
// calls VideoResetState();
// and
// initialises g_pFramebufferbits as a simple malloc'ed buffer
void VideoBufferInitialize();
void VideoBufferDestroy();