Cocoa Port: Continue refactoring of the display view code to reduce port-specific dependence.

This commit is contained in:
rogerman 2017-01-06 15:23:26 -08:00
parent 616962f0b7
commit cffc343496
14 changed files with 1343 additions and 1179 deletions

View File

@ -17,155 +17,440 @@
#include "ClientDisplayView.h"
#include <sstream>
ClientDisplayView::ClientDisplayView()
{
_property.normalWidth = GPU_FRAMEBUFFER_NATIVE_WIDTH;
_property.normalHeight = GPU_FRAMEBUFFER_NATIVE_HEIGHT * 2.0;
_property.clientWidth = _property.normalWidth;
_property.clientHeight = _property.normalHeight;
_property.rotation = 0.0;
_property.viewScale = 1.0;
_property.gapScale = 0.0;
_property.gapDistance = DS_DISPLAY_UNSCALED_GAP * _property.gapScale;
_property.mode = ClientDisplayMode_Dual;
_property.layout = ClientDisplayLayout_Vertical;
_property.order = ClientDisplayOrder_MainFirst;
ClientDisplayViewProperties defaultProperty;
defaultProperty.normalWidth = GPU_FRAMEBUFFER_NATIVE_WIDTH;
defaultProperty.normalHeight = GPU_FRAMEBUFFER_NATIVE_HEIGHT * 2.0;
defaultProperty.clientWidth = defaultProperty.normalWidth;
defaultProperty.clientHeight = defaultProperty.normalHeight;
defaultProperty.rotation = 0.0;
defaultProperty.viewScale = 1.0;
defaultProperty.gapScale = 0.0;
defaultProperty.gapDistance = DS_DISPLAY_UNSCALED_GAP * defaultProperty.gapScale;
defaultProperty.mode = ClientDisplayMode_Dual;
defaultProperty.layout = ClientDisplayLayout_Vertical;
defaultProperty.order = ClientDisplayOrder_MainFirst;
_initialTouchInMajorDisplay = new InitialTouchPressMap;
__InstanceInit(defaultProperty);
}
ClientDisplayView::ClientDisplayView(const ClientDisplayViewProperties props)
ClientDisplayView::ClientDisplayView(const ClientDisplayViewProperties &props)
{
_property = props;
_initialTouchInMajorDisplay = new InitialTouchPressMap;
__InstanceInit(props);
}
ClientDisplayView::~ClientDisplayView()
{
delete _initialTouchInMajorDisplay;
}
ClientDisplayViewProperties ClientDisplayView::GetProperties() const
{
return this->_property;
}
void ClientDisplayView::SetProperties(const ClientDisplayViewProperties props)
{
this->_property = props;
ClientDisplayView::CalculateNormalSize(props.mode, props.layout, props.gapScale, this->_property.normalWidth, this->_property.normalHeight);
FT_Done_FreeType(this->_ftLibrary);
}
void ClientDisplayView::SetClientSize(const double w, const double h)
void ClientDisplayView::__InstanceInit(const ClientDisplayViewProperties &props)
{
this->_property.clientWidth = w;
this->_property.clientHeight = h;
this->_property.viewScale = ClientDisplayView::GetMaxScalarWithinBounds(this->_property.normalWidth, this->_property.normalHeight, w, h);
_stagedProperty = props;
_renderProperty = _stagedProperty;
_initialTouchInMajorDisplay = new InitialTouchPressMap;
_useDeposterize = false;
_pixelScaler = VideoFilterTypeID_None;
_outputFilter = OutputFilterTypeID_Bilinear;
_scaleFactor = 1.0;
_hudObjectScale = 1.0;
_isHUDVisible = true;
_showVideoFPS = true;
_showRender3DFPS = false;
_showFrameIndex = false;
_showLagFrameCount = false;
_showCPULoadAverage = false;
_showRTC = false;
memset(&_frameInfo, 0, sizeof(_frameInfo));
_hudString = "\x01"; // Char value 0x01 will represent the "text box" character, which will always be first in the string.
FT_Error error = FT_Init_FreeType(&_ftLibrary);
if (error)
{
printf("ClientDisplayView: FreeType failed to init!\n");
}
memset(_glyphInfo, 0, sizeof(_glyphInfo));
_glyphTileSize = ((double)HUD_TEXTBOX_BASEGLYPHSIZE * _scaleFactor) + 0.0001;
_glyphSize = ((double)_glyphTileSize * 0.75) + 0.0001;
// Set up the text box, which resides at glyph position 1.
GlyphInfo &boxInfo = _glyphInfo[1];
boxInfo.width = _glyphTileSize;
boxInfo.texCoord[0] = 1.0f/16.0f; boxInfo.texCoord[1] = 0.0f;
boxInfo.texCoord[2] = 2.0f/16.0f; boxInfo.texCoord[3] = 0.0f;
boxInfo.texCoord[4] = 2.0f/16.0f; boxInfo.texCoord[5] = 1.0f/16.0f;
boxInfo.texCoord[6] = 1.0f/16.0f; boxInfo.texCoord[7] = 1.0f/16.0f;
}
void ClientDisplayView::_UpdateHUDString()
{
std::ostringstream ss;
ss << "\x01"; // This represents the text box. It must always be the first character.
if (this->_showVideoFPS)
{
ss << "Video FPS: " << this->_frameInfo.videoFPS << "\n";
}
if (this->_showRender3DFPS)
{
ss << "3D Rendering FPS: " << this->_frameInfo.render3DFPS << "\n";
}
if (this->_showFrameIndex)
{
ss << "Frame Index: " << this->_frameInfo.frameIndex << "\n";
}
if (this->_showLagFrameCount)
{
ss << "Lag Frame Count: " << this->_frameInfo.lagFrameCount << "\n";
}
if (this->_showCPULoadAverage)
{
static char buffer[32];
memset(buffer, 0, sizeof(buffer));
snprintf(buffer, 25, "CPU Load Avg: %02d%% / %02d%%\n", this->_frameInfo.cpuLoadAvgARM9, this->_frameInfo.cpuLoadAvgARM7);
ss << buffer;
}
if (this->_showRTC)
{
ss << "RTC: " << this->_frameInfo.rtcString << "\n";
}
this->_hudString = ss.str();
}
void ClientDisplayView::_SetHUDShowInfoItem(bool &infoItemFlag, const bool visibleState)
{
if (infoItemFlag == visibleState)
{
return;
}
infoItemFlag = visibleState;
this->_UpdateHUDString();
this->FrameProcessHUD();
}
void ClientDisplayView::Init()
{
// Do nothing. This is implementation dependent.
}
double ClientDisplayView::GetScaleFactor() const
{
return this->_scaleFactor;
}
void ClientDisplayView::SetScaleFactor(const double scaleFactor)
{
this->_scaleFactor = scaleFactor;
const bool willChangeScaleFactor = (this->_scaleFactor != scaleFactor);
if (willChangeScaleFactor)
{
this->_glyphTileSize = (double)HUD_TEXTBOX_BASEGLYPHSIZE * scaleFactor;
this->_glyphSize = (double)this->_glyphTileSize * 0.75;
this->SetHUDFontUsingPath(this->_lastFontFilePath);
}
}
void ClientDisplayView::_UpdateViewScale()
{
double checkWidth = this->_renderProperty.normalWidth;
double checkHeight = this->_renderProperty.normalHeight;
ClientDisplayView::ConvertNormalToTransformedBounds(1.0, this->_renderProperty.rotation, checkWidth, checkHeight);
this->_renderProperty.viewScale = ClientDisplayView::GetMaxScalarWithinBounds(checkWidth, checkHeight, this->_renderProperty.clientWidth, this->_renderProperty.clientHeight);
this->_hudObjectScale = this->_renderProperty.clientWidth / this->_renderProperty.normalWidth;
if (this->_hudObjectScale > 2.0)
{
// If the view scale is <= 2.0, we scale the HUD objects linearly. Otherwise, we scale
// the HUD objects logarithmically, up to a maximum scale of 3.0.
this->_hudObjectScale = ( -1.0/((1.0/12000.0)*pow(this->_hudObjectScale+4.5438939, 5.0)) ) + 3.0;
}
}
// NDS screen layout
const ClientDisplayViewProperties& ClientDisplayView::GetViewProperties() const
{
return this->_renderProperty;
}
void ClientDisplayView::CommitViewProperties(const ClientDisplayViewProperties &props)
{
this->_stagedProperty = props;
}
void ClientDisplayView::SetupViewProperties()
{
// Validate the staged properties.
this->_stagedProperty.gapDistance = (double)DS_DISPLAY_UNSCALED_GAP * this->_stagedProperty.gapScale;
ClientDisplayView::CalculateNormalSize(this->_stagedProperty.mode, this->_stagedProperty.layout, this->_stagedProperty.gapScale, this->_stagedProperty.normalWidth, this->_stagedProperty.normalHeight);
const bool didNormalSizeChange = (this->_renderProperty.mode != this->_stagedProperty.mode) ||
(this->_renderProperty.layout != this->_stagedProperty.layout) ||
(this->_renderProperty.gapScale != this->_stagedProperty.gapScale);
const bool didOrderChange = (this->_renderProperty.order != this->_stagedProperty.order);
const bool didRotationChange = (this->_renderProperty.rotation != this->_stagedProperty.rotation);
const bool didClientSizeChange = (this->_renderProperty.clientWidth != this->_stagedProperty.clientWidth) || (this->_renderProperty.clientHeight != this->_stagedProperty.clientHeight);
// Copy the staged properties to the current rendering properties.
this->_renderProperty = this->_stagedProperty;
// Update internal states based on the new render properties
this->_UpdateViewScale();
if (didNormalSizeChange)
{
this->_UpdateNormalSize();
}
if (didOrderChange)
{
this->_UpdateOrder();
}
if (didRotationChange)
{
this->_UpdateRotation();
}
if (didClientSizeChange)
{
this->_UpdateClientSize();
}
}
double ClientDisplayView::GetRotation() const
{
return this->_property.rotation;
}
void ClientDisplayView::SetRotation(const double r)
{
this->_property.rotation = r;
double checkWidth = this->_property.normalWidth;
double checkHeight = this->_property.normalHeight;
ClientDisplayView::ConvertNormalToTransformedBounds(1.0, r, checkWidth, checkHeight);
this->_property.viewScale = ClientDisplayView::GetMaxScalarWithinBounds(checkWidth, checkHeight, this->_property.clientWidth, this->_property.clientHeight);
return this->_renderProperty.rotation;
}
double ClientDisplayView::GetViewScale() const
{
return this->_property.viewScale;
return this->_renderProperty.viewScale;
}
ClientDisplayMode ClientDisplayView::GetMode() const
{
return this->_property.mode;
}
void ClientDisplayView::SetMode(const ClientDisplayMode mode)
{
this->_property.mode = mode;
ClientDisplayView::CalculateNormalSize(this->_property.mode, this->_property.layout, this->_property.gapScale, this->_property.normalWidth, this->_property.normalHeight);
this->_property.viewScale = ClientDisplayView::GetMaxScalarWithinBounds(this->_property.normalWidth, this->_property.normalHeight, this->_property.clientWidth, this->_property.clientHeight);
return this->_renderProperty.mode;
}
ClientDisplayLayout ClientDisplayView::GetLayout() const
{
return this->_property.layout;
}
void ClientDisplayView::SetLayout(const ClientDisplayLayout layout)
{
this->_property.layout = layout;
ClientDisplayView::CalculateNormalSize(this->_property.mode, this->_property.layout, this->_property.gapScale, this->_property.normalWidth, this->_property.normalHeight);
this->_property.viewScale = ClientDisplayView::GetMaxScalarWithinBounds(this->_property.normalWidth, this->_property.normalHeight, this->_property.clientWidth, this->_property.clientHeight);
return this->_renderProperty.layout;
}
ClientDisplayOrder ClientDisplayView::GetOrder() const
{
return this->_property.order;
}
void ClientDisplayView::SetOrder(const ClientDisplayOrder order)
{
this->_property.order = order;
return this->_renderProperty.order;
}
double ClientDisplayView::GetGapScale() const
{
return this->_property.gapScale;
}
void ClientDisplayView::SetGapWithScalar(const double gapScale)
{
this->_property.gapScale = gapScale;
this->_property.gapDistance = (double)DS_DISPLAY_UNSCALED_GAP * gapScale;
return this->_renderProperty.gapScale;
}
double ClientDisplayView::GetGapDistance() const
{
return this->_property.gapDistance;
return this->_renderProperty.gapDistance;
}
void ClientDisplayView::SetGapWithDistance(const double gapDistance)
// NDS screen filters
bool ClientDisplayView::GetSourceDeposterize()
{
this->_property.gapScale = gapDistance / (double)DS_DISPLAY_UNSCALED_GAP;
this->_property.gapDistance = gapDistance;
return this->_useDeposterize;
}
void ClientDisplayView::SetSourceDeposterize(const bool useDeposterize)
{
this->_useDeposterize = useDeposterize;
}
OutputFilterTypeID ClientDisplayView::GetOutputFilter() const
{
return this->_outputFilter;
}
void ClientDisplayView::SetOutputFilter(const OutputFilterTypeID filterID)
{
this->_outputFilter = filterID;
}
VideoFilterTypeID ClientDisplayView::GetPixelScaler() const
{
return this->_pixelScaler;
}
void ClientDisplayView::SetPixelScaler(const VideoFilterTypeID filterID)
{
this->_pixelScaler = filterID;
}
// HUD appearance
void ClientDisplayView::SetHUDFontUsingPath(const char *filePath)
{
FT_Face fontFace;
FT_Error error = FT_Err_Ok;
error = FT_New_Face(this->_ftLibrary, filePath, 0, &fontFace);
if (error == FT_Err_Unknown_File_Format)
{
printf("ClientDisplayView: FreeType failed to load font face because it is in an unknown format from:\n%s\n", filePath);
return;
}
else if (error)
{
printf("ClientDisplayView: FreeType failed to load font face with an unknown error from:\n%s\n", filePath);
return;
}
this->CopyHUDFont(fontFace, this->_glyphSize, this->_glyphTileSize, this->_glyphInfo);
FT_Done_Face(fontFace);
this->_lastFontFilePath = filePath;
}
void ClientDisplayView::CopyHUDFont(const FT_Face &fontFace, const size_t glyphSize, const size_t glyphTileSize, GlyphInfo *glyphInfo)
{
// Do nothing. This is implementation dependent.
}
void ClientDisplayView::SetHUDInfo(const NDSFrameInfo &frameInfo)
{
this->_frameInfo = frameInfo;
this->_UpdateHUDString();
}
const std::string& ClientDisplayView::GetHUDString() const
{
return this->_hudString;
}
float ClientDisplayView::GetHUDObjectScale() const
{
return this->_hudObjectScale;
}
void ClientDisplayView::SetHUDObjectScale(float objectScale)
{
this->_hudObjectScale = objectScale;
}
bool ClientDisplayView::GetHUDVisibility() const
{
return this->_isHUDVisible;
}
void ClientDisplayView::SetHUDVisibility(const bool visibleState)
{
this->_isHUDVisible = visibleState;
}
bool ClientDisplayView::GetHUDShowVideoFPS() const
{
return this->_showVideoFPS;
}
void ClientDisplayView::SetHUDShowVideoFPS(const bool visibleState)
{
this->_SetHUDShowInfoItem(this->_showVideoFPS, visibleState);
}
bool ClientDisplayView::GetHUDShowRender3DFPS() const
{
return this->_showRender3DFPS;
}
void ClientDisplayView::SetHUDShowRender3DFPS(const bool visibleState)
{
this->_SetHUDShowInfoItem(this->_showRender3DFPS, visibleState);
}
bool ClientDisplayView::GetHUDShowFrameIndex() const
{
return this->_showFrameIndex;
}
void ClientDisplayView::SetHUDShowFrameIndex(const bool visibleState)
{
this->_SetHUDShowInfoItem(this->_showFrameIndex, visibleState);
}
bool ClientDisplayView::GetHUDShowLagFrameCount() const
{
return this->_showLagFrameCount;
}
void ClientDisplayView::SetHUDShowLagFrameCount(const bool visibleState)
{
this->_SetHUDShowInfoItem(this->_showLagFrameCount, visibleState);
}
bool ClientDisplayView::GetHUDShowCPULoadAverage() const
{
return this->_showCPULoadAverage;
}
void ClientDisplayView::SetHUDShowCPULoadAverage(const bool visibleState)
{
this->_SetHUDShowInfoItem(this->_showCPULoadAverage, visibleState);
}
bool ClientDisplayView::GetHUDShowRTC() const
{
return this->_showRTC;
}
void ClientDisplayView::SetHUDShowRTC(const bool visibleState)
{
this->_SetHUDShowInfoItem(this->_showRTC, visibleState);
}
// Touch screen input handling
void ClientDisplayView::GetNDSPoint(const int inputID, const bool isInitialTouchPress,
const double clientX, const double clientY,
u8 &outX, u8 &outY) const
{
double x = clientX;
double y = clientY;
double w = this->_property.normalWidth;
double h = this->_property.normalHeight;
double w = this->_renderProperty.normalWidth;
double h = this->_renderProperty.normalHeight;
ClientDisplayView::ConvertNormalToTransformedBounds(1.0, this->_property.rotation, w, h);
const double s = ClientDisplayView::GetMaxScalarWithinBounds(w, h, this->_property.clientWidth, this->_property.clientHeight);
ClientDisplayView::ConvertNormalToTransformedBounds(1.0, this->_renderProperty.rotation, w, h);
const double s = ClientDisplayView::GetMaxScalarWithinBounds(w, h, this->_renderProperty.clientWidth, this->_renderProperty.clientHeight);
ClientDisplayView::ConvertClientToNormalPoint(this->_property.normalWidth, this->_property.normalHeight,
this->_property.clientWidth, this->_property.clientHeight,
ClientDisplayView::ConvertClientToNormalPoint(this->_renderProperty.normalWidth, this->_renderProperty.normalHeight,
this->_renderProperty.clientWidth, this->_renderProperty.clientHeight,
s,
this->_property.rotation,
this->_renderProperty.rotation,
x, y);
// Normalize the touch location to the DS.
if (this->_property.mode == ClientDisplayMode_Dual)
if (this->_renderProperty.mode == ClientDisplayMode_Dual)
{
switch (this->_property.layout)
switch (this->_renderProperty.layout)
{
case ClientDisplayLayout_Horizontal:
{
if (this->_property.order == ClientDisplayOrder_MainFirst)
if (this->_renderProperty.order == ClientDisplayOrder_MainFirst)
{
x -= GPU_FRAMEBUFFER_NATIVE_WIDTH;
}
@ -178,14 +463,14 @@ void ClientDisplayView::GetNDSPoint(const int inputID, const bool isInitialTouch
{
if (isInitialTouchPress)
{
const bool isClickWithinMajorDisplay = (this->_property.order == ClientDisplayOrder_TouchFirst) && (x >= 0.0) && (x < 256.0);
const bool isClickWithinMajorDisplay = (this->_renderProperty.order == ClientDisplayOrder_TouchFirst) && (x >= 0.0) && (x < 256.0);
(*_initialTouchInMajorDisplay)[inputID] = isClickWithinMajorDisplay;
}
const bool handleClickInMajorDisplay = (*_initialTouchInMajorDisplay)[inputID];
if (!handleClickInMajorDisplay)
{
const double minorDisplayScale = (this->_property.normalWidth - (double)GPU_FRAMEBUFFER_NATIVE_WIDTH) / (double)GPU_FRAMEBUFFER_NATIVE_WIDTH;
const double minorDisplayScale = (this->_renderProperty.normalWidth - (double)GPU_FRAMEBUFFER_NATIVE_WIDTH) / (double)GPU_FRAMEBUFFER_NATIVE_WIDTH;
x = (x - GPU_FRAMEBUFFER_NATIVE_WIDTH) / minorDisplayScale;
y = y / minorDisplayScale;
}
@ -194,9 +479,9 @@ void ClientDisplayView::GetNDSPoint(const int inputID, const bool isInitialTouch
default: // Default to vertical orientation.
{
if (this->_property.order == ClientDisplayOrder_TouchFirst)
if (this->_renderProperty.order == ClientDisplayOrder_TouchFirst)
{
y -= ((double)GPU_FRAMEBUFFER_NATIVE_HEIGHT + this->_property.gapDistance);
y -= ((double)GPU_FRAMEBUFFER_NATIVE_HEIGHT + this->_renderProperty.gapDistance);
}
break;
}
@ -506,3 +791,45 @@ void ClientDisplayView::CalculateNormalSize(const ClientDisplayMode mode, const
outHeight = (double)GPU_FRAMEBUFFER_NATIVE_HEIGHT;
}
}
ClientDisplay3DView::ClientDisplay3DView()
{
_canFilterOnGPU = false;
_willFilterOnGPU = false;
_filtersPreferGPU = false;
}
bool ClientDisplay3DView::CanFilterOnGPU() const
{
return this->_canFilterOnGPU;
}
bool ClientDisplay3DView::WillFilterOnGPU() const
{
return this->_willFilterOnGPU;
}
bool ClientDisplay3DView::GetFiltersPreferGPU() const
{
return this->_filtersPreferGPU;
}
void ClientDisplay3DView::SetFiltersPreferGPU(const bool preferGPU)
{
this->_filtersPreferGPU = preferGPU;
}
void ClientDisplay3DView::SetSourceDeposterize(bool useDeposterize)
{
this->_useDeposterize = (this->_canFilterOnGPU) ? useDeposterize : false;
}
void ClientDisplay3DView::SetVideoBuffers(const uint32_t colorFormat,
const void *videoBufferHead,
const void *nativeBuffer0,
const void *nativeBuffer1,
const void *customBuffer0, const size_t customWidth0, const size_t customHeight0,
const void *customBuffer1, const size_t customWidth1, const size_t customHeight1)
{
// Do nothing. This is implementation dependent.
}

View File

@ -19,8 +19,18 @@
#define _CLIENT_DISPLAY_VIEW_H_
#include <map>
#include <string>
#include "../../filter/videofilter.h"
#include "../../GPU.h"
#include <ft2build.h>
#include FT_FREETYPE_H
#define HUD_MAX_CHARACTERS 2048
#define HUD_TEXTBOX_BASEGLYPHSIZE 64.0
#define HUD_TEXTBOX_BASE_SCALE (1.0/3.0)
#define HUD_TEXTBOX_MIN_SCALE 0.70
#define DS_DISPLAY_VERTICAL_GAP_TO_HEIGHT_RATIO (21.0/46.0) // Based on the official DS specification: 21mm/46mm
#define DS_DISPLAY_UNSCALED_GAP (GPU_FRAMEBUFFER_NATIVE_HEIGHT * DS_DISPLAY_VERTICAL_GAP_TO_HEIGHT_RATIO)
@ -46,58 +56,165 @@ enum ClientDisplayOrder
ClientDisplayOrder_TouchFirst
};
enum OutputFilterTypeID
{
OutputFilterTypeID_NearestNeighbor = 0,
OutputFilterTypeID_Bilinear = 1,
OutputFilterTypeID_BicubicBSpline = 2,
OutputFilterTypeID_BicubicMitchell = 3,
OutputFilterTypeID_Lanczos2 = 4,
OutputFilterTypeID_Lanczos3 = 5
};
typedef std::map<int, bool> InitialTouchPressMap; // Key = An ID number of the host input, Value = Flag that indicates if the initial touch press was in the major display
typedef struct
struct GlyphInfo
{
float width;
float texCoord[8];
};
typedef struct GlyphInfo GlyphInfo;
struct NDSFrameInfo
{
uint32_t videoFPS;
uint32_t render3DFPS;
uint32_t frameIndex;
uint32_t lagFrameCount;
uint32_t cpuLoadAvgARM9;
uint32_t cpuLoadAvgARM7;
char rtcString[25];
};
typedef struct NDSFrameInfo NDSFrameInfo;
struct ClientDisplayViewProperties
{
double normalWidth;
double normalHeight;
double clientWidth;
double clientHeight;
double rotation;
double viewScale;
double gapScale;
double gapDistance;
ClientDisplayMode mode;
ClientDisplayLayout layout;
ClientDisplayOrder order;
} ClientDisplayViewProperties;
double gapScale;
double rotation;
double clientWidth;
double clientHeight;
double normalWidth;
double normalHeight;
double viewScale;
double gapDistance;
};
typedef struct ClientDisplayViewProperties ClientDisplayViewProperties;
class ClientDisplayView
{
private:
void __InstanceInit(const ClientDisplayViewProperties &props);
protected:
ClientDisplayViewProperties _property;
ClientDisplayViewProperties _renderProperty;
ClientDisplayViewProperties _stagedProperty;
InitialTouchPressMap *_initialTouchInMajorDisplay;
bool _useDeposterize;
VideoFilterTypeID _pixelScaler;
OutputFilterTypeID _outputFilter;
double _scaleFactor;
double _hudObjectScale;
bool _isHUDVisible;
bool _showVideoFPS;
bool _showRender3DFPS;
bool _showFrameIndex;
bool _showLagFrameCount;
bool _showCPULoadAverage;
bool _showRTC;
NDSFrameInfo _frameInfo;
std::string _hudString;
FT_Library _ftLibrary;
const char *_lastFontFilePath;
GlyphInfo _glyphInfo[256];
size_t _glyphSize;
size_t _glyphTileSize;
void _UpdateHUDString();
void _SetHUDShowInfoItem(bool &infoItemFlag, const bool visibleState);
virtual void _UpdateNormalSize() = 0;
virtual void _UpdateOrder() = 0;
virtual void _UpdateRotation() = 0;
virtual void _UpdateClientSize() = 0;
virtual void _UpdateViewScale();
public:
ClientDisplayView();
ClientDisplayView(const ClientDisplayViewProperties props);
~ClientDisplayView();
ClientDisplayView(const ClientDisplayViewProperties &props);
virtual ~ClientDisplayView();
ClientDisplayViewProperties GetProperties() const;
void SetProperties(const ClientDisplayViewProperties properties);
virtual void Init();
void SetClientSize(const double w, const double h);
double GetScaleFactor() const;
virtual void SetScaleFactor(const double scaleFactor);
// NDS screen layout
const ClientDisplayViewProperties& GetViewProperties() const;
void CommitViewProperties(const ClientDisplayViewProperties &props);
virtual void SetupViewProperties();
double GetRotation() const;
void SetRotation(const double r);
double GetViewScale() const;
ClientDisplayMode GetMode() const;
void SetMode(const ClientDisplayMode mode);
ClientDisplayLayout GetLayout() const;
void SetLayout(const ClientDisplayLayout layout);
ClientDisplayOrder GetOrder() const;
void SetOrder(const ClientDisplayOrder order);
double GetGapScale() const;
void SetGapWithScalar(const double gapScale);
double GetGapDistance() const;
void SetGapWithDistance(const double gapDistance);
// NDS screen filters
bool GetSourceDeposterize();
virtual void SetSourceDeposterize(const bool useDeposterize);
OutputFilterTypeID GetOutputFilter() const;
virtual void SetOutputFilter(const OutputFilterTypeID filterID);
VideoFilterTypeID GetPixelScaler() const;
virtual void SetPixelScaler(const VideoFilterTypeID filterID);
// HUD appearance
void SetHUDFontUsingPath(const char *filePath);
virtual void CopyHUDFont(const FT_Face &fontFace, const size_t glyphSize, const size_t glyphTileSize, GlyphInfo *glyphInfo);
virtual void SetHUDInfo(const NDSFrameInfo &frameInfo);
const std::string& GetHUDString() const;
float GetHUDObjectScale() const;
virtual void SetHUDObjectScale(float objectScale);
bool GetHUDVisibility() const;
virtual void SetHUDVisibility(const bool visibleState);
bool GetHUDShowVideoFPS() const;
virtual void SetHUDShowVideoFPS(const bool visibleState);
bool GetHUDShowRender3DFPS() const;
virtual void SetHUDShowRender3DFPS(const bool visibleState);
bool GetHUDShowFrameIndex() const;
virtual void SetHUDShowFrameIndex(const bool visibleState);
bool GetHUDShowLagFrameCount() const;
virtual void SetHUDShowLagFrameCount(const bool visibleState);
bool GetHUDShowCPULoadAverage() const;
virtual void SetHUDShowCPULoadAverage(const bool visibleState);
bool GetHUDShowRTC() const;
virtual void SetHUDShowRTC(const bool visibleState);
// NDS GPU interface
virtual void FrameLoadGPU(bool isMainSizeNative, bool isTouchSizeNative) = 0;
virtual void FrameProcessGPU() = 0;
virtual void FrameProcessHUD() = 0;
virtual void FrameRender() = 0;
virtual void FrameFinish() = 0;
// Touch screen input handling
void GetNDSPoint(const int inputID, const bool isInitialTouchPress,
const double clientX, const double clientY,
u8 &outX, u8 &outY) const;
// Utility methods
static void ConvertNormalToTransformedBounds(const double scalar,
const double angleDegrees,
double &inoutWidth, double &inoutHeight);
@ -115,4 +232,34 @@ public:
double &outWidth, double &outHeight);
};
class ClientDisplay3DView : public ClientDisplayView
{
protected:
bool _canFilterOnGPU;
bool _willFilterOnGPU;
bool _filtersPreferGPU;
public:
ClientDisplay3DView();
bool CanFilterOnGPU() const;
bool GetFiltersPreferGPU() const;
virtual void SetFiltersPreferGPU(const bool preferGPU);
bool WillFilterOnGPU() const;
virtual void SetSourceDeposterize(const bool useDeposterize);
virtual void SetVideoBuffers(const uint32_t colorFormat,
const void *videoBufferHead,
const void *nativeBuffer0,
const void *nativeBuffer1,
const void *customBuffer0, const size_t customWidth0, const size_t customHeight0,
const void *customBuffer1, const size_t customWidth1, const size_t customHeight1) = 0;
virtual void FrameFlush() = 0;
virtual void FrameRenderAndFlush() = 0;
virtual void UpdateView() = 0;
};
#endif // _CLIENT_DISPLAY_VIEW_H_

File diff suppressed because it is too large Load Diff

View File

@ -23,6 +23,7 @@
#if defined(__APPLE__)
#include <OpenGL/gl.h>
#include <OpenGL/glext.h>
#include <OpenGL/OpenGL.h>
#endif
#endif // _OGLDISPLAYOUTPUT_3_2_H_
@ -33,28 +34,11 @@
#include "ClientDisplayView.h"
#include <ft2build.h>
#include FT_FREETYPE_H
#define HUD_MAX_CHARACTERS 2048
#define HUD_VERTEX_ATTRIBUTE_BUFFER_SIZE (sizeof(GLfloat) * HUD_MAX_CHARACTERS * (2 * 4))
#define HUD_TEXTBOX_BASEGLYPHSIZE 64.0
#define HUD_TEXTBOX_BASE_SCALE (1.0/3.0)
#define HUD_TEXTBOX_MIN_SCALE 0.70
class OGLVideoOutput;
struct NDSFrameInfo;
enum OutputFilterTypeID
{
OutputFilterTypeID_NearestNeighbor = 0,
OutputFilterTypeID_Bilinear = 1,
OutputFilterTypeID_BicubicBSpline = 2,
OutputFilterTypeID_BicubicMitchell = 3,
OutputFilterTypeID_Lanczos2 = 4,
OutputFilterTypeID_Lanczos3 = 5
};
enum ShaderSupportTier
{
ShaderSupport_Unsupported = 0,
@ -76,6 +60,7 @@ protected:
bool _useShader150;
bool _isVBOSupported;
bool _isVAOSupported;
bool _isPBOSupported;
bool _isFBOSupported;
@ -85,6 +70,7 @@ public:
bool IsUsingShader150();
bool IsVBOSupported();
bool IsVAOSupported();
bool IsPBOSupported();
bool IsShaderSupported();
bool IsFBOSupported();
@ -271,102 +257,49 @@ class OGLVideoLayer
protected:
OGLVideoOutput *_output;
bool _isVisible;
GLfloat _scaleFactor;
GLsizei _viewportWidth;
GLsizei _viewportHeight;
bool _needUpdateRotationScale;
bool _needUpdateVertices;
public:
virtual ~OGLVideoLayer() {};
virtual float GetScaleFactor();
virtual void SetScaleFactor(float scaleFactor);
void SetNeedsUpdateVertices();
virtual bool IsVisible();
virtual void SetVisibility(const bool visibleState);
virtual void SetViewportSizeOGL(GLsizei w, GLsizei h);
virtual void UpdateViewportOGL() {};
virtual void ProcessOGL() = 0;
virtual void RenderOGL() = 0;
virtual void FinishOGL() {};
};
typedef struct
{
GLfloat width;
GLfloat texCoord[8];
} GlyphInfo;
class OGLHUDLayer : public OGLVideoLayer
{
protected:
FT_Library _ftLibrary;
const char *_lastFontFilePath;
GLuint _texCharMap;
GlyphInfo _glyphInfo[256];
std::string _statusString;
size_t _glyphSize;
size_t _glyphTileSize;
OGLShaderProgram *_program;
bool _isVAOPresent;
bool _canUseShaderOutput;
GLint _uniformViewSize;
GLuint _vaoMainStatesID;
GLuint _vboVertexID;
GLuint _vboTexCoordID;
GLuint _vboElementID;
GLuint _texCharMap;
bool _showVideoFPS;
bool _showRender3DFPS;
bool _showFrameIndex;
bool _showLagFrameCount;
bool _showCPULoadAverage;
bool _showRTC;
uint32_t _lastVideoFPS;
uint32_t _lastRender3DFPS;
uint32_t _lastFrameIndex;
uint32_t _lastLagFrameCount;
uint32_t _lastCpuLoadAvgARM9;
uint32_t _lastCpuLoadAvgARM7;
char _lastRTCString[25];
GLfloat _hudObjectScale;
GlyphInfo *_glyphInfo;
GLfloat _glyphSize;
GLfloat _glyphTileSize;
void _SetShowInfoItemOGL(bool &infoItemFlag, const bool visibleState);
void _UpdateVerticesOGL();
public:
OGLHUDLayer(OGLVideoOutput *oglVO);
virtual ~OGLHUDLayer();
void SetFontUsingPath(const char *filePath);
void CopyHUDFont(const FT_Face &fontFace, const size_t glyphSize, const size_t glyphTileSize, GlyphInfo *glyphInfo);
void SetInfo(const uint32_t videoFPS, const uint32_t render3DFPS, const uint32_t frameIndex, const uint32_t lagFrameCount, const char *rtcString, const uint32_t cpuLoadAvgARM9, const uint32_t cpuLoadAvgARM7);
void RefreshInfo();
void SetObjectScale(float objectScale);
float GetObjectScale() const;
void SetShowVideoFPS(const bool visibleState);
bool GetShowVideoFPS() const;
void SetShowRender3DFPS(const bool visibleState);
bool GetShowRender3DFPS() const;
void SetShowFrameIndex(const bool visibleState);
bool GetShowFrameIndex() const;
void SetShowLagFrameCount(const bool visibleState);
bool GetShowLagFrameCount() const;
void SetShowCPULoadAverage(const bool visibleState);
bool GetShowCPULoadAverage() const;
void SetShowRTC(const bool visibleState);
bool GetShowRTC() const;
void ProcessVerticesOGL();
virtual void SetScaleFactor(float scaleFactor);
virtual void SetViewportSizeOGL(GLsizei w, GLsizei h);
virtual void UpdateViewportOGL();
virtual void ProcessOGL();
virtual void RenderOGL();
};
@ -374,19 +307,9 @@ public:
class OGLDisplayLayer : public OGLVideoLayer
{
protected:
bool _isVAOPresent;
bool _canUseShaderBasedFilters;
bool _canUseShaderOutput;
bool _useShader150;
ShaderSupportTier _shaderSupport;
GLboolean _useClientStorage;
bool _needUpdateVertices;
bool _useDeposterize;
bool _useShaderBasedPixelScaler;
bool _filtersPreferGPU;
int _outputFilter;
VideoFilterTypeID _pixelScaler;
OGLShaderProgram *_finalOutputProgram;
OGLFilter *_filterDeposterize[2];
@ -413,14 +336,6 @@ protected:
VideoFilter *_vf[2];
GLuint _texCPUFilterDstID[2];
ClientDisplayMode _displayMode;
ClientDisplayOrder _displayOrder;
ClientDisplayLayout _displayOrientation;
double _normalWidth;
double _normalHeight;
double _gapScalar;
double _rotation;
GLuint _texLQ2xLUT;
GLuint _texHQ2xLUT;
GLuint _texHQ3xLUT;
@ -438,9 +353,9 @@ protected:
void DetermineTextureStorageHints(GLint &videoSrcTexStorageHint, GLint &cpuFilterTexStorageHint);
void ResizeCPUPixelScalerOGL(const size_t srcWidthMain, const size_t srcHeightMain, const size_t srcWidthTouch, const size_t srcHeightTouch, const size_t scaleMultiply, const size_t scaleDivide);
void UploadTransformationOGL();
void UpdateVerticesOGL();
void _UpdateRotationScaleOGL();
void _UpdateVerticesOGL();
public:
OGLDisplayLayer() {};
@ -454,64 +369,100 @@ public:
const void *customBuffer0, const size_t customWidth0, const size_t customHeight0,
const void *customBuffer1, const size_t customWidth1, const size_t customHeight1);
bool GetFiltersPreferGPU();
void SetFiltersPreferGPUOGL(bool preferGPU);
ClientDisplayMode GetMode() const;
void SetMode(ClientDisplayMode dispMode);
ClientDisplayLayout GetOrientation() const;
void SetOrientation(ClientDisplayLayout dispOrientation);
ClientDisplayOrder GetOrder() const;
void SetOrder(ClientDisplayOrder dispOrder);
double GetGapScalar() const;
void SetGapScalar(double theScalar);
double GetRotation() const;
void SetRotation(double theRotation);
bool GetSourceDeposterize();
void SetSourceDeposterize(bool useDeposterize);
void SetNeedsUpdateRotationScale();
void SetFiltersPreferGPUOGL();
bool CanUseShaderBasedFilters();
void GetNormalSize(double &w, double &h) const;
int GetOutputFilter();
virtual void SetOutputFilterOGL(const int filterID);
int GetPixelScaler();
void SetPixelScalerOGL(const int filterID);
OutputFilterTypeID SetOutputFilterOGL(const OutputFilterTypeID filterID);
bool SetGPUPixelScalerOGL(const VideoFilterTypeID filterID);
void SetCPUPixelScalerOGL(const VideoFilterTypeID filterID);
void LoadFrameOGL(bool isMainSizeNative, bool isTouchSizeNative);
virtual void UpdateViewportOGL();
virtual void ProcessOGL();
virtual void RenderOGL();
virtual void FinishOGL();
};
class OGLVideoOutput
class OGLVideoOutput : public ClientDisplay3DView
{
protected:
OGLInfo *_info;
GLfloat _scaleFactor;
GLsizei _viewportWidth;
GLsizei _viewportHeight;
bool _needUpdateViewport;
std::vector<OGLVideoLayer *> *_layerList;
void _UpdateViewport();
virtual void _UpdateNormalSize();
virtual void _UpdateOrder();
virtual void _UpdateRotation();
virtual void _UpdateClientSize();
virtual void _UpdateViewScale();
public:
OGLVideoOutput();
~OGLVideoOutput();
void InitLayers();
OGLInfo* GetInfo();
float GetScaleFactor();
void SetScaleFactor(float scaleFactor);
GLsizei GetViewportWidth();
GLsizei GetViewportHeight();
OGLDisplayLayer* GetDisplayLayer();
OGLHUDLayer* GetHUDLayer();
virtual void Init();
virtual void SetOutputFilter(const OutputFilterTypeID filterID);
virtual void SetPixelScaler(const VideoFilterTypeID filterID);
virtual void CopyHUDFont(const FT_Face &fontFace, const size_t glyphSize, const size_t glyphTileSize, GlyphInfo *glyphInfo);
virtual void SetHUDVisibility(const bool visibleState);
virtual void SetFiltersPreferGPU(const bool preferGPU);
virtual void SetVideoBuffers(const uint32_t colorFormat,
const void *videoBufferHead,
const void *nativeBuffer0,
const void *nativeBuffer1,
const void *customBuffer0, const size_t customWidth0, const size_t customHeight0,
const void *customBuffer1, const size_t customWidth1, const size_t customHeight1);
virtual void FrameLoadGPU(bool isMainSizeNative, bool isTouchSizeNative);
virtual void FrameProcessGPU();
virtual void FrameProcessHUD();
virtual void FrameRender();
virtual void FrameFinish();
};
class MacOGLDisplayView : public OGLVideoOutput
{
protected:
CGLContextObj _context;
public:
MacOGLDisplayView(CGLContextObj context);
CGLContextObj GetContext() const;
void SetContext(CGLContextObj context);
void ProcessOGL();
void RenderOGL();
void SetViewportSizeOGL(GLsizei w, GLsizei h);
void FinishOGL();
virtual void SetHUDInfo(const NDSFrameInfo &frameInfo);
virtual void SetVideoBuffers(const uint32_t colorFormat,
const void *videoBufferHead,
const void *nativeBuffer0,
const void *nativeBuffer1,
const void *customBuffer0, const size_t customWidth0, const size_t customHeight0,
const void *customBuffer1, const size_t customWidth1, const size_t customHeight1);
virtual void FrameFinish();
virtual void FrameFlush();
virtual void FrameRenderAndFlush();
virtual void UpdateView();
};
OGLInfo* OGLInfoCreate_Legacy();

View File

@ -47,6 +47,7 @@ OGLInfo_3_2::OGLInfo_3_2()
{
_useShader150 = true;
_isVBOSupported = true;
_isVAOSupported = true;
_isPBOSupported = true;
_isFBOSupported = true;

View File

@ -21,6 +21,7 @@
#if defined(__APPLE__)
#include <OpenGL/gl3.h>
#include <OpenGL/gl3ext.h>
#include <OpenGL/OpenGL.h>
#endif
#include "OGLDisplayOutput.h"

View File

@ -45,19 +45,6 @@ typedef struct
pthread_rwlock_t rwlockCoreExecute;
} CoreThreadParam;
struct NDSFrameInfo
{
uint32_t videoFPS;
uint32_t render3DFPS;
uint32_t frameIndex;
uint32_t lagFrameCount;
uint32_t cpuLoadAvgARM9;
uint32_t cpuLoadAvgARM7;
char rtcString[25];
};
typedef struct NDSFrameInfo NDSFrameInfo;
@interface CocoaDSCore : NSObject
{
CocoaDSController *cdsController;

View File

@ -405,16 +405,11 @@ enum
// Video Messages
MESSAGE_RECEIVE_GPU_FRAME,
MESSAGE_RESIZE_VIEW,
MESSAGE_TRANSFORM_VIEW,
MESSAGE_CHANGE_VIEW_PROPERTIES,
MESSAGE_REDRAW_VIEW,
MESSAGE_RELOAD_AND_REDRAW,
MESSAGE_REPROCESS_AND_REDRAW,
MESSAGE_SET_GPU_STATE_FLAGS,
MESSAGE_CHANGE_DISPLAY_TYPE,
MESSAGE_CHANGE_DISPLAY_ORIENTATION,
MESSAGE_CHANGE_DISPLAY_ORDER,
MESSAGE_CHANGE_DISPLAY_GAP,
MESSAGE_SET_RENDER3D_METHOD,
MESSAGE_SET_RENDER3D_HIGH_PRECISION_COLOR_INTERPOLATION,
MESSAGE_SET_RENDER3D_EDGE_MARKING,

View File

@ -21,21 +21,14 @@
#include <libkern/OSAtomic.h>
#import "cocoa_util.h"
#include "ClientDisplayView.h"
#undef BOOL
@class NSImage;
@class NSBitmapImageRep;
struct NDSFrameInfo;
typedef struct
{
double scale;
double rotation; // Angle is in degrees
double translationX;
double translationY;
double translationZ;
} DisplayOutputTransformData;
@interface CocoaDSOutput : CocoaDSThread
{
NSMutableDictionary *property;
@ -106,7 +99,7 @@ typedef struct
@required
- (void) doFinishFrame;
- (void) doDisplayModeChanged:(NSInteger)displayModeID;
- (void) doViewPropertiesChanged;
@end
@ -131,12 +124,7 @@ typedef struct
- (void) doProcessVideoFrameWithInfo:(const NDSFrameInfo &)frameInfo;
@optional
- (void) doResizeView:(NSRect)rect;
- (void) doTransformView:(const DisplayOutputTransformData *)transformData;
- (void) doRedraw;
- (void) doDisplayOrientationChanged:(NSInteger)displayOrientationID;
- (void) doDisplayOrderChanged:(NSInteger)displayOrderID;
- (void) doDisplayGapChanged:(float)displayGapScalar;
@end
@ -145,7 +133,7 @@ typedef struct
{
id <CocoaDSDisplayDelegate> delegate;
NSSize displaySize;
NSInteger displayMode;
ClientDisplayMode displayMode;
uint32_t _receivedFrameIndex;
uint32_t _currentReceivedFrameIndex;
@ -161,11 +149,10 @@ typedef struct
@property (retain) id <CocoaDSDisplayDelegate> delegate;
@property (readonly) NSSize displaySize;
@property (assign) NSInteger displayMode;
@property (assign) ClientDisplayMode displayMode;
- (void) doReceiveGPUFrame;
- (void) handleReceiveGPUFrame;
- (void) handleChangeDisplayMode:(NSData *)displayModeData;
- (void) handleRequestScreenshot:(NSData *)fileURLStringData fileTypeData:(NSData *)fileTypeData;
- (void) handleCopyToPasteboard;
@ -185,14 +172,9 @@ typedef struct
}
- (void) handleReceiveGPUFrame;
- (void) handleResizeView:(NSData *)rectData;
- (void) handleTransformView:(NSData *)transformData;
- (void) handleRedrawView;
- (void) handleReloadAndRedraw;
- (void) handleReprocessAndRedraw;
- (void) handleChangeDisplayOrientation:(NSData *)displayOrientationIdData;
- (void) handleChangeDisplayOrder:(NSData *)displayOrderIdData;
- (void) handleChangeDisplayGap:(NSData *)displayGapScalarData;
- (void) resetVideoBuffers;

View File

@ -32,8 +32,6 @@
#include "../../metaspu/metaspu.h"
#include "../../rtc.h"
#include "OGLDisplayOutput.h"
#import <Cocoa/Cocoa.h>
#undef BOOL
@ -84,7 +82,6 @@
- (void)handlePortMessage:(NSPortMessage *)portMessage
{
NSInteger message = (NSInteger)[portMessage msgid];
NSArray *messageComponents = [portMessage components];
switch (message)
{
@ -553,7 +550,7 @@
return size;
}
- (void) setDisplayMode:(NSInteger)displayModeID
- (void) setDisplayMode:(ClientDisplayMode)displayModeID
{
NSString *newDispString = nil;
@ -583,10 +580,10 @@
OSSpinLockUnlock(&spinlockDisplayType);
}
- (NSInteger) displayMode
- (ClientDisplayMode) displayMode
{
OSSpinLockLock(&spinlockDisplayType);
NSInteger displayModeID = displayMode;
ClientDisplayMode displayModeID = displayMode;
OSSpinLockUnlock(&spinlockDisplayType);
return displayModeID;
@ -608,8 +605,8 @@
[self handleReceiveGPUFrame];
break;
case MESSAGE_CHANGE_DISPLAY_TYPE:
[self handleChangeDisplayMode:[messageComponents objectAtIndex:0]];
case MESSAGE_CHANGE_VIEW_PROPERTIES:
[self handleChangeViewProperties];
break;
case MESSAGE_REQUEST_SCREENSHOT:
@ -633,16 +630,9 @@
OSSpinLockUnlock(&spinlockReceivedFrameIndex);
}
- (void) handleChangeDisplayMode:(NSData *)displayModeData
- (void) handleChangeViewProperties
{
if (delegate == nil || ![delegate respondsToSelector:@selector(doDisplayModeChanged:)])
{
return;
}
const NSInteger displayModeID = *(NSInteger *)[displayModeData bytes];
[self setDisplayMode:displayModeID];
[(id<CocoaDSDisplayDelegate>)delegate doDisplayModeChanged:displayModeID];
[(id<CocoaDSDisplayDelegate>)delegate doViewPropertiesChanged];
}
- (void) handleRequestScreenshot:(NSData *)fileURLStringData fileTypeData:(NSData *)fileTypeData
@ -822,7 +812,6 @@
- (void)handlePortMessage:(NSPortMessage *)portMessage
{
NSInteger message = (NSInteger)[portMessage msgid];
NSArray *messageComponents = [portMessage components];
switch (message)
{
@ -834,30 +823,10 @@
[self handleReprocessAndRedraw];
break;
case MESSAGE_RESIZE_VIEW:
[self handleResizeView:[messageComponents objectAtIndex:0]];
break;
case MESSAGE_TRANSFORM_VIEW:
[self handleTransformView:[messageComponents objectAtIndex:0]];
break;
case MESSAGE_REDRAW_VIEW:
[self handleRedrawView];
break;
case MESSAGE_CHANGE_DISPLAY_ORIENTATION:
[self handleChangeDisplayOrientation:[messageComponents objectAtIndex:0]];
break;
case MESSAGE_CHANGE_DISPLAY_ORDER:
[self handleChangeDisplayOrder:[messageComponents objectAtIndex:0]];
break;
case MESSAGE_CHANGE_DISPLAY_GAP:
[self handleChangeDisplayGap:[messageComponents objectAtIndex:0]];
break;
default:
[super handlePortMessage:portMessage];
break;
@ -925,27 +894,6 @@
[(id<CocoaDSDisplayVideoDelegate>)delegate doLoadVideoFrameWithMainSizeNative:isMainSizeNative touchSizeNative:isTouchSizeNative];
}
- (void) handleResizeView:(NSData *)rectData
{
if (delegate == nil || ![delegate respondsToSelector:@selector(doResizeView:)])
{
return;
}
const NSRect resizeRect = *(NSRect *)[rectData bytes];
[(id<CocoaDSDisplayVideoDelegate>)delegate doResizeView:resizeRect];
}
- (void) handleTransformView:(NSData *)transformData
{
if (delegate == nil || ![delegate respondsToSelector:@selector(doTransformView:)])
{
return;
}
[(id<CocoaDSDisplayVideoDelegate>)delegate doTransformView:(DisplayOutputTransformData *)[transformData bytes]];
}
- (void) handleRedrawView
{
if (delegate == nil || ![delegate respondsToSelector:@selector(doRedraw)])
@ -967,39 +915,6 @@
[self handleEmuFrameProcessed];
}
- (void) handleChangeDisplayOrientation:(NSData *)displayOrientationIdData
{
if (delegate == nil || ![delegate respondsToSelector:@selector(doDisplayOrientationChanged:)])
{
return;
}
const NSInteger theOrientation = *(NSInteger *)[displayOrientationIdData bytes];
[(id<CocoaDSDisplayVideoDelegate>)delegate doDisplayOrientationChanged:theOrientation];
}
- (void) handleChangeDisplayOrder:(NSData *)displayOrderIdData
{
if (delegate == nil || ![delegate respondsToSelector:@selector(doDisplayOrderChanged:)])
{
return;
}
const NSInteger theOrder = *(NSInteger *)[displayOrderIdData bytes];
[(id<CocoaDSDisplayVideoDelegate>)delegate doDisplayOrderChanged:theOrder];
}
- (void) handleChangeDisplayGap:(NSData *)displayGapScalarData
{
if (delegate == nil || ![delegate respondsToSelector:@selector(doDisplayGapChanged:)])
{
return;
}
const float gapScalar = *(float *)[displayGapScalarData bytes];
[(id<CocoaDSDisplayVideoDelegate>)delegate doDisplayGapChanged:gapScalar];
}
- (void) resetVideoBuffers
{
const NDSDisplayInfo &dispInfo = GPU->GetDisplayInfo();

View File

@ -38,8 +38,8 @@ class OGLVideoOutput;
@interface DisplayView : NSView <CocoaDSDisplayVideoDelegate, InputHIDManagerTarget>
{
InputManager *inputManager;
ClientDisplayView *_cdv;
OGLVideoOutput *oglv;
ClientDisplay3DView *_cdv;
ClientDisplayViewProperties _intermediateViewProps;
BOOL canUseShaderBasedFilters;
BOOL _useVerticalSync;
@ -51,6 +51,8 @@ class OGLVideoOutput;
OSSpinLock spinlockSourceDeposterize;
OSSpinLock spinlockPixelScaler;
OSSpinLock spinlockViewProperties;
// OpenGL context
NSOpenGLContext *context;
CGLContextObj cglDisplayContext;
@ -72,7 +74,8 @@ class OGLVideoOutput;
@property (assign) NSInteger pixelScaler;
- (void) setScaleFactor:(float)theScaleFactor;
- (void) drawVideoFrame;
- (void) commitViewProperties:(const ClientDisplayViewProperties &)viewProps;
- (void) setupViewProperties;
- (BOOL) handleKeyPress:(NSEvent *)theEvent keyPressed:(BOOL)keyPressed;
- (BOOL) handleMouseButton:(NSEvent *)theEvent buttonPressed:(BOOL)buttonPressed;
- (void) requestScreenshot:(NSURL *)fileURL fileType:(NSBitmapImageFileType)fileType;
@ -138,6 +141,7 @@ class OGLVideoOutput;
@property (assign) NSScreen *assignedScreen;
@property (retain) NSWindow *masterWindow;
@property (readonly, nonatomic) BOOL isFullScreen;
@property (assign) double displayScale;
@property (assign) double displayRotation;
@property (assign) BOOL videoFiltersPreferGPU;
@ -154,10 +158,21 @@ class OGLVideoOutput;
- (id)initWithWindowNibName:(NSString *)windowNibName emuControlDelegate:(EmuControllerDelegate *)theEmuController;
- (ClientDisplayViewProperties &) localViewProperties;
- (void) setDisplayMode:(ClientDisplayMode)mode
layout:(ClientDisplayLayout)layout
order:(ClientDisplayOrder)order
rotation:(double)rotation
viewScale:(double)viewScale
gapScale:(double)gapScale
isMinSizeNormal:(BOOL)isMinSizeNormal
isShowingStatusBar:(BOOL)isShowingStatusBar;
- (void) setupUserDefaults;
- (BOOL) masterStatusBarState;
- (NSRect) masterWindowFrame;
- (double) masterWindowScale;
- (NSRect) updateViewProperties;
- (void) resizeWithTransform;
- (double) maxScalarForContentBoundsWidth:(double)contentBoundsWidth height:(double)contentBoundsHeight;
- (void) enterFullScreen;

View File

@ -59,6 +59,7 @@
@synthesize microphoneGainSlider;
@synthesize microphoneMuteButton;
@dynamic isFullScreen;
@dynamic displayScale;
@dynamic displayRotation;
@dynamic videoFiltersPreferGPU;
@ -152,6 +153,11 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
#pragma mark Dynamic Property Methods
- (BOOL) isFullScreen
{
return ([self assignedScreen] != nil);
}
- (void) setDisplayScale:(double)s
{
// There are two ways that this property is used:
@ -199,37 +205,29 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
// Convert angle to clockwise-direction degrees (left-handed Cartesian coordinate system).
_localViewProps.rotation = 360.0 - newAngleDegrees;
NSWindow *theWindow = [self window];
// Set the minimum content size for the window, since this will change based on rotation.
double contentMinWidth = _minDisplayViewSize.width;
double contentMinHeight = _minDisplayViewSize.height;
ClientDisplayView::ConvertNormalToTransformedBounds(1.0, _localViewProps.rotation, contentMinWidth, contentMinHeight);
contentMinHeight += _statusBarHeight;
[theWindow setContentMinSize:NSMakeSize(contentMinWidth, contentMinHeight)];
[self setIsMinSizeNormal:[self isMinSizeNormal]];
// Resize the window.
const NSSize oldBounds = [theWindow frame].size;
[self resizeWithTransform];
const NSSize newBounds = [theWindow frame].size;
// If the window size didn't change, it is possible that the old and new rotation angles
// are 180 degrees offset from each other. In this case, we'll need to force the
// display view to update itself.
if (oldBounds.width == newBounds.width && oldBounds.height == newBounds.height)
if ([self isFullScreen])
{
[view setNeedsDisplay:YES];
[view commitViewProperties:_localViewProps];
}
else
{
// Resize the window.
NSWindow *theWindow = [self window];
const NSSize oldBounds = [theWindow frame].size;
[self resizeWithTransform];
const NSSize newBounds = [theWindow frame].size;
// If the window size didn't change, it is possible that the old and new rotation angles
// are 180 degrees offset from each other. In this case, we'll need to force the
// display view to update itself.
if (oldBounds.width == newBounds.width && oldBounds.height == newBounds.height)
{
[view commitViewProperties:_localViewProps];
}
}
DisplayOutputTransformData transformData = { _localViewProps.viewScale,
_localViewProps.rotation,
0.0,
0.0,
0.0 };
[CocoaDSUtil messageSendOneWayWithData:[[self cdsVideoOutput] receivePort]
msgID:MESSAGE_TRANSFORM_VIEW
data:[NSData dataWithBytes:&transformData length:sizeof(DisplayOutputTransformData)]];
}
- (double) displayRotation
@ -243,35 +241,21 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
- (void) setDisplayMode:(NSInteger)displayModeID
{
NSString *modeString = @"Unknown";
switch (displayModeID)
{
case ClientDisplayMode_Main:
modeString = NSSTRING_DISPLAYMODE_MAIN;
break;
case ClientDisplayMode_Touch:
modeString = NSSTRING_DISPLAYMODE_TOUCH;
break;
case ClientDisplayMode_Dual:
modeString = NSSTRING_DISPLAYMODE_DUAL;
break;
default:
break;
}
OSSpinLockLock(&spinlockDisplayMode);
_localViewProps.mode = (ClientDisplayMode)displayModeID;
OSSpinLockUnlock(&spinlockDisplayMode);
ClientDisplayView::CalculateNormalSize((ClientDisplayMode)[self displayMode], (ClientDisplayLayout)[self displayOrientation], [self displayGap], _localViewProps.normalWidth, _localViewProps.normalHeight);
ClientDisplayView::CalculateNormalSize((ClientDisplayMode)displayModeID, (ClientDisplayLayout)[self displayOrientation], [self displayGap], _localViewProps.normalWidth, _localViewProps.normalHeight);
[self setIsMinSizeNormal:[self isMinSizeNormal]];
[self resizeWithTransform];
[CocoaDSUtil messageSendOneWayWithInteger:[[self cdsVideoOutput] receivePort] msgID:MESSAGE_CHANGE_DISPLAY_TYPE integerValue:displayModeID];
if ([self isFullScreen])
{
[view commitViewProperties:_localViewProps];
}
else if ([self displayMode] == ClientDisplayMode_Dual)
{
[self resizeWithTransform];
}
}
- (NSInteger) displayMode
@ -289,15 +273,17 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
_localViewProps.layout = (ClientDisplayLayout)theOrientation;
OSSpinLockUnlock(&spinlockDisplayOrientation);
ClientDisplayView::CalculateNormalSize((ClientDisplayMode)[self displayMode], (ClientDisplayLayout)[self displayOrientation], [self displayGap], _localViewProps.normalWidth, _localViewProps.normalHeight);
ClientDisplayView::CalculateNormalSize((ClientDisplayMode)[self displayMode], (ClientDisplayLayout)theOrientation, [self displayGap], _localViewProps.normalWidth, _localViewProps.normalHeight);
[self setIsMinSizeNormal:[self isMinSizeNormal]];
if ([self displayMode] == ClientDisplayMode_Dual)
if ([self isFullScreen])
{
[view commitViewProperties:_localViewProps];
}
else if ([self displayMode] == ClientDisplayMode_Dual)
{
[self resizeWithTransform];
}
[CocoaDSUtil messageSendOneWayWithInteger:[[self cdsVideoOutput] receivePort] msgID:MESSAGE_CHANGE_DISPLAY_ORIENTATION integerValue:theOrientation];
}
- (NSInteger) displayOrientation
@ -315,7 +301,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
_localViewProps.order = (ClientDisplayOrder)theOrder;
OSSpinLockUnlock(&spinlockDisplayOrder);
[CocoaDSUtil messageSendOneWayWithInteger:[[self cdsVideoOutput] receivePort] msgID:MESSAGE_CHANGE_DISPLAY_ORDER integerValue:theOrder];
[view commitViewProperties:_localViewProps];
}
- (NSInteger) displayOrder
@ -333,15 +319,31 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
_localViewProps.gapScale = gapScalar;
OSSpinLockUnlock(&spinlockDisplayGap);
ClientDisplayView::CalculateNormalSize((ClientDisplayMode)[self displayMode], (ClientDisplayLayout)[self displayOrientation], [self displayGap], _localViewProps.normalWidth, _localViewProps.normalHeight);
ClientDisplayView::CalculateNormalSize((ClientDisplayMode)[self displayMode], (ClientDisplayLayout)[self displayOrientation], gapScalar, _localViewProps.normalWidth, _localViewProps.normalHeight);
[self setIsMinSizeNormal:[self isMinSizeNormal]];
if ([self displayMode] == ClientDisplayMode_Dual)
if ([self isFullScreen])
{
[self resizeWithTransform];
[view commitViewProperties:_localViewProps];
}
else if ([self displayMode] == ClientDisplayMode_Dual)
{
switch ([self displayOrientation])
{
case ClientDisplayLayout_Hybrid_16_9:
case ClientDisplayLayout_Hybrid_16_10:
[view commitViewProperties:_localViewProps];
break;
case ClientDisplayLayout_Horizontal:
case ClientDisplayLayout_Hybrid_2_1:
break;
default:
[self resizeWithTransform];
break;
}
}
[CocoaDSUtil messageSendOneWayWithFloat:[[self cdsVideoOutput] receivePort] msgID:MESSAGE_CHANGE_DISPLAY_GAP floatValue:(float)gapScalar];
}
- (double) displayGap
@ -464,18 +466,75 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
#pragma mark Class Methods
- (ClientDisplayViewProperties &) localViewProperties
{
return _localViewProps;
}
- (void) setDisplayMode:(ClientDisplayMode)mode
layout:(ClientDisplayLayout)layout
order:(ClientDisplayOrder)order
rotation:(double)rotation
viewScale:(double)viewScale
gapScale:(double)gapScale
isMinSizeNormal:(BOOL)isMinSizeNormal
isShowingStatusBar:(BOOL)isShowingStatusBar
{
_statusBarHeight = (isShowingStatusBar) ? WINDOW_STATUS_BAR_HEIGHT : 0;
_localRotation = fmod(rotation, 360.0);
if (_localRotation < 0.0)
{
_localRotation = 360.0 + _localRotation;
}
if (_localRotation == 360.0)
{
_localRotation = 0.0;
}
_localViewProps.mode = mode;
_localViewProps.layout = layout;
_localViewProps.order = order;
_localViewProps.viewScale = viewScale;
_localViewProps.gapScale = gapScale;
_localViewProps.gapDistance = DS_DISPLAY_UNSCALED_GAP * gapScale;
_localViewProps.rotation = 360.0 - _localRotation;
ClientDisplayView::CalculateNormalSize(mode, layout, gapScale, _localViewProps.normalWidth, _localViewProps.normalHeight);
// Set the minimum content size.
_isMinSizeNormal = isMinSizeNormal;
_minDisplayViewSize.width = _localViewProps.normalWidth;
_minDisplayViewSize.height = _localViewProps.normalHeight;
if (!_isMinSizeNormal)
{
_minDisplayViewSize.width /= 4.0;
_minDisplayViewSize.height /= 4.0;
}
double transformedMinWidth = _minDisplayViewSize.width;
double transformedMinHeight = _minDisplayViewSize.height;
ClientDisplayView::ConvertNormalToTransformedBounds(1.0, _localViewProps.rotation, transformedMinWidth, transformedMinHeight);
[[self window] setContentMinSize:NSMakeSize(transformedMinWidth, transformedMinHeight + _statusBarHeight)];
// Set the client size and resize the windows.
NSRect newWindowFrame = [self updateViewProperties];
[masterWindow setFrame:newWindowFrame display:YES animate:NO];
}
- (void) setupUserDefaults
{
// Set the display window per user preferences.
[self setIsShowingStatusBar:[[NSUserDefaults standardUserDefaults] boolForKey:@"DisplayView_ShowStatusBar"]];
[self setDisplayMode:(ClientDisplayMode)[[NSUserDefaults standardUserDefaults] integerForKey:@"DisplayView_Mode"]
layout:(ClientDisplayLayout)[[NSUserDefaults standardUserDefaults] integerForKey:@"DisplayViewCombo_Orientation"]
order:(ClientDisplayOrder)[[NSUserDefaults standardUserDefaults] integerForKey:@"DisplayViewCombo_Order"]
rotation:[[NSUserDefaults standardUserDefaults] doubleForKey:@"DisplayView_Rotation"]
viewScale:([[NSUserDefaults standardUserDefaults] doubleForKey:@"DisplayView_Size"] / 100.0)
gapScale:([[NSUserDefaults standardUserDefaults] doubleForKey:@"DisplayViewCombo_Gap"] / 100.0)
isMinSizeNormal:[self isMinSizeNormal]
isShowingStatusBar:[[NSUserDefaults standardUserDefaults] boolForKey:@"DisplayView_ShowStatusBar"]];
// Set the display settings per user preferences.
[self setDisplayGap:([[NSUserDefaults standardUserDefaults] doubleForKey:@"DisplayViewCombo_Gap"] / 100.0)];
[self setDisplayMode:[[NSUserDefaults standardUserDefaults] integerForKey:@"DisplayView_Mode"]];
[self setDisplayOrientation:[[NSUserDefaults standardUserDefaults] integerForKey:@"DisplayViewCombo_Orientation"]];
[self setDisplayOrder:[[NSUserDefaults standardUserDefaults] integerForKey:@"DisplayViewCombo_Order"]];
[self setDisplayScale:([[NSUserDefaults standardUserDefaults] doubleForKey:@"DisplayView_Size"] / 100.0)];
[self setDisplayRotation:[[NSUserDefaults standardUserDefaults] doubleForKey:@"DisplayView_Rotation"]];
[self setVideoFiltersPreferGPU:[[NSUserDefaults standardUserDefaults] boolForKey:@"DisplayView_FiltersPreferGPU"]];
[self setVideoSourceDeposterize:[[NSUserDefaults standardUserDefaults] boolForKey:@"DisplayView_Deposterize"]];
[self setVideoOutputFilter:[[NSUserDefaults standardUserDefaults] integerForKey:@"DisplayView_OutputFilter"]];
@ -494,27 +553,22 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
- (BOOL) masterStatusBarState
{
return (([self assignedScreen] == nil) || !_useMavericksFullScreen) ? [self isShowingStatusBar] : _masterStatusBarState;
return (![self isFullScreen] || !_useMavericksFullScreen) ? [self isShowingStatusBar] : _masterStatusBarState;
}
- (NSRect) masterWindowFrame
{
return (([self assignedScreen] == nil) || !_useMavericksFullScreen) ? [masterWindow frame] : _masterWindowFrame;
return (![self isFullScreen] || !_useMavericksFullScreen) ? [masterWindow frame] : _masterWindowFrame;
}
- (double) masterWindowScale
{
return (([self assignedScreen] == nil) || !_useMavericksFullScreen) ? [self displayScale] : _masterWindowScale;
return (![self isFullScreen] || !_useMavericksFullScreen) ? [self displayScale] : _masterWindowScale;
}
- (void) resizeWithTransform
- (NSRect) updateViewProperties
{
if ([self assignedScreen] != nil)
{
return;
}
// Get the maximum scalar size within drawBounds. Constrain scalar to maxScalar if necessary.
// Get the maximum scalar size within drawBounds.
double checkWidth = _localViewProps.normalWidth;
double checkHeight = _localViewProps.normalHeight;
ClientDisplayView::ConvertNormalToTransformedBounds(1.0, _localViewProps.rotation, checkWidth, checkHeight);
@ -522,9 +576,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
const double constrainedScale = [self maxScalarForContentBoundsWidth:checkWidth height:checkHeight];
if (_localViewProps.viewScale > constrainedScale)
{
_isUpdatingDisplayScaleValueOnly = YES;
[self setDisplayScale:constrainedScale];
_isUpdatingDisplayScaleValueOnly = NO;
_localViewProps.viewScale = constrainedScale;
}
// Get the new bounds for the window's content view based on the transformed draw bounds.
@ -540,7 +592,22 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
// Resize the window.
const NSRect windowFrame = [masterWindow frame];
const NSRect newFrame = [masterWindow frameRectForContentRect:NSMakeRect(windowFrame.origin.x + translationX, windowFrame.origin.y + translationY, transformedWidth, transformedHeight + _statusBarHeight)];
[masterWindow setFrame:newFrame display:YES animate:NO];
_localViewProps.clientWidth = newFrame.size.width;
_localViewProps.clientHeight = newFrame.size.height;
return newFrame;
}
- (void) resizeWithTransform
{
if ([self isFullScreen])
{
return;
}
NSRect newWindowFrame = [self updateViewProperties];
[masterWindow setFrame:newWindowFrame display:YES animate:NO];
}
- (double) maxScalarForContentBoundsWidth:(double)contentBoundsWidth height:(double)contentBoundsHeight
@ -657,7 +724,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
{
// This method only applies for displays in full screen mode. For displays in
// windowed mode, we don't need to do anything.
if ([self assignedScreen] == nil)
if (![self isFullScreen])
{
return;
}
@ -797,13 +864,13 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
else
#endif
{
if ([self assignedScreen] == nil)
if ([self isFullScreen])
{
[self enterFullScreen];
[self exitFullScreen];
}
else
{
[self exitFullScreen];
[self enterFullScreen];
}
}
}
@ -1173,7 +1240,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
[(NSMenuItem *)theItem setTitle:([self isShowingStatusBar]) ? NSSTRING_TITLE_HIDE_STATUS_BAR : NSSTRING_TITLE_SHOW_STATUS_BAR];
}
if ([self assignedScreen] != nil)
if ([self isFullScreen])
{
enable = NO;
}
@ -1182,7 +1249,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
{
if ([(id)theItem isMemberOfClass:[NSMenuItem class]])
{
[(NSMenuItem *)theItem setTitle:([self assignedScreen] != nil) ? NSSTRING_TITLE_EXIT_FULL_SCREEN : NSSTRING_TITLE_ENTER_FULL_SCREEN];
[(NSMenuItem *)theItem setTitle:([self isFullScreen]) ? NSSTRING_TITLE_EXIT_FULL_SCREEN : NSSTRING_TITLE_ENTER_FULL_SCREEN];
}
}
else if (theAction == @selector(toggleKeepMinDisplaySizeAtNormal:))
@ -1192,7 +1259,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
[(NSMenuItem *)theItem setState:([self isMinSizeNormal]) ? NSOnState : NSOffState];
}
if ([self assignedScreen] != nil)
if ([self isFullScreen])
{
enable = NO;
}
@ -1262,7 +1329,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
- (NSSize)windowWillResize:(NSWindow *)sender toSize:(NSSize)frameSize
{
if ([self assignedScreen] != nil)
if ([self isFullScreen])
{
return frameSize;
}
@ -1290,7 +1357,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
- (void)windowDidResize:(NSNotification *)notification
{
if ([self assignedScreen] != nil)
if ([self isFullScreen])
{
return;
}
@ -1318,7 +1385,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
- (NSRect)windowWillUseStandardFrame:(NSWindow *)window defaultFrame:(NSRect)newFrame
{
if ([self assignedScreen] != nil)
if ([self isFullScreen])
{
return newFrame;
}
@ -1574,7 +1641,6 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
#endif
inputManager = nil;
_cdv = new ClientDisplayView();
// Initialize the OpenGL context
NSOpenGLPixelFormatAttribute attributes[] = {
@ -1614,18 +1680,13 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
CGLContextObj prevContext = CGLGetCurrentContext();
CGLSetCurrentContext(cglDisplayContext);
oglv = new OGLVideoOutput();
oglv->InitLayers();
_cdv = new MacOGLDisplayView(cglDisplayContext);
_cdv->Init();
NSString *fontPath = [[NSBundle mainBundle] pathForResource:@"SourceSansPro-Bold" ofType:@"otf"];
oglv->GetHUDLayer()->SetFontUsingPath([fontPath cStringUsingEncoding:NSUTF8StringEncoding]);
_cdv->SetHUDFontUsingPath([fontPath cStringUsingEncoding:NSUTF8StringEncoding]);
OGLDisplayLayer *displayLayer = oglv->GetDisplayLayer();
displayLayer->SetFiltersPreferGPUOGL(true);
displayLayer->SetSourceDeposterize(false);
displayLayer->SetOutputFilterOGL(OutputFilterTypeID_Bilinear);
displayLayer->SetPixelScalerOGL(VideoFilterTypeID_None);
canUseShaderBasedFilters = (displayLayer->CanUseShaderBasedFilters()) ? YES : NO;
canUseShaderBasedFilters = (_cdv->CanFilterOnGPU()) ? YES : NO;
CGLSetCurrentContext(prevContext);
@ -1638,6 +1699,8 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
spinlockSourceDeposterize = OS_SPINLOCK_INIT;
spinlockPixelScaler = OS_SPINLOCK_INIT;
spinlockViewProperties = OS_SPINLOCK_INIT;
return self;
}
@ -1645,10 +1708,9 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
{
CGLContextObj prevContext = CGLGetCurrentContext();
CGLSetCurrentContext(cglDisplayContext);
delete oglv;
delete _cdv;
CGLSetCurrentContext(prevContext);
delete _cdv;
[self setInputManager:nil];
[context clearDrawable];
[context release];
@ -1664,8 +1726,8 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
oglv->GetHUDLayer()->SetVisibility((theState) ? true : false);
[self drawVideoFrame];
_cdv->SetHUDVisibility((theState) ? true : false);
_cdv->FrameRenderAndFlush();
CGLUnlockContext(cglDisplayContext);
OSSpinLockUnlock(&spinlockIsHUDVisible);
@ -1674,7 +1736,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
- (BOOL) isHUDVisible
{
OSSpinLockLock(&spinlockIsHUDVisible);
const BOOL theState = (oglv->GetHUDLayer()->IsVisible()) ? YES : NO;
const BOOL theState = (_cdv->GetHUDVisibility()) ? YES : NO;
OSSpinLockUnlock(&spinlockIsHUDVisible);
return theState;
@ -1686,8 +1748,8 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
oglv->GetHUDLayer()->SetShowVideoFPS((theState) ? true : false);
[self drawVideoFrame];
_cdv->SetHUDShowVideoFPS((theState) ? true : false);
_cdv->FrameRenderAndFlush();
CGLUnlockContext(cglDisplayContext);
OSSpinLockUnlock(&spinlockIsHUDVisible);
@ -1696,7 +1758,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
- (BOOL) isHUDVideoFPSVisible
{
OSSpinLockLock(&spinlockIsHUDVisible);
const BOOL theState = (oglv->GetHUDLayer()->GetShowVideoFPS()) ? YES : NO;
const BOOL theState = (_cdv->GetHUDShowVideoFPS()) ? YES : NO;
OSSpinLockUnlock(&spinlockIsHUDVisible);
return theState;
@ -1708,8 +1770,8 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
oglv->GetHUDLayer()->SetShowRender3DFPS((theState) ? true : false);
[self drawVideoFrame];
_cdv->SetHUDShowRender3DFPS((theState) ? true : false);
_cdv->FrameRenderAndFlush();
CGLUnlockContext(cglDisplayContext);
OSSpinLockUnlock(&spinlockIsHUDVisible);
@ -1718,7 +1780,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
- (BOOL) isHUDRender3DFPSVisible
{
OSSpinLockLock(&spinlockIsHUDVisible);
const BOOL theState = (oglv->GetHUDLayer()->GetShowRender3DFPS()) ? YES : NO;
const BOOL theState = (_cdv->GetHUDShowRender3DFPS()) ? YES : NO;
OSSpinLockUnlock(&spinlockIsHUDVisible);
return theState;
@ -1730,8 +1792,8 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
oglv->GetHUDLayer()->SetShowFrameIndex((theState) ? true : false);
[self drawVideoFrame];
_cdv->SetHUDShowFrameIndex((theState) ? true : false);
_cdv->FrameRenderAndFlush();
CGLUnlockContext(cglDisplayContext);
OSSpinLockUnlock(&spinlockIsHUDVisible);
@ -1740,7 +1802,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
- (BOOL) isHUDFrameIndexVisible
{
OSSpinLockLock(&spinlockIsHUDVisible);
const BOOL theState = (oglv->GetHUDLayer()->GetShowFrameIndex()) ? YES : NO;
const BOOL theState = (_cdv->GetHUDShowFrameIndex()) ? YES : NO;
OSSpinLockUnlock(&spinlockIsHUDVisible);
return theState;
@ -1752,8 +1814,8 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
oglv->GetHUDLayer()->SetShowLagFrameCount((theState) ? true : false);
[self drawVideoFrame];
_cdv->SetHUDShowLagFrameCount((theState) ? true : false);
_cdv->FrameRenderAndFlush();
CGLUnlockContext(cglDisplayContext);
OSSpinLockUnlock(&spinlockIsHUDVisible);
@ -1762,7 +1824,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
- (BOOL) isHUDLagFrameCountVisible
{
OSSpinLockLock(&spinlockIsHUDVisible);
const BOOL theState = (oglv->GetHUDLayer()->GetShowLagFrameCount()) ? YES : NO;
const BOOL theState = (_cdv->GetHUDShowLagFrameCount()) ? YES : NO;
OSSpinLockUnlock(&spinlockIsHUDVisible);
return theState;
@ -1774,8 +1836,8 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
oglv->GetHUDLayer()->SetShowCPULoadAverage((theState) ? true : false);
[self drawVideoFrame];
_cdv->SetHUDShowCPULoadAverage((theState) ? true : false);
_cdv->FrameRenderAndFlush();
CGLUnlockContext(cglDisplayContext);
OSSpinLockUnlock(&spinlockIsHUDVisible);
@ -1784,7 +1846,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
- (BOOL) isHUDCPULoadAverageVisible
{
OSSpinLockLock(&spinlockIsHUDVisible);
const BOOL theState = (oglv->GetHUDLayer()->GetShowCPULoadAverage()) ? YES : NO;
const BOOL theState = (_cdv->GetHUDShowCPULoadAverage()) ? YES : NO;
OSSpinLockUnlock(&spinlockIsHUDVisible);
return theState;
@ -1796,8 +1858,8 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
oglv->GetHUDLayer()->SetShowRTC((theState) ? true : false);
[self drawVideoFrame];
_cdv->SetHUDShowRTC((theState) ? true : false);
_cdv->FrameRenderAndFlush();
CGLUnlockContext(cglDisplayContext);
OSSpinLockUnlock(&spinlockIsHUDVisible);
@ -1806,7 +1868,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
- (BOOL) isHUDRealTimeClockVisible
{
OSSpinLockLock(&spinlockIsHUDVisible);
const BOOL theState = (oglv->GetHUDLayer()->GetShowRTC()) ? YES : NO;
const BOOL theState = (_cdv->GetHUDShowRTC()) ? YES : NO;
OSSpinLockUnlock(&spinlockIsHUDVisible);
return theState;
@ -1841,7 +1903,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
oglv->GetDisplayLayer()->SetFiltersPreferGPUOGL((theState) ? true : false);
_cdv->SetFiltersPreferGPU((theState) ? true : false);
CGLUnlockContext(cglDisplayContext);
OSSpinLockUnlock(&spinlockVideoFiltersPreferGPU);
@ -1850,7 +1912,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
- (BOOL) videoFiltersPreferGPU
{
OSSpinLockLock(&spinlockVideoFiltersPreferGPU);
const BOOL theState = (oglv->GetDisplayLayer()->GetFiltersPreferGPU()) ? YES : NO;
const BOOL theState = (_cdv->GetFiltersPreferGPU()) ? YES : NO;
OSSpinLockUnlock(&spinlockVideoFiltersPreferGPU);
return theState;
@ -1859,14 +1921,14 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
- (void) setSourceDeposterize:(BOOL)theState
{
OSSpinLockLock(&spinlockSourceDeposterize);
oglv->GetDisplayLayer()->SetSourceDeposterize((theState) ? true : false);
_cdv->SetSourceDeposterize((theState) ? true : false);
OSSpinLockUnlock(&spinlockSourceDeposterize);
}
- (BOOL) sourceDeposterize
{
OSSpinLockLock(&spinlockSourceDeposterize);
const BOOL theState = (oglv->GetDisplayLayer()->GetSourceDeposterize()) ? YES : NO;
const BOOL theState = (_cdv->GetSourceDeposterize()) ? YES : NO;
OSSpinLockUnlock(&spinlockSourceDeposterize);
return theState;
@ -1878,7 +1940,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
oglv->GetDisplayLayer()->SetOutputFilterOGL(filterID);
_cdv->SetOutputFilter((OutputFilterTypeID)filterID);
CGLUnlockContext(cglDisplayContext);
OSSpinLockUnlock(&spinlockOutputFilter);
@ -1887,7 +1949,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
- (NSInteger) outputFilter
{
OSSpinLockLock(&spinlockOutputFilter);
const NSInteger filterID = oglv->GetDisplayLayer()->GetOutputFilter();
const NSInteger filterID = _cdv->GetOutputFilter();
OSSpinLockUnlock(&spinlockOutputFilter);
return filterID;
@ -1899,7 +1961,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
oglv->GetDisplayLayer()->SetPixelScalerOGL(filterID);
_cdv->SetPixelScaler((VideoFilterTypeID)filterID);
CGLUnlockContext(cglDisplayContext);
OSSpinLockUnlock(&spinlockPixelScaler);
@ -1908,7 +1970,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
- (NSInteger) pixelScaler
{
OSSpinLockLock(&spinlockPixelScaler);
const NSInteger filterID = oglv->GetDisplayLayer()->GetPixelScaler();
const NSInteger filterID = _cdv->GetPixelScaler();
OSSpinLockUnlock(&spinlockPixelScaler);
return filterID;
@ -1922,16 +1984,33 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
oglv->SetScaleFactor(theScaleFactor);
_cdv->SetScaleFactor(theScaleFactor);
CGLUnlockContext(cglDisplayContext);
OSSpinLockUnlock(&spinlockIsHUDVisible);
}
- (void) drawVideoFrame
- (void) commitViewProperties:(const ClientDisplayViewProperties &)viewProps
{
oglv->RenderOGL();
CGLFlushDrawable(cglDisplayContext);
OSSpinLockLock(&spinlockViewProperties);
_intermediateViewProps = viewProps;
OSSpinLockUnlock(&spinlockViewProperties);
DisplayWindowController *windowController = (DisplayWindowController *)[[self window] delegate];
[CocoaDSUtil messageSendOneWay:[[windowController cdsVideoOutput] receivePort] msgID:MESSAGE_CHANGE_VIEW_PROPERTIES];
}
- (void) setupViewProperties
{
OSSpinLockLock(&spinlockViewProperties);
_cdv->CommitViewProperties(_intermediateViewProps);
OSSpinLockUnlock(&spinlockViewProperties);
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
_cdv->SetupViewProperties();
_cdv->FrameRenderAndFlush();
CGLUnlockContext(cglDisplayContext);
}
#pragma mark InputHIDManagerTarget Protocol
@ -2081,7 +2160,11 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
#else
const NSRect newViewportRect = rect;
#endif
[CocoaDSUtil messageSendOneWayWithRect:[[windowController cdsVideoOutput] receivePort] msgID:MESSAGE_RESIZE_VIEW rect:newViewportRect];
ClientDisplayViewProperties &props = [windowController localViewProperties];
props.clientWidth = newViewportRect.size.width;
props.clientHeight = newViewportRect.size.height;
[self commitViewProperties:props];
}
}
@ -2198,12 +2281,10 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
- (void)doLoadVideoFrameWithMainSizeNative:(bool)isMainSizeNative touchSizeNative:(bool)isTouchSizeNative
{
OGLDisplayLayer *displayLayer = oglv->GetDisplayLayer();
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
displayLayer->LoadFrameOGL(isMainSizeNative, isTouchSizeNative);
displayLayer->ProcessOGL();
_cdv->FrameLoadGPU(isMainSizeNative, isTouchSizeNative);
_cdv->FrameProcessGPU();
CGLUnlockContext(cglDisplayContext);
}
@ -2218,139 +2299,32 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
customWidth1:(const size_t)customWidth1
customHeight1:(const size_t)customHeight1
{
OGLDisplayLayer *displayLayer = oglv->GetDisplayLayer();
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
displayLayer->SetVideoBuffers(colorFormat,
videoBufferHead,
nativeBuffer0,
nativeBuffer1,
customBuffer0, customWidth0, customHeight0,
customBuffer1, customWidth1, customHeight1);
CGLUnlockContext(cglDisplayContext);
_cdv->SetVideoBuffers(colorFormat,
videoBufferHead,
nativeBuffer0,
nativeBuffer1,
customBuffer0, customWidth0, customHeight0,
customBuffer1, customWidth1, customHeight1);
}
- (void)doFinishFrame
{
OGLDisplayLayer *displayLayer = oglv->GetDisplayLayer();
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
displayLayer->FinishOGL();
CGLUnlockContext(cglDisplayContext);
_cdv->FrameFinish();
}
- (void)doProcessVideoFrameWithInfo:(const NDSFrameInfo &)frameInfo
{
OGLHUDLayer *hudLayer = oglv->GetHUDLayer();
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
if (hudLayer->IsVisible())
{
hudLayer->SetInfo(frameInfo.videoFPS,
frameInfo.render3DFPS,
frameInfo.frameIndex,
frameInfo.lagFrameCount,
frameInfo.rtcString,
frameInfo.cpuLoadAvgARM9,
frameInfo.cpuLoadAvgARM7);
hudLayer->ProcessOGL();
}
[self drawVideoFrame];
CGLUnlockContext(cglDisplayContext);
_cdv->SetHUDInfo(frameInfo);
}
- (void)doResizeView:(NSRect)rect
- (void)doViewPropertiesChanged
{
const GLsizei w = (GLsizei)rect.size.width;
const GLsizei h = (GLsizei)rect.size.height;
_cdv->SetClientSize(rect.size.width, rect.size.height);
double hudObjectScale = _cdv->GetViewScale();
if (hudObjectScale > 2.0)
{
// If the view scale is <= 2.0, we scale the HUD objects linearly. Otherwise, we scale
// the HUD objects logarithmically, up to a maximum scale of 3.0.
hudObjectScale = ( -1.0/((1.0/12000.0)*pow(hudObjectScale+4.5438939, 5.0)) ) + 3.0;
}
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
oglv->SetViewportSizeOGL(w, h);
oglv->GetHUDLayer()->SetObjectScale(hudObjectScale);
oglv->GetHUDLayer()->ProcessVerticesOGL();
[self drawVideoFrame];
CGLUnlockContext(cglDisplayContext);
}
- (void)doTransformView:(const DisplayOutputTransformData *)transformData
{
_cdv->SetRotation(transformData->rotation);
OGLDisplayLayer *display = oglv->GetDisplayLayer();
display->SetRotation((GLfloat)transformData->rotation);
[self doRedraw];
[self setupViewProperties];
}
- (void)doRedraw
{
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
[self drawVideoFrame];
CGLUnlockContext(cglDisplayContext);
}
- (void)doDisplayModeChanged:(NSInteger)displayModeID
{
_cdv->SetMode((ClientDisplayMode)displayModeID);
OGLDisplayLayer *display = oglv->GetDisplayLayer();
display->SetMode((ClientDisplayMode)displayModeID);
[self doRedraw];
}
- (void)doDisplayOrientationChanged:(NSInteger)displayOrientationID
{
_cdv->SetLayout((ClientDisplayLayout)displayOrientationID);
OGLDisplayLayer *display = oglv->GetDisplayLayer();
display->SetOrientation((ClientDisplayLayout)displayOrientationID);
if (display->GetMode() == ClientDisplayMode_Dual)
{
[self doRedraw];
}
}
- (void)doDisplayOrderChanged:(NSInteger)displayOrderID
{
_cdv->SetOrder((ClientDisplayOrder)displayOrderID);
OGLDisplayLayer *display = oglv->GetDisplayLayer();
display->SetOrder((ClientDisplayOrder)displayOrderID);
if (display->GetMode() == ClientDisplayMode_Dual)
{
[self doRedraw];
}
}
- (void)doDisplayGapChanged:(float)displayGapScalar
{
_cdv->SetGapWithScalar(displayGapScalar);
OGLDisplayLayer *display = oglv->GetDisplayLayer();
display->SetGapScalar((GLfloat)displayGapScalar);
if (display->GetMode() == ClientDisplayMode_Dual)
{
[self doRedraw];
}
_cdv->UpdateView();
}
@end

View File

@ -32,8 +32,6 @@
#import "cocoa_rom.h"
#import "cocoa_slot2.h"
#include "../OGLDisplayOutput.h"
@implementation EmuControllerDelegate
@synthesize inputManager;

View File

@ -648,22 +648,26 @@
int frameX = 0;
int frameY = 0;
int frameWidth = 256;
int frameHeight = 192;
int frameHeight = 192*2;
const char *frameCStr = [windowFrameStr cStringUsingEncoding:NSUTF8StringEncoding];
sscanf(frameCStr, "%i %i %i %i", &frameX, &frameY, &frameWidth, &frameHeight);
[windowController setIsShowingStatusBar:isShowingStatusBar];
// Force the window to load now so that we can overwrite its internal defaults with the user's defaults.
[windowController window];
[windowController setDisplayMode:(ClientDisplayMode)displayMode
layout:(ClientDisplayLayout)displayOrientation
order:(ClientDisplayOrder)displayOrder
rotation:displayRotation
viewScale:displayScale
gapScale:displayGap
isMinSizeNormal:isMinSizeNormal
isShowingStatusBar:isShowingStatusBar];
[windowController setVideoFiltersPreferGPU:videoFiltersPreferGPU];
[windowController setVideoSourceDeposterize:videoSourceDeposterize];
[windowController setVideoPixelScaler:videoPixelScaler];
[windowController setVideoOutputFilter:videoOutputFilter];
[windowController setDisplayMode:displayMode];
[windowController setDisplayOrientation:displayOrientation];
[windowController setDisplayOrder:displayOrder];
[windowController setDisplayGap:displayGap];
[windowController setIsMinSizeNormal:isMinSizeNormal];
[windowController setDisplayRotation:displayRotation];
[windowController setDisplayScale:displayScale];
[windowController setScreenshotFileFormat:screenshotFileFormat];
[[windowController view] setUseVerticalSync:useVerticalSync];
[[windowController view] setIsHUDVisible:hudEnable];
@ -719,7 +723,6 @@
for (DisplayWindowController *windowController in windowList)
{
const BOOL isInFullScreenMode = ([windowController assignedScreen] != nil);
const NSUInteger screenIndex = [[NSScreen screens] indexOfObject:[[windowController masterWindow] screen]];
const NSRect windowFrame = [windowController masterWindowFrame];
@ -748,7 +751,7 @@
[NSNumber numberWithBool:[[windowController view] isHUDRealTimeClockVisible]], @"hudShowRTC",
[NSNumber numberWithBool:[windowController isMinSizeNormal]], @"isMinSizeNormal",
[NSNumber numberWithBool:[windowController masterStatusBarState]], @"isShowingStatusBar",
[NSNumber numberWithBool:isInFullScreenMode], @"isInFullScreenMode",
[NSNumber numberWithBool:[windowController isFullScreen]], @"isInFullScreenMode",
[NSNumber numberWithUnsignedInteger:screenIndex], @"screenIndex",
windowFrameStr, @"windowFrame",
nil];