Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow ruby to implement screen software rendering functions #1551

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion ares/ares/node/video/screen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,13 @@ auto Screen::pixels(bool frame) -> array_span<u32> {
auto Screen::resetPalette() -> void {
lock_guard<recursive_mutex> lock(_mutex);
_palette.reset();
platform->resetPalette(shared());
}

auto Screen::resetSprites() -> void {
lock_guard<recursive_mutex> lock(_mutex);
_sprites.reset();
platform->resetSprites(shared());
}

auto Screen::setRefresh(function<void ()> refresh) -> void {
Expand All @@ -78,7 +80,7 @@ auto Screen::refreshRateHint(double pixelFrequency, int dotsPerLine, int linesPe

auto Screen::refreshRateHint(double refreshRate) -> void {
lock_guard<recursive_mutex> lock(_mutex);
platform->refreshRateHint(refreshRate);
platform->refreshRateHint(shared(), refreshRate);
}

auto Screen::setViewport(u32 x, u32 y, u32 width, u32 height) -> void {
Expand All @@ -87,105 +89,123 @@ auto Screen::setViewport(u32 x, u32 y, u32 width, u32 height) -> void {
_viewportY = y;
_viewportWidth = width;
_viewportHeight = height;
platform->setViewport(shared(), x, y, width, height);
}

auto Screen::setOverscan(bool overscan) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_overscan = overscan;
platform->setOverscan(shared(), overscan);
}

auto Screen::setSize(u32 width, u32 height) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_width = width;
_height = height;
platform->setSize(shared(), width, height);
}

auto Screen::setScale(f64 scaleX, f64 scaleY) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_scaleX = scaleX;
_scaleY = scaleY;
platform->setScale(shared(), scaleX, scaleY);
}

auto Screen::setAspect(f64 aspectX, f64 aspectY) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_aspectX = aspectX;
_aspectY = aspectY;
platform->setAspect(shared(), aspectX, aspectY);
}

auto Screen::setSaturation(f64 saturation) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_saturation = saturation;
_palette.reset();
platform->setSaturation(shared(), saturation);
}

auto Screen::setGamma(f64 gamma) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_gamma = gamma;
_palette.reset();
platform->setGamma(shared(), gamma);
}

auto Screen::setLuminance(f64 luminance) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_luminance = luminance;
_palette.reset();
platform->setLuminance(shared(), luminance);
}

auto Screen::setFillColor(u32 fillColor) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_fillColor = fillColor;
platform->setFillColor(shared(), fillColor);
}

auto Screen::setColorBleed(bool colorBleed) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_colorBleed = colorBleed;
platform->setColorBleed(shared(), colorBleed);
}

auto Screen::setColorBleedWidth(u32 width) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_colorBleedWidth = width;
platform->setColorBleedWidth(shared(), width);
}

auto Screen::setInterframeBlending(bool interframeBlending) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_interframeBlending = interframeBlending;
platform->setInterframeBlending(shared(), interframeBlending);
}

auto Screen::setRotation(u32 rotation) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_rotation = rotation;
platform->setRotation(shared(), rotation);
}

auto Screen::setProgressive(bool progressiveDouble) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_interlace = false;
_progressive = true;
_progressiveDouble = progressiveDouble;
platform->setProgressive(shared(), progressiveDouble);
}

auto Screen::setInterlace(bool interlaceField) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_progressive = false;
_interlace = true;
_interlaceField = interlaceField;
platform->setInterlace(shared(), interlaceField);
}

auto Screen::attach(Node::Video::Sprite sprite) -> void {
lock_guard<recursive_mutex> lock(_mutex);
if(_sprites.find(sprite)) return;
_sprites.append(sprite);
platform->attachSprite(shared(), sprite);
}

auto Screen::detach(Node::Video::Sprite sprite) -> void {
lock_guard<recursive_mutex> lock(_mutex);
if(!_sprites.find(sprite)) return;
_sprites.removeByValue(sprite);
platform->detachSprite(shared(), sprite);
}

auto Screen::colors(u32 colors, function<n64 (n32)> color) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_colors = colors;
_color = color;
_palette.reset();
platform->colors(shared(), colors, color);
}

auto Screen::frame() -> void {
Expand Down Expand Up @@ -219,6 +239,13 @@ auto Screen::refresh() -> void {
auto width = _canvasWidth;
auto height = _canvasHeight;
auto input = _inputB.data();

if (!_usesSoftwareRendering) {
platform->video(shared(), input + viewX + viewY * width, width * sizeof(u32), viewWidth, viewHeight);
memory::fill<u32>(_inputB.data(), width * height, _fillColor);
return;
}

auto output = _output.data();

for(u32 y : range(height)) {
Expand Down
1 change: 1 addition & 0 deletions ares/ares/node/video/screen.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ struct Screen : Video {
auto refreshPalette() -> void;

protected:
bool _usesSoftwareRendering = true; //todo: add setting for this
u32 _canvasWidth = 0;
u32 _canvasHeight = 0;
u32 _width = 0;
Expand Down
23 changes: 22 additions & 1 deletion ares/ares/platform.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,28 @@ struct Platform {
virtual auto log(Node::Debugger::Tracer::Tracer, string_view message) -> void {}
virtual auto status(string_view message) -> void {}
virtual auto video(Node::Video::Screen, const u32* data, u32 pitch, u32 width, u32 height) -> void {}
virtual auto refreshRateHint(double refreshRate) -> void {}
virtual auto refreshRateHint(Node::Video::Screen, double refreshRate) -> void {}
virtual auto resetPalette(ares::Node::Video::Screen node) -> void {}
virtual auto resetSprites(ares::Node::Video::Screen node) -> void {}
virtual auto setViewport(ares::Node::Video::Screen node, u32 x, u32 y, u32 width, u32 height) -> void {}
virtual auto setOverscan(ares::Node::Video::Screen node, bool overscan) -> void {}
virtual auto setSize(ares::Node::Video::Screen node, u32 width, u32 height) -> void {}
virtual auto setScale(ares::Node::Video::Screen node, f64 scaleX, f64 scaleY) -> void {}
virtual auto setAspect(ares::Node::Video::Screen node, f64 aspectX, f64 aspectY) -> void {}
virtual auto setSaturation(ares::Node::Video::Screen node, f64 saturation) -> void {}
virtual auto setGamma(ares::Node::Video::Screen node, f64 gamma) -> void {}
virtual auto setLuminance(ares::Node::Video::Screen node, f64 luminance) -> void {}
virtual auto setFillColor(ares::Node::Video::Screen node, u32 fillColor) -> void {}
virtual auto setColorBleed(ares::Node::Video::Screen node, bool colorBleed) -> void {}
virtual auto setColorBleedWidth(ares::Node::Video::Screen node, u32 width) -> void {}
virtual auto setInterframeBlending(ares::Node::Video::Screen node, bool interframeBlending) -> void {}
virtual auto setRotation(ares::Node::Video::Screen node, u32 rotation) -> void {}
virtual auto setProgressive(ares::Node::Video::Screen node, bool progressiveDouble) -> void {}
virtual auto setInterlace(ares::Node::Video::Screen node, bool interlaceField) -> void {}
virtual auto attachSprite(ares::Node::Video::Screen node, ares::Node::Video::Sprite sprite) -> void {}
virtual auto detachSprite(ares::Node::Video::Screen node, ares::Node::Video::Sprite sprite) -> void {}
virtual auto colors(ares::Node::Video::Screen node, u32 colors, function<n64 (n32)> color) -> void {}

virtual auto audio(Node::Audio::Stream) -> void {}
virtual auto input(Node::Input::Input) -> void {}
virtual auto cheat(u32 addr) -> maybe<u32> { return nothing; }
Expand Down
4 changes: 0 additions & 4 deletions desktop-ui/program/platform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,6 @@ auto Program::video(ares::Node::Video::Screen node, const u32* data, u32 pitch,
}
}

auto Program::refreshRateHint(double refreshRate) -> void {
ruby::video.refreshRateHint(refreshRate);
}

auto Program::audio(ares::Node::Audio::Stream node) -> void {
if(!streams) return;

Expand Down
1 change: 1 addition & 0 deletions desktop-ui/program/program.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "status.cpp"
#include "utility.cpp"
#include "drivers.cpp"
#include "video.cpp"

Program program;

Expand Down
22 changes: 21 additions & 1 deletion desktop-ui/program/program.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,27 @@ struct Program : ares::Platform {
auto log(ares::Node::Debugger::Tracer::Tracer tracer, string_view message) -> void override;
auto status(string_view message) -> void override;
auto video(ares::Node::Video::Screen, const u32* data, u32 pitch, u32 width, u32 height) -> void override;
auto refreshRateHint(double refreshRate) -> void override;
auto refreshRateHint(ares::Node::Video::Screen node, double refreshRate) -> void override;
auto resetPalette(ares::Node::Video::Screen node) -> void override;
auto resetSprites(ares::Node::Video::Screen node) -> void override;
auto setViewport(ares::Node::Video::Screen node, u32 x, u32 y, u32 width, u32 height) -> void override;
auto setOverscan(ares::Node::Video::Screen node, bool overscan) -> void override;
auto setSize(ares::Node::Video::Screen node, u32 width, u32 height) -> void override;
auto setScale(ares::Node::Video::Screen node, f64 scaleX, f64 scaleY) -> void override;
auto setAspect(ares::Node::Video::Screen node, f64 aspectX, f64 aspectY) -> void override;
auto setSaturation(ares::Node::Video::Screen node, f64 saturation) -> void override;
auto setGamma(ares::Node::Video::Screen node, f64 gamma) -> void override;
auto setLuminance(ares::Node::Video::Screen node, f64 luminance) -> void override;
auto setFillColor(ares::Node::Video::Screen node, u32 fillColor) -> void override;
auto setColorBleed(ares::Node::Video::Screen node, bool colorBleed) -> void override;
auto setColorBleedWidth(ares::Node::Video::Screen node, u32 width) -> void override;
auto setInterframeBlending(ares::Node::Video::Screen node, bool interframeBlending) -> void override;
auto setRotation(ares::Node::Video::Screen node, u32 rotation) -> void override;
auto setProgressive(ares::Node::Video::Screen node, bool progressiveDouble) -> void override;
auto setInterlace(ares::Node::Video::Screen node, bool interlaceField) -> void override;
auto attachSprite(ares::Node::Video::Screen node, ares::Node::Video::Sprite sprite) -> void override;
auto detachSprite(ares::Node::Video::Screen node, ares::Node::Video::Sprite sprite) -> void override;
auto colors(ares::Node::Video::Screen node, u32 colors, function<n64 (n32)> color) -> void override;
auto audio(ares::Node::Audio::Stream) -> void override;
auto input(ares::Node::Input::Input) -> void override;
auto cheat(u32 address) -> maybe<u32> override;
Expand Down
83 changes: 83 additions & 0 deletions desktop-ui/program/video.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
auto Program::refreshRateHint(ares::Node::Video::Screen node, double refreshRate) -> void {
ruby::video.refreshRateHint(node, refreshRate);
}

auto Program::resetPalette(ares::Node::Video::Screen node) -> void {
ruby::video.resetPalette(node);
}

auto Program::resetSprites(ares::Node::Video::Screen node) -> void {
ruby::video.resetSprites(node);
}

auto Program::setViewport(ares::Node::Video::Screen node, u32 x, u32 y, u32 width, u32 height) -> void {
ruby::video.setViewport(node, x, y, width, height);
}

auto Program::setOverscan(ares::Node::Video::Screen node, bool overscan) -> void {
ruby::video.setOverscan(node, overscan);
}

auto Program::setSize(ares::Node::Video::Screen node, u32 width, u32 height) -> void {
ruby::video.setSize(node, width, height);
}

auto Program::setScale(ares::Node::Video::Screen node, f64 scaleX, f64 scaleY) -> void {
ruby::video.setScale(node, scaleX, scaleY);
}

auto Program::setAspect(ares::Node::Video::Screen node, f64 aspectX, f64 aspectY) -> void {
ruby::video.setAspect(node, aspectX, aspectY);
}

auto Program::setSaturation(ares::Node::Video::Screen node, f64 saturation) -> void {
ruby::video.setSaturation(node, saturation);
}

auto Program::setGamma(ares::Node::Video::Screen node, f64 gamma) -> void {
ruby::video.setGamma(node, gamma);
}

auto Program::setLuminance(ares::Node::Video::Screen node, f64 luminance) -> void {
ruby::video.setLuminance(node, luminance);
}

auto Program::setFillColor(ares::Node::Video::Screen node, u32 fillColor) -> void {
ruby::video.setFillColor(node, fillColor);
}

auto Program::setColorBleed(ares::Node::Video::Screen node, bool colorBleed) -> void {
ruby::video.setColorBleed(node, colorBleed);
}

auto Program::setColorBleedWidth(ares::Node::Video::Screen node, u32 width) -> void {
ruby::video.setColorBleedWidth(node, width);
}

auto Program::setInterframeBlending(ares::Node::Video::Screen node, bool interframeBlending) -> void {
ruby::video.setInterframeBlending(node, interframeBlending);
}

auto Program::setRotation(ares::Node::Video::Screen node, u32 rotation) -> void {
ruby::video.setRotation(node, rotation);
}

auto Program::setProgressive(ares::Node::Video::Screen node, bool progressiveDouble) -> void {
ruby::video.setProgressive(node, progressiveDouble);
}

auto Program::setInterlace(ares::Node::Video::Screen node, bool interlaceField) -> void {
ruby::video.setInterlace(node, interlaceField);
}

auto Program::attachSprite(ares::Node::Video::Screen node, ares::Node::Video::Sprite sprite) -> void {
ruby::video.attachSprite(node, sprite);
}

auto Program::detachSprite(ares::Node::Video::Screen node, ares::Node::Video::Sprite sprite) -> void {
ruby::video.detachSprite(node, sprite);
}

auto Program::colors(ares::Node::Video::Screen node, u32 colors, function<n64 (n32)> color) -> void {
ruby::video.colors(node, colors, color);
}
1 change: 1 addition & 0 deletions ruby/ruby.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <nall/vector.hpp>
#include <nall/dsp/resampler/cubic.hpp>
#include <nall/hash/crc32.hpp>
#include <ares/ares.hpp>

using nall::atomic;
using nall::function;
Expand Down
2 changes: 1 addition & 1 deletion ruby/video/metal/metal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ struct VideoMetal : VideoDriver, Metal {
return true;
}

auto refreshRateHint(double refreshRate) -> void override {
auto refreshRateHint(ares::Node::Video::Screen node, double refreshRate) -> void override {
if (refreshRate == _refreshRateHint) return;
_refreshRateHint = refreshRate;
updatePresentInterval();
Expand Down
2 changes: 1 addition & 1 deletion ruby/video/metal/metal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ struct Metal {
auto output() -> void;
auto initialize(const string& shader) -> bool;
auto terminate() -> void;
auto refreshRateHint(double refreshRate) -> void;
auto refreshRateHint(ares::Node::Video::Screen node, double refreshRate) -> void;

auto size(u32 width, u32 height) -> void;
auto release() -> void;
Expand Down
Loading