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:
Tim Allen
2019-01-02 10:52:08 +11:00
parent 3159285eaa
commit aaf094e7c4
115 changed files with 3319 additions and 1394 deletions

View 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

View 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

View File

@@ -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));
}

View File

@@ -10,4 +10,5 @@ namespace hiro {
#include "list-view.cpp"
#include "browser-dialog.cpp"
#include "message-dialog.cpp"
#include "about-dialog.cpp"
}

View File

@@ -8,4 +8,5 @@ namespace hiro {
#include "shared.hpp"
#include "browser-dialog.hpp"
#include "message-dialog.hpp"
#include "about-dialog.hpp"
}

View File

@@ -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();

View File

@@ -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;

View File

@@ -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; }

View File

@@ -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;
}

View File

@@ -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();

View File

@@ -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;