RetroFrame.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
This commit is contained in:
Andrea Odetti 2021-01-13 17:48:25 +00:00
parent 59c581b807
commit 54a3bbf773
6 changed files with 111 additions and 69 deletions

View file

@ -17,6 +17,7 @@ if (EXISTS ${LIBRETRO_COMMON_PATH}/include/libretro.h)
analog.cpp
rdirectsound.cpp
retroregistry.cpp
retroframe.cpp
)
set(HEADER_FILES
@ -28,6 +29,7 @@ if (EXISTS ${LIBRETRO_COMMON_PATH}/include/libretro.h)
analog.h
rdirectsound.h
retroregistry.h
retroframe.h
)
add_library(applewin_libretro SHARED

View file

@ -3,6 +3,7 @@
#include "frontends/libretro/retroregistry.h"
#include "frontends/libretro/joypad.h"
#include "frontends/libretro/analog.h"
#include "frontends/libretro/retroframe.h"
#include "Common.h"
#include "CardManager.h"
@ -13,12 +14,11 @@
#include "CPU.h"
#include "NTSC.h"
#include "Utilities.h"
#include "Video.h"
#include "Interface.h"
#include "linux/keyboard.h"
#include "linux/registry.h"
#include "linux/paddle.h"
#include "linux/context.h"
#include "frontends/common2/utils.h"
#include "libretro.h"
@ -26,12 +26,6 @@
namespace
{
void updateWindowTitle()
{
GetAppleWindowTitle();
display_message(g_pAppTitle.c_str());
}
bool insertDisk(const std::string & filename)
{
if (filename.empty())
@ -57,31 +51,15 @@ namespace
unsigned Game::ourInputDevices[MAX_PADS] = {RETRO_DEVICE_NONE};
Game::Game()
: mySpeed(true), myButtonStates(RETRO_DEVICE_ID_JOYPAD_R3 + 1)
Game::Game(const std::shared_ptr<RetroFrame> & frame)
: myFrame(frame), mySpeed(true), myButtonStates(RETRO_DEVICE_ID_JOYPAD_R3 + 1)
{
SetFrame(myFrame);
LogInit();
InitialiseRetroRegistry();
initialiseEmulator();
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);
const size_t size = myHeight * myPitch;
myVideoBuffer.resize(size);
switch (ourInputDevices[0])
{
@ -104,6 +82,7 @@ Game::Game()
Game::~Game()
{
uninitialiseEmulator();
SetFrame(std::shared_ptr<FrameBase>());
Paddle::instance.reset();
Registry::instance.reset();
}
@ -281,26 +260,13 @@ void Game::keyboardEmulation()
{
if (ourInputDevices[0] != RETRO_DEVICE_NONE)
{
Video & video = GetVideo();
if (checkButtonPressed(RETRO_DEVICE_ID_JOYPAD_R))
{
video.IncVideoType();
video.VideoReinitialize(false);
video.Config_Save_Video();
updateWindowTitle();
myFrame->CycleVideoType();
}
if (checkButtonPressed(RETRO_DEVICE_ID_JOYPAD_L))
{
VideoStyle_e videoStyle = video.GetVideoStyle();
videoStyle = VideoStyle_e(videoStyle ^ VS_HALF_SCANLINES);
video.SetVideoStyle(videoStyle);
video.VideoReinitialize(false);
video.Config_Save_Video();
updateWindowTitle();
myFrame->Cycle50ScanLines();
}
if (checkButtonPressed(RETRO_DEVICE_ID_JOYPAD_START))
{
@ -313,22 +279,6 @@ void Game::keyboardEmulation()
}
}
void Game::drawVideoBuffer()
{
// this should not be necessary
// either libretro handles it
// or we should change AW
// but for now, there is no alternative
for (size_t row = 0; row < myHeight; ++row)
{
const uint8_t * src = myFrameBuffer + row * myPitch;
uint8_t * dst = myVideoBuffer.data() + (myHeight - row - 1) * myPitch;
memcpy(dst, src, myPitch);
}
video_cb(myVideoBuffer.data() + myOffset, myBorderlessWidth, myBorderlessHeight, myPitch);
}
bool Game::loadGame(const std::string & path)
{
const bool ok = insertDisk(path);

View file

@ -6,10 +6,12 @@
#include <string>
#include <vector>
class RetroFrame;
class Game
{
public:
Game();
Game(const std::shared_ptr<RetroFrame> & frame);
~Game();
bool loadGame(const std::string & path);
@ -28,15 +30,9 @@ public:
static retro_usec_t ourFrameTime;
private:
Speed mySpeed; // fixed speed
std::vector<uint8_t> myVideoBuffer;
const std::shared_ptr<RetroFrame> myFrame;
size_t myPitch;
size_t myOffset;
size_t myHeight;
size_t myBorderlessWidth;
size_t myBorderlessHeight;
uint8_t* myFrameBuffer;
Speed mySpeed; // fixed speed
std::vector<int> myButtonStates;

View file

@ -14,6 +14,7 @@
#include "frontends/libretro/environment.h"
#include "frontends/libretro/rdirectsound.h"
#include "frontends/libretro/retroregistry.h"
#include "frontends/libretro/retroframe.h"
namespace
{
@ -160,7 +161,7 @@ void retro_run(void)
{
ourGame->processInputEvents();
ourGame->executeOneFrame();
ourGame->drawVideoBuffer();
GetFrame().VideoPresentScreen();
const size_t ms = (1000 + 60 - 1) / 60; // round up
RDirectSound::writeAudio(ms);
}
@ -179,7 +180,8 @@ bool retro_load_game(const retro_game_info *info)
try
{
std::unique_ptr<Game> game(new Game);
std::shared_ptr<RetroFrame> frame(new RetroFrame());
std::unique_ptr<Game> game(new Game(frame));
const std::string snapshotEnding = ".aws.yaml";
const std::string gamePath = info->path;

View file

@ -0,0 +1,66 @@
#include "StdAfx.h"
#include "frontends/libretro/retroframe.h"
#include "frontends/libretro/environment.h"
#include "Interface.h"
#include "Core.h"
#include "Utilities.h"
RetroFrame::RetroFrame()
{
}
void RetroFrame::FrameRefreshStatus(int drawflags)
{
if (drawflags & DRAW_TITLE)
{
GetAppleWindowTitle();
display_message(g_pAppTitle.c_str());
}
}
void RetroFrame::VideoPresentScreen()
{
// this should not be necessary
// either libretro handles it
// or we should change AW
// but for now, there is no alternative
for (size_t row = 0; row < myHeight; ++row)
{
const uint8_t * src = myFrameBuffer + row * myPitch;
uint8_t * dst = myVideoBuffer.data() + (myHeight - row - 1) * myPitch;
memcpy(dst, src, myPitch);
}
video_cb(myVideoBuffer.data() + myOffset, myBorderlessWidth, myBorderlessHeight, myPitch);
}
void RetroFrame::Initialize()
{
LinuxFrame::Initialize();
FrameRefreshStatus(DRAW_TITLE);
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);
const size_t size = myHeight * myPitch;
myVideoBuffer.resize(size);
}
void RetroFrame::Destroy()
{
LinuxFrame::Destroy();
myFrameBuffer = nullptr;
myVideoBuffer.clear();
}

View file

@ -0,0 +1,26 @@
#pragma once
#include "linux/linuxframe.h"
#include <memory>
#include <vector>
class RetroFrame : public LinuxFrame
{
public:
RetroFrame();
virtual void VideoPresentScreen();
virtual void FrameRefreshStatus(int drawflags);
virtual void Initialize();
virtual void Destroy();
private:
std::vector<uint8_t> myVideoBuffer;
size_t myPitch;
size_t myOffset;
size_t myHeight;
size_t myBorderlessWidth;
size_t myBorderlessHeight;
uint8_t* myFrameBuffer;
};