mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-09-01 03:13:17 +02:00
Update to v106r69 release.
byuu says: The biggest change was improving WonderSwan emulation. With help from trap15, I tracked down a bug where I was checking the wrong bit for reverse DMA transfers. Then I also emulated VTOTAL to support variable refresh rate. Then I improved HyperVoice emulation which should be unsigned samples in three of four modes. That got Fire Lancer running great. I also rewrote the disassembler. The old one disassembled many instructions completely wrong, and deviated too much from any known x86 syntax. I also emulated some of the quirks of the V30 (two-byte POP into registers fails, SALC is just XLAT mirrored, etc) which probably don't matter unless someone tries to run code to verify it's a NEC CPU and not an Intel CPU, but hey, why not? I also put more work into the MSX skeleton, but it's still just a skeleton with no real emulation yet.
This commit is contained in:
141
hiro/extension/about-dialog.cpp
Normal file
141
hiro/extension/about-dialog.cpp
Normal file
@@ -0,0 +1,141 @@
|
||||
#if defined(Hiro_AboutDialog)
|
||||
|
||||
auto AboutDialog::setAuthor(const string& author) -> type& {
|
||||
state.author = author;
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto AboutDialog::setDescription(const string& description) -> type& {
|
||||
state.description = description;
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto AboutDialog::setLicense(const string& license) -> type& {
|
||||
state.license = license;
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto AboutDialog::setLogo(const image& logo) -> type& {
|
||||
state.logo = logo;
|
||||
state.logo.transform();
|
||||
state.logo.alphaBlend(0xfffff0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto AboutDialog::setName(const string& name) -> type& {
|
||||
state.name = name;
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto AboutDialog::setParent(sWindow parent) -> type& {
|
||||
state.parent = parent;
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto AboutDialog::setVersion(const string& version) -> type& {
|
||||
state.version = version;
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto AboutDialog::setWebsite(const string& website) -> type& {
|
||||
state.website = website;
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto AboutDialog::show() -> void {
|
||||
Window window;
|
||||
window.onClose([&] { window.setModal(false); });
|
||||
|
||||
VerticalLayout layout{&window};
|
||||
layout.setPadding(5);
|
||||
|
||||
Label nameLabel{&layout, Size{~0, 0}};
|
||||
nameLabel.setCollapsible();
|
||||
nameLabel.setAlignment(0.5);
|
||||
nameLabel.setForegroundColor({0, 0, 0});
|
||||
nameLabel.setFont(Font().setFamily("Georgia").setBold().setSize(36.0));
|
||||
nameLabel.setText(state.name ? state.name : Application::name());
|
||||
nameLabel.setVisible(!state.logo);
|
||||
|
||||
Canvas logoCanvas{&layout, Size{~0, 0}};
|
||||
logoCanvas.setCollapsible();
|
||||
logoCanvas.setIcon(state.logo);
|
||||
logoCanvas.setVisible((bool)state.logo);
|
||||
|
||||
Label descriptionLabel{&layout, Size{~0, 0}};
|
||||
descriptionLabel.setCollapsible();
|
||||
descriptionLabel.setAlignment(0.5);
|
||||
descriptionLabel.setForegroundColor({0, 0, 0});
|
||||
descriptionLabel.setText(state.description);
|
||||
if(!state.description) descriptionLabel.setVisible(false);
|
||||
|
||||
HorizontalLayout versionLayout{&layout, Size{~0, 0}, 0};
|
||||
versionLayout.setCollapsible();
|
||||
Label versionLabel{&versionLayout, Size{~0, 0}, 3};
|
||||
versionLabel.setAlignment(1.0);
|
||||
versionLabel.setFont(Font().setBold());
|
||||
versionLabel.setForegroundColor({0, 0, 0});
|
||||
versionLabel.setText("Version:");
|
||||
Label versionValue{&versionLayout, Size{~0, 0}};
|
||||
versionValue.setAlignment(0.0);
|
||||
versionValue.setFont(Font().setBold());
|
||||
versionValue.setForegroundColor({0, 0, 0});
|
||||
versionValue.setText(state.version);
|
||||
if(!state.version) versionLayout.setVisible(false);
|
||||
|
||||
HorizontalLayout authorLayout{&layout, Size{~0, 0}, 0};
|
||||
authorLayout.setCollapsible();
|
||||
Label authorLabel{&authorLayout, Size{~0, 0}, 3};
|
||||
authorLabel.setAlignment(1.0);
|
||||
authorLabel.setFont(Font().setBold());
|
||||
authorLabel.setForegroundColor({0, 0, 0});
|
||||
authorLabel.setText("Author:");
|
||||
Label authorValue{&authorLayout, Size{~0, 0}};
|
||||
authorValue.setAlignment(0.0);
|
||||
authorValue.setFont(Font().setBold());
|
||||
authorValue.setForegroundColor({0, 0, 0});
|
||||
authorValue.setText(state.author);
|
||||
if(!state.author) authorLayout.setVisible(false);
|
||||
|
||||
HorizontalLayout licenseLayout{&layout, Size{~0, 0}, 0};
|
||||
licenseLayout.setCollapsible();
|
||||
Label licenseLabel{&licenseLayout, Size{~0, 0}, 3};
|
||||
licenseLabel.setAlignment(1.0);
|
||||
licenseLabel.setFont(Font().setBold());
|
||||
licenseLabel.setForegroundColor({0, 0, 0});
|
||||
licenseLabel.setText("License:");
|
||||
Label licenseValue{&licenseLayout, Size{~0, 0}};
|
||||
licenseValue.setAlignment(0.0);
|
||||
licenseValue.setFont(Font().setBold());
|
||||
licenseValue.setForegroundColor({0, 0, 0});
|
||||
licenseValue.setText(state.license);
|
||||
if(!state.license) licenseLayout.setVisible(false);
|
||||
|
||||
HorizontalLayout websiteLayout{&layout, Size{~0, 0}, 0};
|
||||
websiteLayout.setCollapsible();
|
||||
Label websiteLabel{&websiteLayout, Size{~0, 0}, 3};
|
||||
websiteLabel.setAlignment(1.0);
|
||||
websiteLabel.setFont(Font().setBold());
|
||||
websiteLabel.setForegroundColor({0, 0, 0});
|
||||
websiteLabel.setText("Website:");
|
||||
Label websiteValue{&websiteLayout, Size{~0, 0}};
|
||||
websiteValue.setAlignment(0.0);
|
||||
websiteValue.setFont(Font().setBold());
|
||||
websiteValue.setForegroundColor({0, 0, 240});
|
||||
websiteValue.setText(state.website);
|
||||
websiteValue.onMouseRelease([&](Mouse::Button button) {
|
||||
if(button == Mouse::Button::Left) invoke(state.website);
|
||||
});
|
||||
if(!state.website) websiteLayout.setVisible(false);
|
||||
|
||||
window.setTitle({"About ", state.name ? state.name : Application::name(), " ..."});
|
||||
window.setBackgroundColor({255, 255, 240});
|
||||
window.setSize({max(360, layout.minimumSize().width()), layout.minimumSize().height()});
|
||||
window.setResizable(false);
|
||||
window.setCentered(state.parent);
|
||||
window.setDismissable();
|
||||
window.setVisible();
|
||||
window.setModal();
|
||||
}
|
||||
|
||||
#endif
|
29
hiro/extension/about-dialog.hpp
Normal file
29
hiro/extension/about-dialog.hpp
Normal file
@@ -0,0 +1,29 @@
|
||||
#if defined(Hiro_AboutDialog)
|
||||
|
||||
struct AboutDialog {
|
||||
using type = AboutDialog;
|
||||
|
||||
auto setAuthor(const string& author = "") -> type&;
|
||||
auto setDescription(const string& description = "") -> type&;
|
||||
auto setLicense(const string& license = "") -> type&;
|
||||
auto setLogo(const image& logo = {}) -> type&;
|
||||
auto setName(const string& name = "") -> type&;
|
||||
auto setParent(sWindow parent = {}) -> type&;
|
||||
auto setVersion(const string& version = "") -> type&;
|
||||
auto setWebsite(const string& website = "") -> type&;
|
||||
auto show() -> void;
|
||||
|
||||
private:
|
||||
struct State {
|
||||
string author;
|
||||
string description;
|
||||
string license;
|
||||
image logo;
|
||||
string name;
|
||||
sWindow parent;
|
||||
string version;
|
||||
string website;
|
||||
} state;
|
||||
};
|
||||
|
||||
#endif
|
@@ -162,7 +162,7 @@ auto BrowserDialogWindow::run() -> BrowserDialog::Response {
|
||||
auto part = filter.split("|", 1L);
|
||||
filterList.append(ComboButtonItem().setText(part.left()));
|
||||
}
|
||||
optionList.setVisible((bool)state.options).onChange([&] { response.option = optionList.selected().text(); });
|
||||
optionList.setCollapsible().setVisible((bool)state.options).onChange([&] { response.option = optionList.selected().text(); });
|
||||
for(auto& option : state.options) {
|
||||
optionList.append(ComboButtonItem().setText(option));
|
||||
}
|
||||
|
@@ -10,4 +10,5 @@ namespace hiro {
|
||||
#include "list-view.cpp"
|
||||
#include "browser-dialog.cpp"
|
||||
#include "message-dialog.cpp"
|
||||
#include "about-dialog.cpp"
|
||||
}
|
||||
|
@@ -8,4 +8,5 @@ namespace hiro {
|
||||
#include "shared.hpp"
|
||||
#include "browser-dialog.hpp"
|
||||
#include "message-dialog.hpp"
|
||||
#include "about-dialog.hpp"
|
||||
}
|
||||
|
@@ -40,19 +40,23 @@ auto mHorizontalLayout::destruct() -> void {
|
||||
|
||||
auto mHorizontalLayout::minimumSize() const -> Size {
|
||||
float width = 0;
|
||||
float spacing = 0;
|
||||
for(auto index : range(cellCount())) {
|
||||
auto cell = this->cell(index);
|
||||
if(cell.collapsible()) continue;
|
||||
if(cell.size().width() == Size::Minimum || cell.size().width() == Size::Maximum) {
|
||||
width += cell.sizable().minimumSize().width();
|
||||
} else {
|
||||
width += cell.size().width();
|
||||
}
|
||||
if(index != cellCount() - 1) width += cell.spacing();
|
||||
width += spacing;
|
||||
spacing = cell.spacing();
|
||||
}
|
||||
|
||||
float height = 0;
|
||||
for(auto index : range(cellCount())) {
|
||||
auto cell = this->cell(index);
|
||||
if(cell.collapsible()) continue;
|
||||
if(cell.size().height() == Size::Minimum || cell.size().height() == Size::Maximum) {
|
||||
height = max(height, cell.sizable().minimumSize().height());
|
||||
continue;
|
||||
@@ -108,10 +112,10 @@ auto mHorizontalLayout::setFont(const Font& font) -> type& {
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto mHorizontalLayout::setGeometry(Geometry geometry) -> type& {
|
||||
mSizable::setGeometry(geometry);
|
||||
if(!visible(true)) return *this;
|
||||
auto mHorizontalLayout::setGeometry(Geometry requestedGeometry) -> type& {
|
||||
if(!visible(true)) return mSizable::setGeometry(requestedGeometry), *this;
|
||||
|
||||
auto geometry = requestedGeometry;
|
||||
geometry.setX(geometry.x() + padding().x());
|
||||
geometry.setY(geometry.y() + padding().y());
|
||||
geometry.setWidth (geometry.width() - padding().x() - padding().width());
|
||||
@@ -120,8 +124,9 @@ auto mHorizontalLayout::setGeometry(Geometry geometry) -> type& {
|
||||
vector<float> widths;
|
||||
widths.resize(cellCount());
|
||||
uint maximumWidths = 0;
|
||||
for(auto index : range(cellCount())) {
|
||||
for(uint index : range(cellCount())) {
|
||||
auto cell = this->cell(index);
|
||||
if(cell.collapsible()) continue;
|
||||
float width = 0;
|
||||
if(cell.size().width() == Size::Maximum) {
|
||||
width = Size::Maximum;
|
||||
@@ -135,9 +140,13 @@ auto mHorizontalLayout::setGeometry(Geometry geometry) -> type& {
|
||||
}
|
||||
|
||||
float fixedWidth = 0;
|
||||
for(uint index : range(state.cells.size())) {
|
||||
float spacing = 0;
|
||||
for(uint index : range(cellCount())) {
|
||||
auto cell = this->cell(index);
|
||||
if(cell.collapsible()) continue;
|
||||
if(widths[index] != Size::Maximum) fixedWidth += widths[index];
|
||||
if(index != cellCount() - 1) fixedWidth += cell(index).spacing();
|
||||
fixedWidth += spacing;
|
||||
spacing = cell.spacing();
|
||||
}
|
||||
|
||||
float maximumWidth = (geometry.width() - fixedWidth) / maximumWidths;
|
||||
@@ -146,8 +155,9 @@ auto mHorizontalLayout::setGeometry(Geometry geometry) -> type& {
|
||||
}
|
||||
|
||||
float height = 0;
|
||||
for(auto index : range(cellCount())) {
|
||||
for(uint index : range(cellCount())) {
|
||||
auto cell = this->cell(index);
|
||||
if(cell.collapsible()) continue;
|
||||
if(cell.size().height() == Size::Maximum) {
|
||||
height = geometry.height();
|
||||
break;
|
||||
@@ -160,10 +170,11 @@ auto mHorizontalLayout::setGeometry(Geometry geometry) -> type& {
|
||||
|
||||
float geometryX = geometry.x();
|
||||
float geometryY = geometry.y();
|
||||
for(auto index : range(cellCount())) {
|
||||
for(uint index : range(cellCount())) {
|
||||
auto cell = this->cell(index);
|
||||
if(cell.collapsible()) continue;
|
||||
float geometryWidth = widths[index];
|
||||
float geometryHeight = height;
|
||||
auto cell = this->cell(index);
|
||||
auto alignment = cell.alignment();
|
||||
if(!alignment) alignment = this->alignment();
|
||||
if(!alignment) alignment = 0.5;
|
||||
@@ -177,6 +188,7 @@ auto mHorizontalLayout::setGeometry(Geometry geometry) -> type& {
|
||||
geometryX += geometryWidth + cell.spacing();
|
||||
}
|
||||
|
||||
mSizable::setGeometry(requestedGeometry);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -218,6 +230,11 @@ auto mHorizontalLayoutCell::alignment() const -> maybe<float> {
|
||||
return state.alignment;
|
||||
}
|
||||
|
||||
auto mHorizontalLayoutCell::collapsible() const -> bool {
|
||||
if(state.sizable) return state.sizable->collapsible() && !state.sizable->visible();
|
||||
return false;
|
||||
}
|
||||
|
||||
auto mHorizontalLayoutCell::destruct() -> void {
|
||||
if(auto& sizable = state.sizable) sizable->destruct();
|
||||
mObject::destruct();
|
||||
|
@@ -49,6 +49,7 @@ struct mHorizontalLayoutCell : mObject {
|
||||
using type = mHorizontalLayoutCell;
|
||||
|
||||
auto alignment() const -> maybe<float>;
|
||||
auto collapsible() const -> bool;
|
||||
auto setAlignment(maybe<float> alignment) -> type&;
|
||||
auto setEnabled(bool enabled) -> type& override;
|
||||
auto setFont(const Font& font) -> type& override;
|
||||
|
@@ -26,6 +26,7 @@ struct HorizontalLayoutCell : sHorizontalLayoutCell {
|
||||
DeclareSharedObject(HorizontalLayoutCell)
|
||||
|
||||
auto alignment() const { return self().alignment(); }
|
||||
auto collapsible() const { return self().collapsible(); }
|
||||
auto setAlignment(maybe<float> alignment = {}) { return self().setAlignment(alignment), *this; }
|
||||
auto setSizable(sSizable sizable) { return self().setSizable(sizable), *this; }
|
||||
auto setSize(Size size) { return self().setSize(size), *this; }
|
||||
@@ -58,6 +59,7 @@ struct VerticalLayoutCell : sVerticalLayoutCell {
|
||||
DeclareSharedObject(VerticalLayoutCell)
|
||||
|
||||
auto alignment() const { return self().alignment(); }
|
||||
auto collapsible() const { return self().collapsible(); }
|
||||
auto setAlignment(maybe<float> alignment = {}) { return self().setAlignment(alignment), *this; }
|
||||
auto setSizable(sSizable sizable) { return self().setSizable(sizable), *this; }
|
||||
auto setSize(Size size) { return self().setSize(size), *this; }
|
||||
|
@@ -143,10 +143,10 @@ auto mTableLayout::setFont(const Font& font) -> type& {
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto mTableLayout::setGeometry(Geometry geometry) -> type& {
|
||||
mSizable::setGeometry(geometry);
|
||||
if(!visible(true)) return *this;
|
||||
auto mTableLayout::setGeometry(Geometry requestedGeometry) -> type& {
|
||||
if(!visible(true)) return mSizable::setGeometry(requestedGeometry), *this;
|
||||
|
||||
auto geometry = requestedGeometry;
|
||||
geometry.setX(geometry.x() + padding().x());
|
||||
geometry.setY(geometry.y() + padding().y());
|
||||
geometry.setWidth (geometry.width() - padding().x() - padding().width());
|
||||
@@ -250,6 +250,7 @@ auto mTableLayout::setGeometry(Geometry geometry) -> type& {
|
||||
geometryY += heights[y] + row.spacing();
|
||||
}
|
||||
|
||||
mSizable::setGeometry(requestedGeometry);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@@ -42,6 +42,7 @@ auto mVerticalLayout::minimumSize() const -> Size {
|
||||
float width = 0;
|
||||
for(auto index : range(cellCount())) {
|
||||
auto cell = this->cell(index);
|
||||
if(cell.collapsible()) continue;
|
||||
if(cell.size().width() == Size::Minimum || cell.size().width() == Size::Maximum) {
|
||||
width = max(width, cell.sizable().minimumSize().width());
|
||||
continue;
|
||||
@@ -50,14 +51,17 @@ auto mVerticalLayout::minimumSize() const -> Size {
|
||||
}
|
||||
|
||||
float height = 0;
|
||||
float spacing = 0;
|
||||
for(auto index : range(cellCount())) {
|
||||
auto cell = this->cell(index);
|
||||
if(cell.collapsible()) continue;
|
||||
if(cell.size().height() == Size::Minimum || cell.size().height() == Size::Maximum) {
|
||||
height += cell.sizable().minimumSize().height();
|
||||
} else {
|
||||
height += cell.size().height();
|
||||
}
|
||||
if(index != cellCount() - 1) height += cell.spacing();
|
||||
height += spacing;
|
||||
spacing = cell.spacing();
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -108,18 +112,19 @@ auto mVerticalLayout::setFont(const Font& font) -> type& {
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto mVerticalLayout::setGeometry(Geometry geometry) -> type& {
|
||||
mSizable::setGeometry(geometry);
|
||||
if(!visible(true)) return *this;
|
||||
auto mVerticalLayout::setGeometry(Geometry requestedGeometry) -> type& {
|
||||
if(!visible(true)) return mSizable::setGeometry(requestedGeometry), *this;
|
||||
|
||||
auto geometry = requestedGeometry;
|
||||
geometry.setX(geometry.x() + padding().x());
|
||||
geometry.setY(geometry.y() + padding().y());
|
||||
geometry.setWidth (geometry.width() - padding().x() - padding().width());
|
||||
geometry.setHeight(geometry.height() - padding().y() - padding().height());
|
||||
|
||||
float width = 0;
|
||||
for(auto index : range(cellCount())) {
|
||||
for(uint index : range(cellCount())) {
|
||||
auto cell = this->cell(index);
|
||||
if(cell.collapsible()) continue;
|
||||
if(cell.size().width() == Size::Maximum) {
|
||||
width = geometry.width();
|
||||
break;
|
||||
@@ -133,8 +138,9 @@ auto mVerticalLayout::setGeometry(Geometry geometry) -> type& {
|
||||
vector<float> heights;
|
||||
heights.resize(cellCount());
|
||||
uint maximumHeights = 0;
|
||||
for(auto index : range(cellCount())) {
|
||||
for(uint index : range(cellCount())) {
|
||||
auto cell = this->cell(index);
|
||||
if(cell.collapsible()) continue;
|
||||
float height = 0;
|
||||
if(cell.size().height() == Size::Maximum) {
|
||||
height = Size::Maximum;
|
||||
@@ -148,9 +154,13 @@ auto mVerticalLayout::setGeometry(Geometry geometry) -> type& {
|
||||
}
|
||||
|
||||
float fixedHeight = 0;
|
||||
for(uint index : range(state.cells.size())) {
|
||||
float spacing = 0;
|
||||
for(uint index : range(cellCount())) {
|
||||
auto cell = this->cell(index);
|
||||
if(cell.collapsible()) continue;
|
||||
if(heights[index] != Size::Maximum) fixedHeight += heights[index];
|
||||
if(index != cellCount() - 1) fixedHeight += cell(index).spacing();
|
||||
fixedHeight += spacing;
|
||||
spacing = cell.spacing();
|
||||
}
|
||||
|
||||
float maximumHeight = (geometry.height() - fixedHeight) / maximumHeights;
|
||||
@@ -160,10 +170,11 @@ auto mVerticalLayout::setGeometry(Geometry geometry) -> type& {
|
||||
|
||||
float geometryX = geometry.x();
|
||||
float geometryY = geometry.y();
|
||||
for(auto index : range(cellCount())) {
|
||||
for(uint index : range(cellCount())) {
|
||||
auto cell = this->cell(index);
|
||||
if(cell.collapsible()) continue;
|
||||
float geometryWidth = width;
|
||||
float geometryHeight = heights[index];
|
||||
auto cell = this->cell(index);
|
||||
auto alignment = cell.alignment();
|
||||
if(!alignment) alignment = this->alignment();
|
||||
if(!alignment) alignment = 0.0;
|
||||
@@ -177,6 +188,7 @@ auto mVerticalLayout::setGeometry(Geometry geometry) -> type& {
|
||||
geometryY += geometryHeight + cell.spacing();
|
||||
}
|
||||
|
||||
mSizable::setGeometry(requestedGeometry);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -218,6 +230,11 @@ auto mVerticalLayoutCell::alignment() const -> maybe<float> {
|
||||
return state.alignment;
|
||||
}
|
||||
|
||||
auto mVerticalLayoutCell::collapsible() const -> bool {
|
||||
if(state.sizable) return state.sizable->collapsible() && !state.sizable->visible();
|
||||
return false;
|
||||
}
|
||||
|
||||
auto mVerticalLayoutCell::destruct() -> void {
|
||||
if(auto& sizable = state.sizable) sizable->destruct();
|
||||
mObject::destruct();
|
||||
|
@@ -49,6 +49,7 @@ struct mVerticalLayoutCell : mObject {
|
||||
using type = mVerticalLayoutCell;
|
||||
|
||||
auto alignment() const -> maybe<float>;
|
||||
auto collapsible() const -> bool;
|
||||
auto setAlignment(maybe<float> alignment) -> type&;
|
||||
auto setEnabled(bool enabled) -> type& override;
|
||||
auto setFont(const Font& font) -> type& override;
|
||||
|
Reference in New Issue
Block a user