1
0
mirror of https://github.com/Swordfish90/cool-retro-term.git synced 2025-01-18 12:15:27 +00:00

Merge pull request #665 from Swordfish90/unstable

Improve rasterization and terminal frame. Some refactoring.
This commit is contained in:
Filippo Scognamiglio 2021-07-15 23:43:06 +02:00 committed by GitHub
commit cfe35d7795
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 1405 additions and 1087 deletions

View File

@ -1,9 +1,28 @@
/*******************************************************************************
* Copyright (c) 2013-2021 "Filippo Scognamiglio"
* https://github.com/Swordfish90/cool-retro-term
*
* This file is part of cool-retro-term.
*
* cool-retro-term is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
import QtQuick 2.2 import QtQuick 2.2
import QtQuick.Controls 2.2 import QtQuick.Controls 2.2
import QtQuick.Layouts 1.1 import QtQuick.Layouts 1.1
import QtQuick.Window 2.0 import QtQuick.Window 2.0
Window{ Window {
id: dialogwindow id: dialogwindow
title: qsTr("About") title: qsTr("About")
width: 600 width: 600
@ -11,16 +30,19 @@ Window{
modality: Qt.ApplicationModal modality: Qt.ApplicationModal
ColumnLayout{ ColumnLayout {
anchors.fill: parent anchors.fill: parent
anchors.margins: 15 anchors.margins: 15
spacing: 15 spacing: 15
Text { Text {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
text: "cool-retro-term" text: "cool-retro-term"
font {bold: true; pointSize: 18} font {
bold: true
pointSize: 18
}
} }
Loader{ Loader {
id: mainContent id: mainContent
Layout.fillHeight: true Layout.fillHeight: true
Layout.fillWidth: true Layout.fillWidth: true
@ -41,32 +63,33 @@ Window{
} }
} }
] ]
Component.onCompleted: mainContent.state = "Default"; Component.onCompleted: mainContent.state = "Default"
} }
Item{ Item {
Layout.fillWidth: true Layout.fillWidth: true
height: childrenRect.height height: childrenRect.height
Button{ Button {
anchors.left: parent.left anchors.left: parent.left
text: qsTr("License") text: qsTr("License")
onClicked: { onClicked: {
mainContent.state == "Default" ? mainContent.state = "License" : mainContent.state = "Default" mainContent.state == "Default" ? mainContent.state
= "License" : mainContent.state = "Default"
} }
} }
Button{ Button {
anchors.right: parent.right anchors.right: parent.right
text: qsTr("Close") text: qsTr("Close")
onClicked: dialogwindow.close(); onClicked: dialogwindow.close()
} }
} }
} }
// MAIN COMPONENTS //////////////////////////////////////////////////////// // MAIN COMPONENTS ////////////////////////////////////////////////////////
Component{ Component {
id: defaultComponent id: defaultComponent
ColumnLayout{ ColumnLayout {
anchors.fill: parent anchors.fill: parent
spacing: 10 spacing: 10
Image{ Image {
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
@ -74,39 +97,36 @@ Window{
source: "images/crt256.png" source: "images/crt256.png"
smooth: true smooth: true
} }
Text{ Text {
Layout.alignment: Qt.AlignCenter Layout.alignment: Qt.AlignCenter
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
text: appSettings.version + "\n" + text: appSettings.version + "\n" + qsTr(
qsTr("Author: ") + "Filippo Scognamiglio\n" + "Author: ") + "Filippo Scognamiglio\n" + qsTr(
qsTr("Email: ") + "flscogna@gmail.com\n" + "Email: ") + "flscogna@gmail.com\n" + qsTr(
qsTr("Source: ") + "https://github.com/Swordfish90/cool-retro-term\n" "Source: ") + "https://github.com/Swordfish90/cool-retro-term\n"
} }
} }
} }
Component{ Component {
id: licenseComponent id: licenseComponent
ScrollView { ScrollView {
anchors.fill: parent anchors.fill: parent
clip: true clip: true
TextArea{ TextArea {
readOnly: true readOnly: true
wrapMode: TextEdit.Wrap wrapMode: TextEdit.Wrap
text: "Copyright (c) 2013 Filippo Scognamiglio <flscogna@gmail.com>\n\n" + text: "Copyright (c) 2013-2021 Filippo Scognamiglio <flscogna@gmail.com>\n\n"
"https://github.com/Swordfish90/cool-retro-term\n\n" + + "https://github.com/Swordfish90/cool-retro-term\n\n" +
"cool-retro-term is free software: you can redistribute it and/or modify "
"cool-retro-term is free software: you can redistribute it and/or modify " + + "it under the terms of the GNU General Public License as published by "
"it under the terms of the GNU General Public License as published by " + + "the Free Software Foundation, either version 3 of the License, or "
"the Free Software Foundation, either version 3 of the License, or " + + "(at your option) any later version.\n\n" +
"(at your option) any later version.\n\n" + "This program is distributed in the hope that it will be useful, "
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of "
"This program is distributed in the hope that it will be useful, " + + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the "
"but WITHOUT ANY WARRANTY; without even the implied warranty of " + + "GNU General Public License for more details.\n\n" +
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the " + "You should have received a copy of the GNU General Public License "
"GNU General Public License for more details.\n\n" + + "along with this program. If not, see <http://www.gnu.org/licenses/>."
"You should have received a copy of the GNU General Public License " +
"along with this program. If not, see <http://www.gnu.org/licenses/>."
} }
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,22 @@
/*******************************************************************************
* Copyright (c) 2013-2021 "Filippo Scognamiglio"
* https://github.com/Swordfish90/cool-retro-term
*
* This file is part of cool-retro-term.
*
* cool-retro-term is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
import QtQuick 2.0 import QtQuick 2.0
import "utils.js" as Utils import "utils.js" as Utils
@ -70,6 +89,10 @@ Loader {
} }
} }
ShaderLibrary {
id: shaderLibrary
}
ShaderEffect { ShaderEffect {
id: burnInShaderEffect id: burnInShaderEffect
@ -99,9 +122,7 @@ Loader {
uniform highp float prevLastUpdate;" + uniform highp float prevLastUpdate;" +
"float rgb2grey(vec3 v){ shaderLibrary.rgb2grey +
return dot(v, vec3(0.21, 0.72, 0.04));
}" +
"void main() { "void main() {
vec2 coords = qt_TexCoord0; vec2 coords = qt_TexCoord0;

View File

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2013 "Filippo Scognamiglio" * Copyright (c) 2013-2021 "Filippo Scognamiglio"
* https://github.com/Swordfish90/cool-retro-term * https://github.com/Swordfish90/cool-retro-term
* *
* This file is part of cool-retro-term. * This file is part of cool-retro-term.
@ -17,7 +17,6 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/ *******************************************************************************/
import QtQuick 2.2 import QtQuick 2.2
import QtQuick.Controls 2.0 import QtQuick.Controls 2.0
import QtQuick.Layouts 1.1 import QtQuick.Layouts 1.1
@ -32,41 +31,42 @@ RowLayout {
property alias max_value: slider.to property alias max_value: slider.to
property alias stepSize: slider.stepSize property alias stepSize: slider.stepSize
signal newValue(real newValue); signal newValue(real newValue)
id: setting_component id: setting_component
Layout.fillWidth: true Layout.fillWidth: true
onValueChanged: { onValueChanged: {
check.checked = !(value == 0); check.checked = !(value == 0)
if(check.checked) if (check.checked)
slider.value = value; slider.value = value
} }
CheckBox{ CheckBox {
id: check id: check
implicitWidth: 160 implicitWidth: 160
onClicked: { onClicked: {
if(!checked){ if (!checked) {
checked = false; checked = false
slider.enabled = false; slider.enabled = false
newValue(0); newValue(0)
} else { } else {
checked = true; checked = true
newValue(slider.value); newValue(slider.value)
slider.enabled = true; slider.enabled = true
} }
} }
} }
Slider{ Slider {
id: slider id: slider
stepSize: parent.stepSize stepSize: parent.stepSize
Layout.fillWidth: true Layout.fillWidth: true
onValueChanged: { onValueChanged: {
newValue(value); newValue(value)
} }
} }
SizedLabel { SizedLabel {
text: Math.round(((value - min_value) / (max_value - min_value)) * 100) + "%" text: Math.round(
((value - min_value) / (max_value - min_value)) * 100) + "%"
} }
} }

View File

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2013 "Filippo Scognamiglio" * Copyright (c) 2013-2021 "Filippo Scognamiglio"
* https://github.com/Swordfish90/cool-retro-term * https://github.com/Swordfish90/cool-retro-term
* *
* This file is part of cool-retro-term. * This file is part of cool-retro-term.
@ -17,14 +17,13 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/ *******************************************************************************/
import QtQuick 2.2 import QtQuick 2.2
import QtQuick.Dialogs 1.1 import QtQuick.Dialogs 1.1
Item { Item {
id: rootItem id: rootItem
signal colorSelected (color color) signal colorSelected(color color)
property color color property color color
property string name property string name
@ -35,10 +34,12 @@ Item {
visible: false visible: false
//This is a workaround to a Qt 5.2 bug. //This is a workaround to a Qt 5.2 bug.
onColorChanged: if (Qt.platform.os !== "osx") colorSelected(color) onColorChanged: if (Qt.platform.os !== "osx")
onAccepted: if (Qt.platform.os === "osx") colorSelected(color) colorSelected(color)
onAccepted: if (Qt.platform.os === "osx")
colorSelected(color)
} }
Rectangle{ Rectangle {
anchors.fill: parent anchors.fill: parent
radius: 10 radius: 10
color: rootItem.color color: rootItem.color
@ -50,14 +51,14 @@ Item {
color: "white" color: "white"
opacity: 0.5 opacity: 0.5
} }
Text{ Text {
anchors.centerIn: parent anchors.centerIn: parent
z: parent.z + 1 z: parent.z + 1
text: name + ": " + rootItem.color text: name + ": " + rootItem.color
} }
} }
MouseArea{ MouseArea {
anchors.fill: parent anchors.fill: parent
onClicked: colorDialog.visible = true; onClicked: colorDialog.visible = true
} }
} }

View File

@ -1,5 +1,7 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2013 "Filippo Scognamiglio" * Copyright (c) 2013-2021 "Filippo Scognamiglio"
* https://github.com/Swordfish90/cool-retro-term * https://github.com/Swordfish90/cool-retro-term
* *
* This file is part of cool-retro-term. * This file is part of cool-retro-term.
@ -17,15 +19,12 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/ *******************************************************************************/
import QtQuick 2.0 import QtQuick 2.0
import QtQuick.Controls 2.0 import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0 import QtQuick.Layouts 1.0
// This component is simply a label with a predefined size. // This component is simply a label with a predefined size.
// Used to improve alignment. // Used to improve alignment.
Label { Label {
id: textfield id: textfield
Layout.minimumWidth: appSettings.labelWidth Layout.minimumWidth: appSettings.labelWidth

View File

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2013 "Filippo Scognamiglio" * Copyright (c) 2013-2021 "Filippo Scognamiglio"
* https://github.com/Swordfish90/cool-retro-term * https://github.com/Swordfish90/cool-retro-term
* *
* This file is part of cool-retro-term. * This file is part of cool-retro-term.
@ -17,10 +17,9 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/ *******************************************************************************/
import QtQuick 2.2 import QtQuick 2.2
QtObject{ QtObject {
property int selectedFontIndex property int selectedFontIndex
property real scaling property real scaling
property var _font: fontlist.get(selectedFontIndex) property var _font: fontlist.get(selectedFontIndex)
@ -31,8 +30,8 @@ QtObject{
property real defaultFontWidth: fontlist.get(selectedFontIndex).fontWidth property real defaultFontWidth: fontlist.get(selectedFontIndex).fontWidth
property bool lowResolutionFont: true property bool lowResolutionFont: true
property ListModel fontlist: ListModel{ property ListModel fontlist: ListModel {
ListElement{ ListElement {
name: "COMMODORE_PET" name: "COMMODORE_PET"
text: "Commodore PET (1977)" text: "Commodore PET (1977)"
source: "fonts/1977-commodore-pet/PetMe.ttf" source: "fonts/1977-commodore-pet/PetMe.ttf"
@ -41,7 +40,7 @@ QtObject{
baseScaling: 3.5 baseScaling: 3.5
fontWidth: 0.8 fontWidth: 0.8
} }
ListElement{ ListElement {
name: "IBM_PC" name: "IBM_PC"
text: "IBM PC (1981)" text: "IBM PC (1981)"
source: "fonts/1981-ibm-pc/PxPlus_IBM_BIOS.ttf" source: "fonts/1981-ibm-pc/PxPlus_IBM_BIOS.ttf"
@ -50,7 +49,7 @@ QtObject{
baseScaling: 3.5 baseScaling: 3.5
fontWidth: 0.8 fontWidth: 0.8
} }
ListElement{ ListElement {
name: "PROGGY_TINY" name: "PROGGY_TINY"
text: "Proggy Tiny (Modern)" text: "Proggy Tiny (Modern)"
source: "fonts/modern-proggy-tiny/ProggyTiny.ttf" source: "fonts/modern-proggy-tiny/ProggyTiny.ttf"
@ -59,7 +58,7 @@ QtObject{
baseScaling: 3.3 baseScaling: 3.3
fontWidth: 0.9 fontWidth: 0.9
} }
ListElement{ ListElement {
name: "TERMINUS_SCALED" name: "TERMINUS_SCALED"
text: "Terminus (Modern)" text: "Terminus (Modern)"
source: "fonts/modern-terminus/TerminusTTF-4.46.0.ttf" source: "fonts/modern-terminus/TerminusTTF-4.46.0.ttf"
@ -68,7 +67,7 @@ QtObject{
baseScaling: 3.0 baseScaling: 3.0
fontWidth: 1.0 fontWidth: 1.0
} }
ListElement{ ListElement {
name: "PRO_FONT_SCALED" name: "PRO_FONT_SCALED"
text: "Pro Font (Modern)" text: "Pro Font (Modern)"
source: "fonts/modern-pro-font-win-tweaked/ProFontWindows.ttf" source: "fonts/modern-pro-font-win-tweaked/ProFontWindows.ttf"
@ -77,7 +76,7 @@ QtObject{
baseScaling: 3.0 baseScaling: 3.0
fontWidth: 1.0 fontWidth: 1.0
} }
ListElement{ ListElement {
name: "APPLE_II" name: "APPLE_II"
text: "Apple ][ (1977)" text: "Apple ][ (1977)"
source: "fonts/1977-apple2/PrintChar21.ttf" source: "fonts/1977-apple2/PrintChar21.ttf"
@ -86,7 +85,7 @@ QtObject{
baseScaling: 3.5 baseScaling: 3.5
fontWidth: 0.9 fontWidth: 0.9
} }
ListElement{ ListElement {
name: "ATARI_400" name: "ATARI_400"
text: "Atari 400-800 (1979)" text: "Atari 400-800 (1979)"
source: "fonts/1979-atari-400-800/AtariClassic-Regular.ttf" source: "fonts/1979-atari-400-800/AtariClassic-Regular.ttf"
@ -95,7 +94,7 @@ QtObject{
baseScaling: 3.5 baseScaling: 3.5
fontWidth: 0.8 fontWidth: 0.8
} }
ListElement{ ListElement {
name: "COMMODORE_64" name: "COMMODORE_64"
text: "Commodore 64 (1982)" text: "Commodore 64 (1982)"
source: "fonts/1982-commodore64/C64_Pro_Mono-STYLE.ttf" source: "fonts/1982-commodore64/C64_Pro_Mono-STYLE.ttf"

View File

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2013 "Filippo Scognamiglio" * Copyright (c) 2013-2021 "Filippo Scognamiglio"
* https://github.com/Swordfish90/cool-retro-term * https://github.com/Swordfish90/cool-retro-term
* *
* This file is part of cool-retro-term. * This file is part of cool-retro-term.
@ -17,10 +17,9 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/ *******************************************************************************/
import QtQuick 2.2 import QtQuick 2.2
QtObject{ QtObject {
property int selectedFontIndex property int selectedFontIndex
property real scaling property real scaling
property var _font: fontlist.get(selectedFontIndex) property var _font: fontlist.get(selectedFontIndex)
@ -31,8 +30,8 @@ QtObject{
property real defaultFontWidth: fontlist.get(selectedFontIndex).fontWidth property real defaultFontWidth: fontlist.get(selectedFontIndex).fontWidth
property bool lowResolutionFont: true property bool lowResolutionFont: true
property ListModel fontlist: ListModel{ property ListModel fontlist: ListModel {
ListElement{ ListElement {
name: "COMMODORE_PET" name: "COMMODORE_PET"
text: "Commodore PET (1977)" text: "Commodore PET (1977)"
source: "fonts/1977-commodore-pet/PetMe.ttf" source: "fonts/1977-commodore-pet/PetMe.ttf"
@ -41,7 +40,7 @@ QtObject{
baseScaling: 3.5 baseScaling: 3.5
fontWidth: 0.7 fontWidth: 0.7
} }
ListElement{ ListElement {
name: "IBM_PC" name: "IBM_PC"
text: "IBM PC (1981)" text: "IBM PC (1981)"
source: "fonts/1981-ibm-pc/PxPlus_IBM_BIOS.ttf" source: "fonts/1981-ibm-pc/PxPlus_IBM_BIOS.ttf"
@ -50,7 +49,7 @@ QtObject{
baseScaling: 3.5 baseScaling: 3.5
fontWidth: 0.8 fontWidth: 0.8
} }
ListElement{ ListElement {
name: "PROGGY_TINY" name: "PROGGY_TINY"
text: "Proggy Tiny (Modern)" text: "Proggy Tiny (Modern)"
source: "fonts/modern-proggy-tiny/ProggyTiny.ttf" source: "fonts/modern-proggy-tiny/ProggyTiny.ttf"
@ -59,7 +58,7 @@ QtObject{
baseScaling: 3.3 baseScaling: 3.3
fontWidth: 0.9 fontWidth: 0.9
} }
ListElement{ ListElement {
name: "TERMINUS_SCALED" name: "TERMINUS_SCALED"
text: "Terminus (Modern)" text: "Terminus (Modern)"
source: "fonts/modern-terminus/TerminusTTF-4.46.0.ttf" source: "fonts/modern-terminus/TerminusTTF-4.46.0.ttf"
@ -68,7 +67,7 @@ QtObject{
baseScaling: 3.0 baseScaling: 3.0
fontWidth: 1.0 fontWidth: 1.0
} }
ListElement{ ListElement {
name: "PRO_FONT_SCALED" name: "PRO_FONT_SCALED"
text: "Pro Font (Modern)" text: "Pro Font (Modern)"
source: "fonts/modern-pro-font-win-tweaked/ProFontWindows.ttf" source: "fonts/modern-pro-font-win-tweaked/ProFontWindows.ttf"
@ -77,7 +76,7 @@ QtObject{
baseScaling: 3.0 baseScaling: 3.0
fontWidth: 1.0 fontWidth: 1.0
} }
ListElement{ ListElement {
name: "APPLE_II" name: "APPLE_II"
text: "Apple ][ (1977)" text: "Apple ][ (1977)"
source: "fonts/1977-apple2/PrintChar21.ttf" source: "fonts/1977-apple2/PrintChar21.ttf"
@ -86,7 +85,7 @@ QtObject{
baseScaling: 3.5 baseScaling: 3.5
fontWidth: 0.8 fontWidth: 0.8
} }
ListElement{ ListElement {
name: "ATARI_400" name: "ATARI_400"
text: "Atari 400-800 (1979)" text: "Atari 400-800 (1979)"
source: "fonts/1979-atari-400-800/AtariClassic-Regular.ttf" source: "fonts/1979-atari-400-800/AtariClassic-Regular.ttf"
@ -95,7 +94,7 @@ QtObject{
baseScaling: 3.5 baseScaling: 3.5
fontWidth: 0.7 fontWidth: 0.7
} }
ListElement{ ListElement {
name: "COMMODORE_64" name: "COMMODORE_64"
text: "Commodore 64 (1982)" text: "Commodore 64 (1982)"
source: "fonts/1982-commodore64/C64_Pro_Mono-STYLE.ttf" source: "fonts/1982-commodore64/C64_Pro_Mono-STYLE.ttf"

View File

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2013 "Filippo Scognamiglio" * Copyright (c) 2013-2021 "Filippo Scognamiglio"
* https://github.com/Swordfish90/cool-retro-term * https://github.com/Swordfish90/cool-retro-term
* *
* This file is part of cool-retro-term. * This file is part of cool-retro-term.
@ -17,27 +17,20 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/ *******************************************************************************/
import QtQuick 2.2 import QtQuick 2.2
QtObject{ QtObject {
property int selectedFontIndex property int selectedFontIndex
property real scaling property real scaling
property var source: fontlist.get(selectedFontIndex).source property var source: fontlist.get(selectedFontIndex).source
property var _font: fontlist.get(selectedFontIndex) property var _font: fontlist.get(selectedFontIndex)
property bool lowResolutionFont: _font.lowResolutionFont property bool lowResolutionFont: _font.lowResolutionFont
property int pixelSize: lowResolutionFont property int pixelSize: lowResolutionFont ? _font.pixelSize : _font.pixelSize * scaling
? _font.pixelSize
: _font.pixelSize * scaling
property int lineSpacing: lowResolutionFont property int lineSpacing: lowResolutionFont ? _font.lineSpacing : pixelSize * _font.lineSpacing
? _font.lineSpacing
: pixelSize * _font.lineSpacing
property real screenScaling: lowResolutionFont property real screenScaling: lowResolutionFont ? _font.baseScaling * scaling : 1.0
? _font.baseScaling * scaling
: 1.0
property real defaultFontWidth: fontlist.get(selectedFontIndex).fontWidth property real defaultFontWidth: fontlist.get(selectedFontIndex).fontWidth
@ -52,9 +45,8 @@ QtObject{
// High resolution fonts are instead drawn on a texture which has the // High resolution fonts are instead drawn on a texture which has the
// size of the screen, and the scaling directly controls their pixels size. // size of the screen, and the scaling directly controls their pixels size.
// Those are slower to render but are not pixelated. // Those are slower to render but are not pixelated.
property ListModel fontlist: ListModel { property ListModel fontlist: ListModel {
ListElement{ ListElement {
name: "TERMINUS_SCALED" name: "TERMINUS_SCALED"
text: "Terminus (Modern)" text: "Terminus (Modern)"
source: "fonts/modern-terminus/TerminusTTF-4.46.0.ttf" source: "fonts/modern-terminus/TerminusTTF-4.46.0.ttf"
@ -66,7 +58,7 @@ QtObject{
isSystemFont: false isSystemFont: false
family: "" family: ""
} }
ListElement{ ListElement {
name: "PRO_FONT_SCALED" name: "PRO_FONT_SCALED"
text: "Pro Font (Modern)" text: "Pro Font (Modern)"
source: "fonts/modern-pro-font-win-tweaked/ProFontWindows.ttf" source: "fonts/modern-pro-font-win-tweaked/ProFontWindows.ttf"
@ -78,7 +70,7 @@ QtObject{
isSystemFont: false isSystemFont: false
family: "" family: ""
} }
ListElement{ ListElement {
name: "EXCELSIOR_SCALED" name: "EXCELSIOR_SCALED"
text: "Fixedsys Excelsior (Modern)" text: "Fixedsys Excelsior (Modern)"
source: "fonts/modern-fixedsys-excelsior/FSEX301-L2.ttf" source: "fonts/modern-fixedsys-excelsior/FSEX301-L2.ttf"
@ -90,7 +82,7 @@ QtObject{
isSystemFont: false isSystemFont: false
family: "" family: ""
} }
ListElement{ ListElement {
name: "COMMODORE_PET_SCALED" name: "COMMODORE_PET_SCALED"
text: "Commodore PET (1977)" text: "Commodore PET (1977)"
source: "fonts/1977-commodore-pet/PetMe.ttf" source: "fonts/1977-commodore-pet/PetMe.ttf"
@ -102,7 +94,7 @@ QtObject{
isSystemFont: false isSystemFont: false
family: "" family: ""
} }
ListElement{ ListElement {
name: "PROGGY_TINY_SCALED" name: "PROGGY_TINY_SCALED"
text: "Proggy Tiny (Modern)" text: "Proggy Tiny (Modern)"
source: "fonts/modern-proggy-tiny/ProggyTiny.ttf" source: "fonts/modern-proggy-tiny/ProggyTiny.ttf"
@ -114,7 +106,7 @@ QtObject{
isSystemFont: false isSystemFont: false
family: "" family: ""
} }
ListElement{ ListElement {
name: "APPLE_II_SCALED" name: "APPLE_II_SCALED"
text: "Apple ][ (1977)" text: "Apple ][ (1977)"
source: "fonts/1977-apple2/PrintChar21.ttf" source: "fonts/1977-apple2/PrintChar21.ttf"
@ -126,7 +118,7 @@ QtObject{
isSystemFont: false isSystemFont: false
family: "" family: ""
} }
ListElement{ ListElement {
name: "ATARI_400_SCALED" name: "ATARI_400_SCALED"
text: "Atari 400-800 (1979)" text: "Atari 400-800 (1979)"
source: "fonts/1979-atari-400-800/AtariClassic-Regular.ttf" source: "fonts/1979-atari-400-800/AtariClassic-Regular.ttf"
@ -138,7 +130,7 @@ QtObject{
isSystemFont: false isSystemFont: false
family: "" family: ""
} }
ListElement{ ListElement {
name: "IBM_PC_SCALED" name: "IBM_PC_SCALED"
text: "IBM PC (1981)" text: "IBM PC (1981)"
source: "fonts/1981-ibm-pc/PxPlus_IBM_BIOS.ttf" source: "fonts/1981-ibm-pc/PxPlus_IBM_BIOS.ttf"
@ -150,7 +142,7 @@ QtObject{
isSystemFont: false isSystemFont: false
family: "" family: ""
} }
ListElement{ ListElement {
name: "COMMODORE_64_SCALED" name: "COMMODORE_64_SCALED"
text: "Commodore 64 (1982)" text: "Commodore 64 (1982)"
source: "fonts/1982-commodore64/C64_Pro_Mono-STYLE.ttf" source: "fonts/1982-commodore64/C64_Pro_Mono-STYLE.ttf"
@ -162,7 +154,7 @@ QtObject{
isSystemFont: false isSystemFont: false
family: "" family: ""
} }
ListElement{ ListElement {
name: "IBM_DOS" name: "IBM_DOS"
text: "IBM DOS (1985)" text: "IBM DOS (1985)"
source: "fonts/1985-ibm-pc-vga/PxPlus_IBM_VGA8.ttf" source: "fonts/1985-ibm-pc-vga/PxPlus_IBM_VGA8.ttf"
@ -174,7 +166,7 @@ QtObject{
isSystemFont: false isSystemFont: false
family: "" family: ""
} }
ListElement{ ListElement {
name: "HERMIT" name: "HERMIT"
text: "HD: Hermit (Modern)" text: "HD: Hermit (Modern)"
source: "fonts/modern-hermit/Hermit-medium.otf" source: "fonts/modern-hermit/Hermit-medium.otf"
@ -185,7 +177,7 @@ QtObject{
isSystemFont: false isSystemFont: false
family: "" family: ""
} }
ListElement{ ListElement {
name: "TERMINUS" name: "TERMINUS"
text: "HD: Terminus (Modern)" text: "HD: Terminus (Modern)"
source: "fonts/modern-terminus/TerminusTTF-4.46.0.ttf" source: "fonts/modern-terminus/TerminusTTF-4.46.0.ttf"
@ -196,7 +188,7 @@ QtObject{
isSystemFont: false isSystemFont: false
family: "" family: ""
} }
ListElement{ ListElement {
name: "PRO_FONT" name: "PRO_FONT"
text: "HD: Pro Font (Modern)" text: "HD: Pro Font (Modern)"
source: "fonts/modern-pro-font-win-tweaked/ProFontWindows.ttf" source: "fonts/modern-pro-font-win-tweaked/ProFontWindows.ttf"
@ -207,7 +199,7 @@ QtObject{
isSystemFont: false isSystemFont: false
family: "" family: ""
} }
ListElement{ ListElement {
name: "INCONSOLATA" name: "INCONSOLATA"
text: "HD: Inconsolata (Modern)" text: "HD: Inconsolata (Modern)"
source: "fonts/modern-inconsolata/Inconsolata.otf" source: "fonts/modern-inconsolata/Inconsolata.otf"
@ -218,7 +210,7 @@ QtObject{
isSystemFont: false isSystemFont: false
family: "" family: ""
} }
ListElement{ ListElement {
name: "IBM_3278" name: "IBM_3278"
text: "HD: IBM 3278 (1971)" text: "HD: IBM 3278 (1971)"
source: "fonts/1971-ibm-3278/3270-Regular.ttf" source: "fonts/1971-ibm-3278/3270-Regular.ttf"
@ -234,7 +226,7 @@ QtObject{
Component.onCompleted: addSystemFonts() Component.onCompleted: addSystemFonts()
function addSystemFonts() { function addSystemFonts() {
var families = monospaceSystemFonts; var families = monospaceSystemFonts
for (var i = 0; i < families.length; i++) { for (var i = 0; i < families.length; i++) {
if (verbose) { if (verbose) {
console.log("Adding system font: ", families[i]) console.log("Adding system font: ", families[i])
@ -245,16 +237,16 @@ QtObject{
function convertToListElement(family) { function convertToListElement(family) {
return { return {
name: "System: " + family, "name": "System: " + family,
text: qsTr("System: ") + family, "text": qsTr("System: ") + family,
source: "", "source": "",
lineSpacing: 0.1, "lineSpacing": 0.1,
pixelSize: 30, "pixelSize": 30,
fontWidth: 1.0, "fontWidth": 1.0,
baseScaling: 1.0, "baseScaling": 1.0,
lowResolutionFont: false, "lowResolutionFont": false,
isSystemFont: true, "isSystemFont": true,
family: family "family": family
} }
} }
} }

View File

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2013 "Filippo Scognamiglio" * Copyright (c) 2013-2021 "Filippo Scognamiglio"
* https://github.com/Swordfish90/cool-retro-term * https://github.com/Swordfish90/cool-retro-term
* *
* This file is part of cool-retro-term. * This file is part of cool-retro-term.
@ -17,14 +17,13 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/ *******************************************************************************/
import QtQuick 2.2 import QtQuick 2.2
import QtQuick.Window 2.0 import QtQuick.Window 2.0
import QtQuick.Controls 2.0 import QtQuick.Controls 2.0
import QtQuick.Layouts 1.1 import QtQuick.Layouts 1.1
import QtQuick.Dialogs 1.1 import QtQuick.Dialogs 1.1
Window{ Window {
id: insertnamedialog id: insertnamedialog
width: 400 width: 400
height: 100 height: 100
@ -39,50 +38,53 @@ Window{
title: qsTr("Error") title: qsTr("Error")
visible: false visible: false
function showError(message){ function showError(message) {
text = message; text = message
open(); open()
} }
} }
function validateName(name){ function validateName(name) {
var profile_list = appSettings.profilesList; var profile_list = appSettings.profilesList
if (name === "") if (name === "")
return 1; return 1
return 0; return 0
} }
ColumnLayout{ ColumnLayout {
anchors.margins: 10 anchors.margins: 10
anchors.fill: parent anchors.fill: parent
RowLayout{ RowLayout {
Label{text: qsTr("Name")} Label {
TextField{ text: qsTr("Name")
}
TextField {
id: namefield id: namefield
Layout.fillWidth: true Layout.fillWidth: true
Component.onCompleted: forceActiveFocus() Component.onCompleted: forceActiveFocus()
onAccepted: okbutton.clickAction() onAccepted: okbutton.clickAction()
} }
} }
RowLayout{ RowLayout {
Layout.alignment: Qt.AlignBottom | Qt.AlignRight Layout.alignment: Qt.AlignBottom | Qt.AlignRight
Button{ Button {
id: okbutton id: okbutton
text: qsTr("OK") text: qsTr("OK")
onClicked: clickAction() onClicked: clickAction()
function clickAction(){ function clickAction() {
var name = namefield.text; var name = namefield.text
switch(validateName(name)){ switch (validateName(name)) {
case 1: case 1:
errorDialog.showError(qsTr("The name you inserted is empty. Please choose a different one.")); errorDialog.showError(
break; qsTr("The name you inserted is empty. Please choose a different one."))
break
default: default:
nameSelected(name); nameSelected(name)
close(); close()
} }
} }
} }
Button{ Button {
text: qsTr("Cancel") text: qsTr("Cancel")
onClicked: close() onClicked: close()
} }

View File

@ -1,78 +0,0 @@
import QtQuick 2.0
import "utils.js" as Utils
ShaderEffect {
property color _staticFrameColor: "#ffffff"
property color _backgroundColor: appSettings.backgroundColor
property color _fontColor: appSettings.fontColor
property color _lightColor: Utils.mix(_fontColor, _backgroundColor, 0.2)
property real _ambientLight: Utils.lint(0.2, 0.8, appSettings.ambientLight)
property color frameColor: Utils.mix(_staticFrameColor, _lightColor, _ambientLight)
property real screenCurvature: appSettings.screenCurvature * appSettings.screenCurvatureSize
property real shadowLength: 0.5 * screenCurvature * Utils.lint(0.50, 1.5, _ambientLight)
property size aadelta: Qt.size(1.0 / width, 1.0 / height)
fragmentShader: "
#ifdef GL_ES
precision mediump float;
#endif
uniform lowp float screenCurvature;
uniform lowp float shadowLength;
uniform highp float qt_Opacity;
uniform lowp vec4 frameColor;
uniform mediump vec2 aadelta;
varying highp vec2 qt_TexCoord0;
vec2 distortCoordinates(vec2 coords){
vec2 cc = (coords - vec2(0.5));
float dist = dot(cc, cc) * screenCurvature;
return (coords + cc * (1.0 + dist) * dist);
}
float max2(vec2 v) {
return max(v.x, v.y);
}
float min2(vec2 v) {
return min(v.x, v.y);
}
float prod2(vec2 v) {
return v.x * v.y;
}
float sum2(vec2 v) {
return v.x + v.y;
}
void main(){
vec2 staticCoords = qt_TexCoord0;
vec2 coords = distortCoordinates(staticCoords);
vec3 color = vec3(0.0);
float alpha = 0.0;
float outShadowLength = shadowLength;
float inShadowLength = shadowLength * 0.5;
float outShadow = max2(1.0 - smoothstep(vec2(-outShadowLength), vec2(0.0), coords) + smoothstep(vec2(1.0), vec2(1.0 + outShadowLength), coords));
outShadow = clamp(sqrt(outShadow), 0.0, 1.0);
color += frameColor.rgb * outShadow;
alpha = sum2(1.0 - smoothstep(vec2(0.0), aadelta, coords) + smoothstep(vec2(1.0) - aadelta, vec2(1.0), coords));
alpha = clamp(alpha, 0.0, 1.0) * mix(1.0, 0.9, outShadow);
float inShadow = 1.0 - prod2(smoothstep(0.0, inShadowLength, coords) - smoothstep(1.0 - inShadowLength, 1.0, coords));
inShadow = 0.5 * inShadow * inShadow;
alpha = max(alpha, inShadow);
gl_FragColor = vec4(color * alpha, alpha);
}
"
onStatusChanged: if (log) console.log(log) //Print warning messages
}

View File

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2013 "Filippo Scognamiglio" * Copyright (c) 2013-2021 "Filippo Scognamiglio"
* https://github.com/Swordfish90/cool-retro-term * https://github.com/Swordfish90/cool-retro-term
* *
* This file is part of cool-retro-term. * This file is part of cool-retro-term.
@ -73,7 +73,7 @@ Item{
id: kterminal id: kterminal
property int textureResolutionScale: appSettings.lowResolutionFont ? devicePixelRatio : 1 property int textureResolutionScale: appSettings.lowResolutionFont ? devicePixelRatio : 1
property int margin: appSettings.margin / screenScaling property int margin: appSettings.totalMargin / screenScaling
property int totalWidth: Math.floor(parent.width / (screenScaling * fontWidth)) property int totalWidth: Math.floor(parent.width / (screenScaling * fontWidth))
property int totalHeight: Math.floor(parent.height / screenScaling) property int totalHeight: Math.floor(parent.height / screenScaling)
@ -177,8 +177,8 @@ Item{
} }
property alias contextmenu: menuLoader.item property alias contextmenu: menuLoader.item
MouseArea{ MouseArea {
property real margin: appSettings.margin property real margin: appSettings.totalMargin
acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton
anchors.fill: parent anchors.fill: parent
@ -219,8 +219,8 @@ Item{
var cc = Qt.size(0.5 - x, 0.5 - y); var cc = Qt.size(0.5 - x, 0.5 - y);
var distortion = (cc.height * cc.height + cc.width * cc.width) * appSettings.screenCurvature * appSettings.screenCurvatureSize; var distortion = (cc.height * cc.height + cc.width * cc.width) * appSettings.screenCurvature * appSettings.screenCurvatureSize;
return Qt.point((x - cc.width * (1+distortion) * distortion) * kterminal.totalWidth, return Qt.point((x - cc.width * (1+distortion) * distortion) * (kterminal.totalWidth),
(y - cc.height * (1+distortion) * distortion) * kterminal.totalHeight) (y - cc.height * (1+distortion) * distortion) * (kterminal.totalHeight))
} }
} }
ShaderEffectSource{ ShaderEffectSource{

View File

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2013 "Filippo Scognamiglio" * Copyright (c) 2013-2021 "Filippo Scognamiglio"
* https://github.com/Swordfish90/cool-retro-term * https://github.com/Swordfish90/cool-retro-term
* *
* This file is part of cool-retro-term. * This file is part of cool-retro-term.
@ -17,7 +17,6 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/ *******************************************************************************/
import QtQuick 2.2 import QtQuick 2.2
import QtQuick.Controls 2.0 import QtQuick.Controls 2.0
import QtQuick.Layouts 1.1 import QtQuick.Layouts 1.1
@ -25,26 +24,26 @@ import QtQml 2.0
import "Components" import "Components"
ColumnLayout{ ColumnLayout {
GroupBox{ GroupBox {
Layout.fillWidth: true Layout.fillWidth: true
title: qsTr("Command") title: qsTr("Command")
ColumnLayout { ColumnLayout {
anchors.fill: parent anchors.fill: parent
CheckBox{ CheckBox {
id: useCustomCommand id: useCustomCommand
text: qsTr("Use custom command instead of shell at startup") text: qsTr("Use custom command instead of shell at startup")
checked: appSettings.useCustomCommand checked: appSettings.useCustomCommand
onCheckedChanged: appSettings.useCustomCommand = checked onCheckedChanged: appSettings.useCustomCommand = checked
} }
// Workaround for QTBUG-31627 for pre 5.3.0 // Workaround for QTBUG-31627 for pre 5.3.0
Binding{ Binding {
target: useCustomCommand target: useCustomCommand
property: "checked" property: "checked"
value: appSettings.useCustomCommand value: appSettings.useCustomCommand
} }
TextField{ TextField {
id: customCommand id: customCommand
Layout.fillWidth: true Layout.fillWidth: true
text: appSettings.customCommand text: appSettings.customCommand
@ -53,89 +52,109 @@ ColumnLayout{
// Save text even if user forgets to press enter or unfocus // Save text even if user forgets to press enter or unfocus
function saveSetting() { function saveSetting() {
appSettings.customCommand = text; appSettings.customCommand = text
} }
Component.onCompleted: settings_window.closing.connect(saveSetting) Component.onCompleted: settings_window.closing.connect(
saveSetting)
} }
} }
} }
GroupBox{ GroupBox {
title: qsTr("Performance") title: qsTr("Performance")
Layout.fillWidth: true Layout.fillWidth: true
GridLayout{ GridLayout {
anchors.fill: parent anchors.fill: parent
columns: 4 columns: 4
Label{text: qsTr("Effects FPS")} Label {
Slider{ text: qsTr("Effects FPS")
}
Slider {
Layout.fillWidth: true Layout.fillWidth: true
Layout.columnSpan: 2 Layout.columnSpan: 2
id: fpsSlider id: fpsSlider
onValueChanged: { onValueChanged: {
if (enabled) { if (enabled) {
appSettings.fps = value !== 60 ? value + 1 : 0; appSettings.fps = value !== 60 ? value + 1 : 0
} }
} }
stepSize: 1 stepSize: 1
enabled: false enabled: false
Component.onCompleted: { Component.onCompleted: {
from = 0; from = 0
to = 60; to = 60
value = appSettings.fps !== 0 ? appSettings.fps - 1 : 60; value = appSettings.fps !== 0 ? appSettings.fps - 1 : 60
enabled = true; enabled = true
} }
} }
Label{text: appSettings.fps !== 0 ? appSettings.fps : qsTr("Max")} Label {
Label{text: qsTr("Texture Quality")} text: appSettings.fps !== 0 ? appSettings.fps : qsTr("Max")
Slider{ }
Label {
text: qsTr("Texture Quality")
}
Slider {
id: txtslider id: txtslider
Layout.fillWidth: true Layout.fillWidth: true
Layout.columnSpan: 2 Layout.columnSpan: 2
onValueChanged: if (enabled) appSettings.windowScaling = value; onValueChanged: if (enabled)
appSettings.windowScaling = value
stepSize: 0.05 stepSize: 0.05
enabled: false enabled: false
Component.onCompleted: { Component.onCompleted: {
from = 0.25 //Without this value gets set to 0.5 from = 0.25 //Without this value gets set to 0.5
value = appSettings.windowScaling; value = appSettings.windowScaling
enabled = true; enabled = true
} }
} }
Label{text: Math.round(txtslider.value * 100) + "%"} Label {
text: Math.round(txtslider.value * 100) + "%"
}
Label{text: qsTr("Bloom Quality")} Label {
Slider{ text: qsTr("Bloom Quality")
}
Slider {
Layout.fillWidth: true Layout.fillWidth: true
Layout.columnSpan: 2 Layout.columnSpan: 2
id: bloomSlider id: bloomSlider
onValueChanged: if (enabled) appSettings.bloomQuality = value; onValueChanged: if (enabled)
appSettings.bloomQuality = value
stepSize: 0.05 stepSize: 0.05
enabled: false enabled: false
Component.onCompleted: { Component.onCompleted: {
from = 0.25 from = 0.25
value = appSettings.bloomQuality; value = appSettings.bloomQuality
enabled = true; enabled = true
} }
} }
Label{text: Math.round(bloomSlider.value * 100) + "%"} Label {
text: Math.round(bloomSlider.value * 100) + "%"
}
Label{text: qsTr("BurnIn Quality")} Label {
Slider{ text: qsTr("BurnIn Quality")
}
Slider {
Layout.fillWidth: true Layout.fillWidth: true
id: burnInSlider id: burnInSlider
Layout.columnSpan: 2 Layout.columnSpan: 2
onValueChanged: if (enabled) appSettings.burnInQuality = value; onValueChanged: if (enabled)
appSettings.burnInQuality = value
stepSize: 0.05 stepSize: 0.05
enabled: false enabled: false
Component.onCompleted: { Component.onCompleted: {
from = 0.25 from = 0.25
value = appSettings.burnInQuality; value = appSettings.burnInQuality
enabled = true; enabled = true
} }
} }
Label{text: Math.round(burnInSlider.value * 100) + "%"} Label {
CheckBox{ text: Math.round(burnInSlider.value * 100) + "%"
}
CheckBox {
Layout.columnSpan: 2 Layout.columnSpan: 2
text: qsTr("Burnin optimization (Might display timing artifacts)") text: qsTr("Burnin optimization (Might display timing artifacts)")
checked: appSettings.useFastBurnIn checked: appSettings.useFastBurnIn

View File

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2013 "Filippo Scognamiglio" * Copyright (c) 2013-2021 "Filippo Scognamiglio"
* https://github.com/Swordfish90/cool-retro-term * https://github.com/Swordfish90/cool-retro-term
* *
* This file is part of cool-retro-term. * This file is part of cool-retro-term.
@ -17,71 +17,70 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/ *******************************************************************************/
import QtQuick 2.2 import QtQuick 2.2
import QtQuick.Controls 2.0 import QtQuick.Controls 2.0
import QtQuick.Layouts 1.1 import QtQuick.Layouts 1.1
ColumnLayout{ ColumnLayout {
spacing: 2 spacing: 2
GroupBox{ GroupBox {
title: qsTr("Effects") title: qsTr("Effects")
Layout.fillWidth: true Layout.fillWidth: true
ColumnLayout { ColumnLayout {
anchors.fill: parent anchors.fill: parent
CheckableSlider{ CheckableSlider {
name: qsTr("Bloom") name: qsTr("Bloom")
onNewValue: appSettings.bloom = newValue onNewValue: appSettings.bloom = newValue
value: appSettings.bloom value: appSettings.bloom
} }
CheckableSlider{ CheckableSlider {
name: qsTr("BurnIn") name: qsTr("BurnIn")
onNewValue: appSettings.burnIn = newValue onNewValue: appSettings.burnIn = newValue
value: appSettings.burnIn value: appSettings.burnIn
} }
CheckableSlider{ CheckableSlider {
name: qsTr("Static Noise") name: qsTr("Static Noise")
onNewValue: appSettings.staticNoise = newValue onNewValue: appSettings.staticNoise = newValue
value: appSettings.staticNoise value: appSettings.staticNoise
} }
CheckableSlider{ CheckableSlider {
name: qsTr("Jitter") name: qsTr("Jitter")
onNewValue: appSettings.jitter = newValue onNewValue: appSettings.jitter = newValue
value: appSettings.jitter value: appSettings.jitter
} }
CheckableSlider{ CheckableSlider {
name: qsTr("Glow Line") name: qsTr("Glow Line")
onNewValue: appSettings.glowingLine = newValue; onNewValue: appSettings.glowingLine = newValue
value: appSettings.glowingLine value: appSettings.glowingLine
} }
CheckableSlider{ CheckableSlider {
name: qsTr("Screen Curvature") name: qsTr("Screen Curvature")
onNewValue: appSettings.screenCurvature = newValue; onNewValue: appSettings.screenCurvature = newValue
value: appSettings.screenCurvature; value: appSettings.screenCurvature
} }
CheckableSlider{ CheckableSlider {
name: qsTr("Ambient Light") name: qsTr("Ambient Light")
onNewValue: appSettings.ambientLight = newValue; onNewValue: appSettings.ambientLight = newValue
value: appSettings.ambientLight value: appSettings.ambientLight
enabled: appSettings.framesIndex !== 0 enabled: appSettings.framesIndex !== 0
} }
CheckableSlider{ CheckableSlider {
name: qsTr("Flickering") name: qsTr("Flickering")
onNewValue: appSettings.flickering = newValue; onNewValue: appSettings.flickering = newValue
value: appSettings.flickering; value: appSettings.flickering
} }
CheckableSlider{ CheckableSlider {
name: qsTr("Horizontal Sync") name: qsTr("Horizontal Sync")
onNewValue: appSettings.horizontalSync = newValue; onNewValue: appSettings.horizontalSync = newValue
value: appSettings.horizontalSync; value: appSettings.horizontalSync
} }
CheckableSlider{ CheckableSlider {
name: qsTr("RGB Shift") name: qsTr("RGB Shift")
onNewValue: appSettings.rbgShift = newValue; onNewValue: appSettings.rbgShift = newValue
value: appSettings.rbgShift; value: appSettings.rbgShift
} }
} }
} }

View File

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2013 "Filippo Scognamiglio" * Copyright (c) 2013-2021 "Filippo Scognamiglio"
* https://github.com/Swordfish90/cool-retro-term * https://github.com/Swordfish90/cool-retro-term
* *
* This file is part of cool-retro-term. * This file is part of cool-retro-term.
@ -17,14 +17,13 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/ *******************************************************************************/
import QtQuick 2.2 import QtQuick 2.2
import QtQuick.Controls 2.4 import QtQuick.Controls 2.4
import QtQuick.Layouts 1.1 import QtQuick.Layouts 1.1
import QtQuick.Dialogs 1.1 import QtQuick.Dialogs 1.1
ColumnLayout{ ColumnLayout {
GroupBox{ GroupBox {
Layout.fillWidth: true Layout.fillWidth: true
title: qsTr("Profile") title: qsTr("Profile")
RowLayout { RowLayout {
@ -52,112 +51,127 @@ ColumnLayout{
ColumnLayout { ColumnLayout {
Layout.fillHeight: true Layout.fillHeight: true
Layout.fillWidth: false Layout.fillWidth: false
Button{ Button {
Layout.fillWidth: true Layout.fillWidth: true
text: qsTr("Save") text: qsTr("Save")
onClicked: { onClicked: {
insertname.profileName = ""; insertname.profileName = ""
insertname.show() insertname.show()
} }
} }
Button{ Button {
Layout.fillWidth: true Layout.fillWidth: true
property alias currentIndex: profilesView.currentIndex property alias currentIndex: profilesView.currentIndex
enabled: currentIndex >= 0 enabled: currentIndex >= 0
text: qsTr("Load") text: qsTr("Load")
onClicked: { onClicked: {
var index = currentIndex; var index = currentIndex
if (index >= 0) if (index >= 0)
appSettings.loadProfile(index); appSettings.loadProfile(index)
} }
} }
Button{ Button {
Layout.fillWidth: true Layout.fillWidth: true
text: qsTr("Remove") text: qsTr("Remove")
property alias currentIndex: profilesView.currentIndex property alias currentIndex: profilesView.currentIndex
enabled: currentIndex >= 0 && !appSettings.profilesList.get(currentIndex).builtin enabled: currentIndex >= 0 && !appSettings.profilesList.get(
currentIndex).builtin
onClicked: { onClicked: {
appSettings.profilesList.remove(currentIndex); appSettings.profilesList.remove(currentIndex)
profilesView.selection.clear(); profilesView.selection.clear()
// TODO This is a very ugly workaround. The view didn't update on Qt 5.3.2. // TODO This is a very ugly workaround. The view didn't update on Qt 5.3.2.
profilesView.model = 0; profilesView.model = 0
profilesView.model = appSettings.profilesList; profilesView.model = appSettings.profilesList
} }
} }
Item { Item {
// Spacing // Spacing
Layout.fillHeight: true Layout.fillHeight: true
} }
Button{ Button {
Layout.fillWidth: true Layout.fillWidth: true
text: qsTr("Import") text: qsTr("Import")
onClicked: { onClicked: {
fileDialog.selectExisting = true; fileDialog.selectExisting = true
fileDialog.callBack = function (url) {loadFile(url);}; fileDialog.callBack = function (url) {
fileDialog.open(); loadFile(url)
}
fileDialog.open()
} }
function loadFile(url) { function loadFile(url) {
try { try {
if (appSettings.verbose) if (appSettings.verbose)
console.log("Loading file: " + url); console.log("Loading file: " + url)
var profileObject = JSON.parse(fileIO.read(url)); var profileObject = JSON.parse(fileIO.read(url))
var name = profileObject.name; var name = profileObject.name
if (!name) if (!name)
throw "Profile doesn't have a name"; throw "Profile doesn't have a name"
var version = profileObject.version !== undefined ? profileObject.version : 1; var version = profileObject.version
!== undefined ? profileObject.version : 1
if (version !== appSettings.profileVersion) if (version !== appSettings.profileVersion)
throw "This profile is not supported on this version of CRT."; throw "This profile is not supported on this version of CRT."
delete profileObject.name; delete profileObject.name
appSettings.appendCustomProfile(name, JSON.stringify(profileObject)); appSettings.appendCustomProfile(name,
JSON.stringify(
profileObject))
} catch (err) { } catch (err) {
messageDialog.text = qsTr(err) messageDialog.text = qsTr(err)
messageDialog.open(); messageDialog.open()
} }
} }
} }
Button{ Button {
property alias currentIndex: profilesView.currentIndex property alias currentIndex: profilesView.currentIndex
Layout.fillWidth: true Layout.fillWidth: true
text: qsTr("Export") text: qsTr("Export")
enabled: currentIndex >= 0 && !appSettings.profilesList.get(currentIndex).builtin enabled: currentIndex >= 0 && !appSettings.profilesList.get(
currentIndex).builtin
onClicked: { onClicked: {
fileDialog.selectExisting = false; fileDialog.selectExisting = false
fileDialog.callBack = function (url) {storeFile(url);}; fileDialog.callBack = function (url) {
fileDialog.open(); storeFile(url)
}
fileDialog.open()
} }
function storeFile(url) { function storeFile(url) {
try { try {
var urlString = url.toString(); var urlString = url.toString()
// Fix the extension if it's missing. // Fix the extension if it's missing.
var extension = urlString.substring(urlString.length - 5, urlString.length); var extension = urlString.substring(
var urlTail = (extension === ".json" ? "" : ".json"); urlString.length - 5, urlString.length)
url += urlTail; var urlTail = (extension === ".json" ? "" : ".json")
url += urlTail
if (true) if (true)
console.log("Storing file: " + url); console.log("Storing file: " + url)
var profileObject = appSettings.profilesList.get(currentIndex); var profileObject = appSettings.profilesList.get(
var profileSettings = JSON.parse(profileObject.obj_string); currentIndex)
profileSettings["name"] = profileObject.text; var profileSettings = JSON.parse(
profileSettings["version"] = appSettings.profileVersion; profileObject.obj_string)
profileSettings["name"] = profileObject.text
profileSettings["version"] = appSettings.profileVersion
var result = fileIO.write(url, JSON.stringify(profileSettings, undefined, 2)); var result = fileIO.write(url, JSON.stringify(
profileSettings,
undefined, 2))
if (!result) if (!result)
throw "The file could not be written."; throw "The file could not be written."
} catch (err) { } catch (err) {
console.log(err); console.log(err)
messageDialog.text = qsTr("There has been an error storing the file.") messageDialog.text = qsTr(
messageDialog.open(); "There has been an error storing the file.")
messageDialog.open()
} }
} }
} }
@ -165,29 +179,44 @@ ColumnLayout{
} }
} }
GroupBox{ GroupBox {
title: qsTr("Screen") title: qsTr("Screen")
Layout.fillWidth: true Layout.fillWidth: true
GridLayout{ GridLayout {
anchors.fill: parent anchors.fill: parent
columns: 2 columns: 2
Label{ text: qsTr("Brightness") } Label {
SimpleSlider{ text: qsTr("Brightness")
}
SimpleSlider {
onValueChanged: appSettings.brightness = value onValueChanged: appSettings.brightness = value
value: appSettings.brightness value: appSettings.brightness
} }
Label{ text: qsTr("Contrast") } Label {
SimpleSlider{ text: qsTr("Contrast")
}
SimpleSlider {
onValueChanged: appSettings.contrast = value onValueChanged: appSettings.contrast = value
value: appSettings.contrast value: appSettings.contrast
} }
Label{ text: qsTr("Margin") } Label {
SimpleSlider{ text: qsTr("Margin")
}
SimpleSlider {
onValueChanged: appSettings._margin = value onValueChanged: appSettings._margin = value
value: appSettings._margin value: appSettings._margin
} }
Label{ text: qsTr("Opacity") } Label {
SimpleSlider{ text: qsTr("Frame size")
}
SimpleSlider {
onValueChanged: appSettings._frameMargin = value
value: appSettings._frameMargin
}
Label {
text: qsTr("Opacity")
}
SimpleSlider {
onValueChanged: appSettings.windowOpacity = value onValueChanged: appSettings.windowOpacity = value
value: appSettings.windowOpacity value: appSettings.windowOpacity
} }
@ -195,17 +224,18 @@ ColumnLayout{
} }
// DIALOGS //////////////////////////////////////////////////////////////// // DIALOGS ////////////////////////////////////////////////////////////////
InsertNameDialog{ InsertNameDialog {
id: insertname id: insertname
onNameSelected: { onNameSelected: {
appSettings.appendCustomProfile(name, appSettings.composeProfileString()); appSettings.appendCustomProfile(name,
appSettings.composeProfileString())
} }
} }
MessageDialog { MessageDialog {
id: messageDialog id: messageDialog
title: qsTr("File Error") title: qsTr("File Error")
onAccepted: { onAccepted: {
messageDialog.close(); messageDialog.close()
} }
} }
Loader { Loader {
@ -213,23 +243,23 @@ ColumnLayout{
property bool selectExisting: false property bool selectExisting: false
id: fileDialog id: fileDialog
sourceComponent: FileDialog{ sourceComponent: FileDialog {
nameFilters: ["Json files (*.json)"] nameFilters: ["Json files (*.json)"]
selectMultiple: false selectMultiple: false
selectFolder: false selectFolder: false
selectExisting: fileDialog.selectExisting selectExisting: fileDialog.selectExisting
onAccepted: callBack(fileUrl); onAccepted: callBack(fileUrl)
} }
onSelectExistingChanged: reload() onSelectExistingChanged: reload()
function open() { function open() {
item.open(); item.open()
} }
function reload() { function reload() {
active = false; active = false
active = true; active = true
} }
} }
} }

View File

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2013 "Filippo Scognamiglio" * Copyright (c) 2013-2021 "Filippo Scognamiglio"
* https://github.com/Swordfish90/cool-retro-term * https://github.com/Swordfish90/cool-retro-term
* *
* This file is part of cool-retro-term. * This file is part of cool-retro-term.
@ -17,7 +17,6 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/ *******************************************************************************/
import QtQuick 2.2 import QtQuick 2.2
import QtQuick.Controls 2.1 import QtQuick.Controls 2.1
import QtQuick.Layouts 1.1 import QtQuick.Layouts 1.1
@ -25,135 +24,143 @@ import QtQml 2.0
import "Components" import "Components"
ColumnLayout{ ColumnLayout {
GroupBox{ GroupBox {
title: qsTr("Font") title: qsTr("Font")
Layout.fillWidth: true Layout.fillWidth: true
GridLayout{ GridLayout {
anchors.fill: parent anchors.fill: parent
columns: 2 columns: 2
Label { text: qsTr("Rasterization") } Label {
text: qsTr("Rasterization")
}
ComboBox { ComboBox {
id: rasterizationBox id: rasterizationBox
property string selectedElement: model[currentIndex] property string selectedElement: model[currentIndex]
Layout.fillWidth: true Layout.fillWidth: true
model: [qsTr("Default"), qsTr("Scanlines"), qsTr("Pixels")] model: [qsTr("Default"), qsTr("Scanlines"), qsTr("Pixels"), qsTr("Sub-Pixels")]
currentIndex: appSettings.rasterization currentIndex: appSettings.rasterization
onCurrentIndexChanged: { onCurrentIndexChanged: {
appSettings.rasterization = currentIndex appSettings.rasterization = currentIndex
} }
} }
Label{ text: qsTr("Name") } Label {
ComboBox{ text: qsTr("Name")
}
ComboBox {
id: fontChanger id: fontChanger
Layout.fillWidth: true Layout.fillWidth: true
model: appSettings.fontlist model: appSettings.fontlist
textRole: "text" textRole: "text"
onActivated: { onActivated: {
var name = appSettings.fontlist.get(index).name; var name = appSettings.fontlist.get(index).name
appSettings.fontNames[appSettings.rasterization] = name; appSettings.fontNames[appSettings.rasterization] = name
appSettings.handleFontChanged(); appSettings.handleFontChanged()
} }
function updateIndex(){ function updateIndex() {
var name = appSettings.fontNames[appSettings.rasterization]; var name = appSettings.fontNames[appSettings.rasterization]
var index = appSettings.getIndexByName(name); var index = appSettings.getIndexByName(name)
if (index !== undefined) if (index !== undefined)
currentIndex = index; currentIndex = index
} }
Connections{ Connections {
target: appSettings target: appSettings
onTerminalFontChanged: fontChanger.updateIndex(); onTerminalFontChanged: fontChanger.updateIndex()
} }
Component.onCompleted: updateIndex(); Component.onCompleted: updateIndex()
} }
Label{ text: qsTr("Scaling") } Label {
RowLayout{ text: qsTr("Scaling")
}
RowLayout {
Layout.fillWidth: true Layout.fillWidth: true
Slider{ Slider {
Layout.fillWidth: true Layout.fillWidth: true
id: fontScalingChanger id: fontScalingChanger
onValueChanged: appSettings.fontScaling = value onValueChanged: appSettings.fontScaling = value
value: appSettings.fontScaling value: appSettings.fontScaling
stepSize: 0.05 stepSize: 0.05
from: appSettings.minimumFontScaling; from: appSettings.minimumFontScaling
to: appSettings.maximumFontScaling; to: appSettings.maximumFontScaling
} }
SizedLabel{ SizedLabel {
text: Math.round(fontScalingChanger.value * 100) + "%" text: Math.round(fontScalingChanger.value * 100) + "%"
} }
} }
Label{ text: qsTr("Font Width") } Label {
RowLayout{ text: qsTr("Font Width")
}
RowLayout {
Layout.fillWidth: true Layout.fillWidth: true
Slider{ Slider {
Layout.fillWidth: true Layout.fillWidth: true
id: widthChanger id: widthChanger
onValueChanged: appSettings.fontWidth = value; onValueChanged: appSettings.fontWidth = value
value: appSettings.fontWidth value: appSettings.fontWidth
stepSize: 0.05 stepSize: 0.05
from: 0.5 from: 0.5
to: 1.5 to: 1.5
} }
SizedLabel{ SizedLabel {
text: Math.round(widthChanger.value * 100) + "%" text: Math.round(widthChanger.value * 100) + "%"
} }
} }
} }
} }
GroupBox{ GroupBox {
title: qsTr("Cursor") title: qsTr("Cursor")
Layout.fillWidth: true Layout.fillWidth: true
ColumnLayout { ColumnLayout {
anchors.fill: parent anchors.fill: parent
CheckBox{ CheckBox {
id: blinkingCursor id: blinkingCursor
text: qsTr("Blinking Cursor") text: qsTr("Blinking Cursor")
checked: appSettings.blinkingCursor checked: appSettings.blinkingCursor
onCheckedChanged: appSettings.blinkingCursor = checked onCheckedChanged: appSettings.blinkingCursor = checked
} }
Binding{ Binding {
target: blinkingCursor target: blinkingCursor
property: "checked" property: "checked"
value: appSettings.blinkingCursor value: appSettings.blinkingCursor
} }
} }
} }
GroupBox{ GroupBox {
title: qsTr("Colors") title: qsTr("Colors")
Layout.fillWidth: true Layout.fillWidth: true
ColumnLayout{ ColumnLayout {
anchors.fill: parent anchors.fill: parent
ColumnLayout{ ColumnLayout {
Layout.fillWidth: true Layout.fillWidth: true
CheckableSlider{ CheckableSlider {
name: qsTr("Chroma Color") name: qsTr("Chroma Color")
onNewValue: appSettings.chromaColor = newValue onNewValue: appSettings.chromaColor = newValue
value: appSettings.chromaColor value: appSettings.chromaColor
} }
CheckableSlider{ CheckableSlider {
name: qsTr("Saturation Color") name: qsTr("Saturation Color")
onNewValue: appSettings.saturationColor = newValue onNewValue: appSettings.saturationColor = newValue
value: appSettings.saturationColor value: appSettings.saturationColor
enabled: appSettings.chromaColor !== 0 enabled: appSettings.chromaColor !== 0
} }
} }
RowLayout{ RowLayout {
Layout.fillWidth: true Layout.fillWidth: true
ColorButton{ ColorButton {
name: qsTr("Font") name: qsTr("Font")
height: 50 height: 50
Layout.fillWidth: true Layout.fillWidth: true
onColorSelected: appSettings._fontColor = color; onColorSelected: appSettings._fontColor = color
color: appSettings._fontColor color: appSettings._fontColor
} }
ColorButton{ ColorButton {
name: qsTr("Background") name: qsTr("Background")
height: 50 height: 50
Layout.fillWidth: true Layout.fillWidth: true
onColorSelected: appSettings._backgroundColor = color; onColorSelected: appSettings._backgroundColor = color
color: appSettings._backgroundColor color: appSettings._backgroundColor
} }
} }

View File

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2013 "Filippo Scognamiglio" * Copyright (c) 2013-2021 "Filippo Scognamiglio"
* https://github.com/Swordfish90/cool-retro-term * https://github.com/Swordfish90/cool-retro-term
* *
* This file is part of cool-retro-term. * This file is part of cool-retro-term.

91
app/qml/ShaderLibrary.qml Normal file
View File

@ -0,0 +1,91 @@
import QtQuick 2.0
QtObject {
property string rasterizationShader:
(appSettings.rasterization === appSettings.no_rasterization ? "
lowp vec3 applyRasterization(vec2 screenCoords, lowp vec3 texel, vec2 virtualResolution, float intensity) {
return texel;
}" : "") +
(appSettings.rasterization === appSettings.scanline_rasterization ? "
#define INTENSITY 0.30
#define BRIGHTBOOST 0.30
lowp vec3 applyRasterization(vec2 screenCoords, lowp vec3 texel, vec2 virtualResolution, float intensity) {
lowp vec3 pixelHigh = ((1.0 + BRIGHTBOOST) - (0.2 * texel)) * texel;
lowp vec3 pixelLow = ((1.0 - INTENSITY) + (0.1 * texel)) * texel;
vec2 coords = fract(screenCoords * virtualResolution) * 2.0 - vec2(1.0);
lowp float mask = 1.0 - abs(coords.y);
lowp vec3 rasterizationColor = mix(pixelLow, pixelHigh, mask);
return mix(texel, rasterizationColor, intensity);
}" : "") +
(appSettings.rasterization === appSettings.pixel_rasterization ? "
#define INTENSITY 0.30
#define BRIGHTBOOST 0.30
lowp vec3 applyRasterization(vec2 screenCoords, lowp vec3 texel, vec2 virtualResolution, float intensity) {
lowp vec3 result = texel;
lowp vec3 pixelHigh = ((1.0 + BRIGHTBOOST) - (0.2 * texel)) * texel;
lowp vec3 pixelLow = ((1.0 - INTENSITY) + (0.1 * texel)) * texel;
vec2 coords = fract(screenCoords * virtualResolution) * 2.0 - vec2(1.0);
coords = coords * coords;
lowp float mask = 1.0 - coords.x - coords.y;
lowp vec3 rasterizationColor = mix(pixelLow, pixelHigh, mask);
return mix(texel, rasterizationColor, intensity);
}" : "") +
(appSettings.rasterization === appSettings.subpixel_rasterization ? "
#define INTENSITY 0.30
#define BRIGHTBOOST 0.30
#define SUBPIXELS 3.0
const vec3 offsets = vec3(3.141592654) * vec3(1.0/2.0,1.0/2.0 - 2.0/3.0,1.0/2.0-4.0/3.0);
lowp vec3 applyRasterization(vec2 screenCoords, lowp vec3 texel, vec2 virtualResolution, float intensity) {
vec2 omega = vec2(3.141592654) * vec2(2.0) * virtualResolution;
vec2 angle = screenCoords * omega;
vec3 xfactors = (SUBPIXELS + sin(angle.x + offsets)) / (SUBPIXELS + 1.0);
lowp vec3 result = texel * xfactors;
lowp vec3 pixelHigh = ((1.0 + BRIGHTBOOST) - (0.2 * result)) * result;
lowp vec3 pixelLow = ((1.0 - INTENSITY) + (0.1 * result)) * result;
vec2 coords = fract(screenCoords * virtualResolution) * 2.0 - vec2(1.0);
lowp float mask = 1.0 - abs(coords.y);
lowp vec3 rasterizationColor = mix(pixelLow, pixelHigh, mask);
return mix(texel, rasterizationColor, intensity);
}" : "") +
"\n\n"
property string min2: "
float min2(vec2 v) {
return min(v.x, v.y);
}\n\n"
property string rgb2grey: "
float rgb2grey(vec3 v) {
return dot(v, vec3(0.21, 0.72, 0.04));
}\n\n"
property string max2: "
float max2(vec2 v) {
return max(v.x, v.y);
}\n\n"
property string prod2: "
float prod2(vec2 v) {
return v.x * v.y;
}\n\n"
property string sum2: "
float sum2(vec2 v) {
return v.x + v.y;
}\n\n"
}

View File

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2013 "Filippo Scognamiglio" * Copyright (c) 2013-2021 "Filippo Scognamiglio"
* https://github.com/Swordfish90/cool-retro-term * https://github.com/Swordfish90/cool-retro-term
* *
* This file is part of cool-retro-term. * This file is part of cool-retro-term.
@ -38,11 +38,19 @@ Item {
property real ambientLight: appSettings.ambientLight * 0.2 property real ambientLight: appSettings.ambientLight * 0.2
property size virtual_resolution property size virtualResolution
property size screenResolution
property real _screenDensity: Math.min(
screenResolution.width / virtualResolution.width,
screenResolution.height / virtualResolution.height
)
ShaderEffect { ShaderEffect {
id: dynamicShader id: dynamicShader
property ShaderLibrary shaderLibrary: ShaderLibrary { }
property ShaderEffectSource screenBuffer: frameBuffer property ShaderEffectSource screenBuffer: frameBuffer
property ShaderEffectSource burnInSource: burnInEffect.source property ShaderEffectSource burnInSource: burnInEffect.source
property ShaderEffectSource frameSource: terminalFrameLoader.item property ShaderEffectSource frameSource: terminalFrameLoader.item
@ -71,10 +79,16 @@ Item {
property size jitterDisplacement: Qt.size(0.007 * jitter, 0.002 * jitter) property size jitterDisplacement: Qt.size(0.007 * jitter, 0.002 * jitter)
property real shadowLength: 0.25 * screenCurvature * Utils.lint(0.50, 1.5, ambientLight) property real shadowLength: 0.25 * screenCurvature * Utils.lint(0.50, 1.5, ambientLight)
property real staticNoise: appSettings.staticNoise property real staticNoise: appSettings.staticNoise
property size scaleNoiseSize: Qt.size((width) / (noiseTexture.width * appSettings.windowScaling * appSettings.totalFontScaling), property size scaleNoiseSize: Qt.size((width * 0.75) / (noiseTexture.width * appSettings.windowScaling * appSettings.totalFontScaling),
(height) / (noiseTexture.height * appSettings.windowScaling * appSettings.totalFontScaling)) (height * 0.75) / (noiseTexture.height * appSettings.windowScaling * appSettings.totalFontScaling))
property size virtual_resolution: parent.virtual_resolution property size virtualResolution: parent.virtualResolution
// Rasterization might display oversamping issues if virtual resolution is close to physical display resolution.
// We progressively disable rasterization from 4x up to 2x resolution.
property real rasterizationIntensity: Utils.smoothstep(2.0, 4.0, _screenDensity)
property real displayTerminalFrame: appSettings._frameMargin > 0 || appSettings.screenCurvature > 0
property real time: timeManager.time property real time: timeManager.time
property ShaderEffectSource noiseSource: noiseShaderSource property ShaderEffectSource noiseSource: noiseShaderSource
@ -86,7 +100,7 @@ Item {
blending: false blending: false
//Smooth random texture used for flickering effect. //Smooth random texture used for flickering effect.
Image{ Image {
id: noiseTexture id: noiseTexture
source: "images/allNoise512.png" source: "images/allNoise512.png"
width: 512 width: 512
@ -94,7 +108,7 @@ Item {
fillMode: Image.Tile fillMode: Image.Tile
visible: false visible: false
} }
ShaderEffectSource{ ShaderEffectSource {
id: noiseShaderSource id: noiseShaderSource
sourceItem: noiseTexture sourceItem: noiseTexture
wrapMode: ShaderEffectSource.Repeat wrapMode: ShaderEffectSource.Repeat
@ -164,7 +178,8 @@ Item {
uniform highp vec4 backgroundColor; uniform highp vec4 backgroundColor;
uniform lowp float shadowLength; uniform lowp float shadowLength;
uniform highp vec2 virtual_resolution;" + uniform highp vec2 virtualResolution;
uniform lowp float rasterizationIntensity;\n" +
(burnIn !== 0 ? " (burnIn !== 0 ? "
uniform sampler2D burnInSource; uniform sampler2D burnInSource;
@ -174,13 +189,13 @@ Item {
uniform sampler2D slowBurnInSource;" : "") + uniform sampler2D slowBurnInSource;" : "") +
(staticNoise !== 0 ? " (staticNoise !== 0 ? "
uniform highp float staticNoise;" : "") + uniform highp float staticNoise;" : "") +
(((staticNoise !== 0 || jitter !== 0) (((staticNoise !== 0 || jitter !== 0) ||(fallBack && (flickering || horizontalSync))) ? "
||(fallBack && (flickering || horizontalSync))) ? "
uniform lowp sampler2D noiseSource; uniform lowp sampler2D noiseSource;
uniform highp vec2 scaleNoiseSize;" : "") + uniform highp vec2 scaleNoiseSize;" : "") +
(screenCurvature !== 0 ? " (displayTerminalFrame ? "
uniform highp float screenCurvature;
uniform lowp sampler2D frameSource;" : "") + uniform lowp sampler2D frameSource;" : "") +
(screenCurvature !== 0 ? "
uniform highp float screenCurvature;" : "") +
(glowingLine !== 0 ? " (glowingLine !== 0 ? "
uniform highp float glowingLine;" : "") + uniform highp float glowingLine;" : "") +
(chromaColor !== 0 ? " (chromaColor !== 0 ? "
@ -203,17 +218,14 @@ Item {
(glowingLine !== 0 ? " (glowingLine !== 0 ? "
float randomPass(vec2 coords){ float randomPass(vec2 coords){
return fract(smoothstep(-120.0, 0.0, coords.y - (virtual_resolution.y + 120.0) * fract(time * 0.00015))); return fract(smoothstep(-120.0, 0.0, coords.y - (virtualResolution.y + 120.0) * fract(time * 0.00015)));
}" : "") + }" : "") +
"float min2(vec2 v) { shaderLibrary.min2 +
return min(v.x, v.y); shaderLibrary.rgb2grey +
} shaderLibrary.rasterizationShader +
float rgb2grey(vec3 v){
return dot(v, vec3(0.21, 0.72, 0.04));
}
"
float isInScreen(vec2 v) { float isInScreen(vec2 v) {
return min2(step(0.0, v) - step(1.0, v)); return min2(step(0.0, v) - step(1.0, v));
} }
@ -291,7 +303,7 @@ Item {
color += noiseVal * noise * (1.0 - distance * 1.3);" : "") + color += noiseVal * noise * (1.0 - distance * 1.3);" : "") +
(glowingLine !== 0 ? " (glowingLine !== 0 ? "
color += randomPass(coords * virtual_resolution) * glowingLine;" : "") + color += randomPass(coords * virtualResolution) * glowingLine;" : "") +
"vec3 txt_color = texture2D(screenBuffer, txt_coords).rgb;" + "vec3 txt_color = texture2D(screenBuffer, txt_coords).rgb;" +
@ -309,6 +321,8 @@ Item {
"txt_color += fontColor.rgb * vec3(color);" + "txt_color += fontColor.rgb * vec3(color);" +
"txt_color = applyRasterization(staticCoords, txt_color, virtualResolution, rasterizationIntensity);\n" +
"vec3 finalColor = txt_color;" + "vec3 finalColor = txt_color;" +
(flickering !== 0 ? " (flickering !== 0 ? "
@ -317,7 +331,7 @@ Item {
(ambientLight !== 0 ? " (ambientLight !== 0 ? "
finalColor += vec3(ambientLight) * (1.0 - distance) * (1.0 - distance);" : "") + finalColor += vec3(ambientLight) * (1.0 - distance) * (1.0 - distance);" : "") +
(screenCurvature !== 0 ? (displayTerminalFrame ?
"vec4 frameColor = texture2D(frameSource, qt_TexCoord0); "vec4 frameColor = texture2D(frameSource, qt_TexCoord0);
finalColor = mix(finalColor, frameColor.rgb, frameColor.a);" finalColor = mix(finalColor, frameColor.rgb, frameColor.a);"
: "") + : "") +
@ -340,7 +354,7 @@ Item {
Loader { Loader {
id: terminalFrameLoader id: terminalFrameLoader
active: screenCurvature !== 0 active: dynamicShader.displayTerminalFrame
width: staticShader.width width: staticShader.width
height: staticShader.height height: staticShader.height
@ -352,7 +366,7 @@ Item {
visible: false visible: false
format: ShaderEffectSource.RGBA format: ShaderEffectSource.RGBA
NewTerminalFrame { TerminalFrame {
id: terminalFrame id: terminalFrame
blending: false blending: false
anchors.fill: parent anchors.fill: parent
@ -360,6 +374,10 @@ Item {
} }
} }
ShaderLibrary {
id: shaderLibrary
}
ShaderEffect { ShaderEffect {
id: staticShader id: staticShader
@ -385,7 +403,7 @@ Item {
property real ambientLight: parent.ambientLight property real ambientLight: parent.ambientLight
property size virtual_resolution: parent.virtual_resolution property size virtualResolution: parent.virtualResolution
blending: false blending: false
visible: false visible: false
@ -408,7 +426,7 @@ Item {
uniform highp vec4 backgroundColor; uniform highp vec4 backgroundColor;
uniform lowp float screen_brightness; uniform lowp float screen_brightness;
uniform highp vec2 virtual_resolution;" + uniform highp vec2 virtualResolution;" +
(bloom !== 0 ? " (bloom !== 0 ? "
uniform highp sampler2D bloomSource; uniform highp sampler2D bloomSource;
@ -426,36 +444,9 @@ Item {
(ambientLight !== 0 ? " (ambientLight !== 0 ? "
uniform lowp float ambientLight;" : "") + uniform lowp float ambientLight;" : "") +
"highp float getScanlineIntensity(vec2 coords) { shaderLibrary.min2 +
float result = 1.0;" + shaderLibrary.sum2 +
shaderLibrary.rgb2grey +
(appSettings.rasterization != appSettings.no_rasterization ?
"float val = 0.0;
vec2 rasterizationCoords = fract(coords * virtual_resolution);
val += smoothstep(0.0, 0.5, rasterizationCoords.y);
val -= smoothstep(0.5, 1.0, rasterizationCoords.y);
result *= mix(0.5, 1.0, val);" : "") +
(appSettings.rasterization == appSettings.pixel_rasterization ?
"val = 0.0;
val += smoothstep(0.0, 0.5, rasterizationCoords.x);
val -= smoothstep(0.5, 1.0, rasterizationCoords.x);
result *= mix(0.5, 1.0, val);" : "") + "
return result;
}
float min2(vec2 v) {
return min(v.x, v.y);
}
float sum2(vec2 v) {
return v.x + v.y;
}
float rgb2grey(vec3 v){
return dot(v, vec3(0.21, 0.72, 0.04));
}" +
"vec3 convertWithChroma(vec3 inColor) { "vec3 convertWithChroma(vec3 inColor) {
vec3 outColor = inColor;" + vec3 outColor = inColor;" +
@ -468,6 +459,7 @@ Item {
" return outColor; " return outColor;
}" + }" +
shaderLibrary.rasterizationShader +
"void main() {" + "void main() {" +
"vec2 cc = vec2(0.5) - qt_TexCoord0;" + "vec2 cc = vec2(0.5) - qt_TexCoord0;" +
@ -490,8 +482,6 @@ Item {
txt_color.b = leftColor.b * 0.30 + rightColor.b * 0.10 + txt_color.b * 0.60; txt_color.b = leftColor.b * 0.30 + rightColor.b * 0.10 + txt_color.b * 0.60;
" : "") + " : "") +
"txt_color *= getScanlineIntensity(txt_coords);" +
"txt_color += vec3(0.0001);" + "txt_color += vec3(0.0001);" +
"float greyscale_color = rgb2grey(txt_color);" + "float greyscale_color = rgb2grey(txt_color);" +

View File

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2013 "Filippo Scognamiglio" * Copyright (c) 2013-2021 "Filippo Scognamiglio"
* https://github.com/Swordfish90/cool-retro-term * https://github.com/Swordfish90/cool-retro-term
* *
* This file is part of cool-retro-term. * This file is part of cool-retro-term.
@ -17,7 +17,6 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/ *******************************************************************************/
import QtQuick 2.2 import QtQuick 2.2
import QtQuick.Controls 2.0 import QtQuick.Controls 2.0
import QtQuick.Layouts 1.1 import QtQuick.Layouts 1.1
@ -33,12 +32,12 @@ RowLayout {
id: setting_component id: setting_component
spacing: 10 spacing: 10
Slider{ Slider {
id: slider id: slider
stepSize: parent.stepSize stepSize: parent.stepSize
Layout.fillWidth: true Layout.fillWidth: true
} }
SizedLabel{ SizedLabel {
text: Math.round(value * maxMultiplier) + "%" text: Math.round(value * maxMultiplier) + "%"
} }
} }

View File

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2013 "Filippo Scognamiglio" * Copyright (c) 2013-2021 "Filippo Scognamiglio"
* https://github.com/Swordfish90/cool-retro-term * https://github.com/Swordfish90/cool-retro-term
* *
* This file is part of cool-retro-term. * This file is part of cool-retro-term.
@ -17,12 +17,12 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/ *******************************************************************************/
import QtQuick 2.2 import QtQuick 2.2
Rectangle{ Rectangle {
property size terminalSize property size terminalSize
property real topOpacity: 0.6 property real topOpacity: 0.6
width: textSize.width * 2 width: textSize.width * 2
height: textSize.height * 2 height: textSize.height * 2
radius: 5 radius: 5
@ -31,17 +31,21 @@ Rectangle{
color: "black" color: "black"
opacity: sizetimer.running ? 0.6 : 0.0 opacity: sizetimer.running ? 0.6 : 0.0
Behavior on opacity{NumberAnimation{duration: 200}} Behavior on opacity {
NumberAnimation {
duration: 200
}
}
onTerminalSizeChanged: sizetimer.restart() onTerminalSizeChanged: sizetimer.restart()
Text{ Text {
id: textSize id: textSize
anchors.centerIn: parent anchors.centerIn: parent
color: "white" color: "white"
text: terminalSize.width + "x" + terminalSize.height text: terminalSize.width + "x" + terminalSize.height
} }
Timer{ Timer {
id: sizetimer id: sizetimer
interval: 1000 interval: 1000
running: false running: false

View File

@ -1,3 +1,23 @@
/*******************************************************************************
* Copyright (c) 2013-2021 "Filippo Scognamiglio"
* https://github.com/Swordfish90/cool-retro-term
*
* This file is part of cool-retro-term.
*
* cool-retro-term is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
import QtQuick 2.0 import QtQuick 2.0
import "utils.js" as Utils import "utils.js" as Utils
@ -6,12 +26,10 @@ Loader {
property ShaderEffectSource source: item ? item.source : null property ShaderEffectSource source: item ? item.source : null
active: !appSettings.useFastBurnIn && appSettings.burnIn !== 0 active: !appSettings.useFastBurnIn && appSettings.burnIn !== 0
anchors.fill: parent anchors.fill: parent
sourceComponent: Item { sourceComponent: Item {
property alias source: burnInSourceEffect property alias source: burnInSourceEffect
property int burnInScaling: scaleTexture * appSettings.burnInQuality property int burnInScaling: scaleTexture * appSettings.burnInQuality
ShaderEffectSource { ShaderEffectSource {
@ -48,7 +66,7 @@ Loader {
} }
} }
Timer{ Timer {
id: livetimer id: livetimer
// The interval assumes 60 fps. This is the time needed burnout a white pixel. // The interval assumes 60 fps. This is the time needed burnout a white pixel.
@ -59,7 +77,7 @@ Loader {
running: true running: true
onTriggered: burnInSourceEffect.updateBurnIn = false; onTriggered: burnInSourceEffect.updateBurnIn = false;
} }
Connections{ Connections {
target: kterminal target: kterminal
onImagePainted:{ onImagePainted:{
burnInSourceEffect.scheduleUpdate(); burnInSourceEffect.scheduleUpdate();
@ -68,7 +86,7 @@ Loader {
} }
} }
// Restart blurred source settings change. // Restart blurred source settings change.
Connections{ Connections {
target: appSettings target: appSettings
onBurnInChanged: burnInSourceEffect.restartBlurSource(); onBurnInChanged: burnInSourceEffect.restartBlurSource();
onTerminalFontChanged: burnInSourceEffect.restartBlurSource(); onTerminalFontChanged: burnInSourceEffect.restartBlurSource();
@ -92,28 +110,28 @@ Loader {
fragmentShader: fragmentShader:
"#ifdef GL_ES "#ifdef GL_ES
precision mediump float; precision mediump float;
#endif\n" + #endif\n" +
"uniform lowp float qt_Opacity;" + "uniform lowp float qt_Opacity;" +
"uniform lowp sampler2D txt_source;" + "uniform lowp sampler2D txt_source;" +
"varying highp vec2 qt_TexCoord0; "varying highp vec2 qt_TexCoord0;
uniform lowp sampler2D blurredSource; uniform lowp sampler2D blurredSource;
uniform highp float burnInCoefficient;" + uniform highp float burnInCoefficient;" +
"float max3(vec3 v) { "float max3(vec3 v) {
return max (max (v.x, v.y), v.z); return max (max (v.x, v.y), v.z);
}" + }" +
"void main() {" + "void main() {" +
"vec2 coords = qt_TexCoord0;" + "vec2 coords = qt_TexCoord0;" +
"vec3 origColor = texture2D(txt_source, coords).rgb;" + "vec3 origColor = texture2D(txt_source, coords).rgb;" +
"vec3 blur_color = texture2D(blurredSource, coords).rgb - vec3(burnInCoefficient);" + "vec3 blur_color = texture2D(blurredSource, coords).rgb - vec3(burnInCoefficient);" +
"vec3 color = min(origColor + blur_color, max(origColor, blur_color));" + "vec3 color = min(origColor + blur_color, max(origColor, blur_color));" +
"gl_FragColor = vec4(color, max3(color - origColor));" + "gl_FragColor = vec4(color, max3(color - origColor));" +
"}" "}"
onStatusChanged: if (log) console.log(log) //Print warning messages onStatusChanged: if (log) console.log(log) //Print warning messages
} }

View File

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2013 "Filippo Scognamiglio" * Copyright (c) 2013-2021 "Filippo Scognamiglio"
* https://github.com/Swordfish90/cool-retro-term * https://github.com/Swordfish90/cool-retro-term
* *
* This file is part of cool-retro-term. * This file is part of cool-retro-term.
@ -27,7 +27,7 @@ QtObject {
property bool initialized: false property bool initialized: false
function getDatabase() { function getDatabase() {
return LocalStorage.openDatabaseSync("coolretroterm" + dbMajorVersion, dbMinorVersion, "StorageDatabase", 100000); return LocalStorage.openDatabaseSync("coolretroterm" + dbMajorVersion, dbMinorVersion, "StorageDatabase", 100000)
} }
function initialize() { function initialize() {
@ -35,43 +35,47 @@ QtObject {
db.transaction( db.transaction(
function(tx) { function(tx) {
tx.executeSql('CREATE TABLE IF NOT EXISTS settings(setting TEXT UNIQUE, value TEXT)'); tx.executeSql('CREATE TABLE IF NOT EXISTS settings(setting TEXT UNIQUE, value TEXT)');
}); }
)
initialized = true; initialized = true
} }
function setSetting(setting, value) { function setSetting(setting, value) {
if(!initialized) initialize(); if(!initialized) initialize();
var db = getDatabase(); var db = getDatabase();
var res = ""; var res = "";
db.transaction(function(tx) { db.transaction(
var rs = tx.executeSql('INSERT OR REPLACE INTO settings VALUES (?,?);', [setting,value]); function(tx) {
//console.log(rs.rowsAffected) var rs = tx.executeSql('INSERT OR REPLACE INTO settings VALUES (?,?);', [setting,value]);
if (rs.rowsAffected > 0) { //console.log(rs.rowsAffected)
if (rs.rowsAffected > 0) {
res = "OK"; res = "OK";
} else { } else {
res = "Error"; res = "Error";
} }
} }
); )
// The function returns OK if it was successful, or Error if it wasn't // The function returns OK if it was successful, or Error if it wasn't
return res; return res
} }
function getSetting(setting) { function getSetting(setting) {
if(!initialized) initialize(); if(!initialized) initialize();
var db = getDatabase(); var db = getDatabase();
var res=""; var res = "";
db.transaction(function(tx) { db.transaction(
var rs = tx.executeSql('SELECT value FROM settings WHERE setting=?;', [setting]); function(tx) {
if (rs.rows.length > 0) { var rs = tx.executeSql('SELECT value FROM settings WHERE setting=?;', [setting]);
res = rs.rows.item(0).value; if (rs.rows.length > 0) {
} else { res = rs.rows.item(0).value;
res = undefined; } else {
} res = undefined;
}) }
return res }
)
return res
} }
function dropSettings(){ function dropSettings(){
@ -79,6 +83,7 @@ QtObject {
db.transaction( db.transaction(
function(tx) { function(tx) {
tx.executeSql('DROP TABLE settings'); tx.executeSql('DROP TABLE settings');
}); }
)
} }
} }

View File

@ -1,3 +1,22 @@
/*******************************************************************************
* Copyright (c) 2013-2021 "Filippo Scognamiglio"
* https://github.com/Swordfish90/cool-retro-term
*
* This file is part of cool-retro-term.
*
* cool-retro-term is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
import QtQuick 2.2 import QtQuick 2.2
import QtGraphicalEffects 1.0 import QtGraphicalEffects 1.0
@ -7,44 +26,49 @@ ShaderTerminal {
property alias title: terminal.title property alias title: terminal.title
property alias terminalSize: terminal.terminalSize property alias terminalSize: terminal.terminalSize
property real devicePixelRatio: terminalWindow.screen.devicePixelRatio
id: mainShader id: mainShader
opacity: appSettings.windowOpacity * 0.3 + 0.7 opacity: appSettings.windowOpacity * 0.3 + 0.7
source: terminal.mainSource source: terminal.mainSource
burnInEffect: terminal.burnInEffect burnInEffect: terminal.burnInEffect
slowBurnInEffect: terminal.slowBurnInEffect slowBurnInEffect: terminal.slowBurnInEffect
virtual_resolution: terminal.virtualResolution virtualResolution: terminal.virtualResolution
screenResolution: Qt.size(
terminalWindow.width * devicePixelRatio * appSettings.windowScaling,
terminalWindow.height * devicePixelRatio * appSettings.windowScaling
)
TimeManager{ TimeManager {
id: timeManager id: timeManager
enableTimer: terminalWindow.visible enableTimer: terminalWindow.visible
} }
PreprocessedTerminal{ PreprocessedTerminal {
id: terminal id: terminal
anchors.fill: parent anchors.fill: parent
} }
// EFFECTS //////////////////////////////////////////////////////////////// // EFFECTS ////////////////////////////////////////////////////////////////
Loader {
Loader{
id: bloomEffectLoader id: bloomEffectLoader
active: appSettings.bloom active: appSettings.bloom
asynchronous: true asynchronous: true
width: parent.width * appSettings.bloomQuality width: parent.width * appSettings.bloomQuality
height: parent.height * appSettings.bloomQuality height: parent.height * appSettings.bloomQuality
sourceComponent: FastBlur{ sourceComponent: FastBlur {
radius: Utils.lint(16, 64, appSettings.bloomQuality); radius: Utils.lint(16, 64, appSettings.bloomQuality)
source: terminal.mainSource source: terminal.mainSource
transparentBorder: true transparentBorder: true
} }
} }
Loader{ Loader {
id: bloomSourceLoader id: bloomSourceLoader
active: appSettings.bloom !== 0 active: appSettings.bloom !== 0
asynchronous: true asynchronous: true
sourceComponent: ShaderEffectSource{ sourceComponent: ShaderEffectSource {
id: _bloomEffectSource id: _bloomEffectSource
sourceItem: bloomEffectLoader.item sourceItem: bloomEffectLoader.item
hideSource: true hideSource: true
@ -54,71 +78,4 @@ ShaderTerminal {
} }
bloomSource: bloomSourceLoader.item bloomSource: bloomSourceLoader.item
// NewTerminalFrame {
// id: terminalFrame
// anchors.fill: parent
// blending: true
// }
// This shader might be useful in the future. Since we used it only for a couple
// of calculations is probably best to move those in the main shader. If in the future
// we need to store another fullScreen channel this might be handy.
// ShaderEffect {
// id: rasterizationEffect
// width: parent.width
// height: parent.height
// property real outColor: 0.0
// property real dispX: (5 / width) * appSettings.windowScaling
// property real dispY: (5 / height) * appSettings.windowScaling
// property size virtual_resolution: terminal.virtualResolution
// blending: false
// fragmentShader:
// "uniform lowp float qt_Opacity;" +
// "varying highp vec2 qt_TexCoord0;
// uniform highp vec2 virtual_resolution;
// uniform highp float dispX;
// uniform highp float dispY;
// uniform mediump float outColor;
// highp float getScanlineIntensity(vec2 coords) {
// highp float result = 1.0;" +
// (appSettings.rasterization != appSettings.no_rasterization ?
// "result *= abs(sin(coords.y * virtual_resolution.y * "+Math.PI+"));" : "") +
// (appSettings.rasterization == appSettings.pixel_rasterization ?
// "result *= abs(sin(coords.x * virtual_resolution.x * "+Math.PI+"));" : "") + "
// return result;
// }" +
// "void main() {" +
// "highp float color = getScanlineIntensity(qt_TexCoord0);" +
// "float distance = length(vec2(0.5) - qt_TexCoord0);" +
// "color = mix(color, 0.0, 1.2 * distance * distance);" +
// "color *= outColor + smoothstep(0.00, dispX, qt_TexCoord0.x) * (1.0 - outColor);" +
// "color *= outColor + smoothstep(0.00, dispY, qt_TexCoord0.y) * (1.0 - outColor);" +
// "color *= outColor + (1.0 - smoothstep(1.00 - dispX, 1.00, qt_TexCoord0.x)) * (1.0 - outColor);" +
// "color *= outColor + (1.0 - smoothstep(1.00 - dispY, 1.00, qt_TexCoord0.y)) * (1.0 - outColor);" +
// "gl_FragColor.a = color;" +
// "}"
// onStatusChanged: if (log) console.log(log) //Print warning messages
// }
// rasterizationSource: ShaderEffectSource{
// id: rasterizationEffectSource
// sourceItem: rasterizationEffect
// hideSource: true
// smooth: true
// wrapMode: ShaderEffectSource.ClampToEdge
// visible: false
// }
} }

104
app/qml/TerminalFrame.qml Normal file
View File

@ -0,0 +1,104 @@
/*******************************************************************************
* Copyright (c) 2013-2021 "Filippo Scognamiglio"
* https://github.com/Swordfish90/cool-retro-term
*
* This file is part of cool-retro-term.
*
* cool-retro-term is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
import QtQuick 2.0
import "utils.js" as Utils
ShaderEffect {
property color _staticFrameColor: "#fff"
property color _backgroundColor: appSettings.backgroundColor
property color _fontColor: appSettings.fontColor
property color _lightColor: Utils.mix(_fontColor, _backgroundColor, 0.2)
property real _ambientLight: Utils.lint(0.2, 0.8, appSettings.ambientLight)
property color frameColor: Utils.mix(_staticFrameColor, _lightColor, _ambientLight)
property real screenCurvature: appSettings.screenCurvature * appSettings.screenCurvatureSize
// Coefficient of the log curve used to approximate shadowing
property real screenShadowCoeff: Utils.lint(20.0, 10.0, _ambientLight)
property real frameShadowCoeff: Utils.lint(20.0, 10.0, _ambientLight)
property size margin: Qt.size(
appSettings.frameMargin / width * appSettings.windowScaling,
appSettings.frameMargin / height * appSettings.windowScaling
)
ShaderLibrary {
id: shaderLibrary
}
fragmentShader: "
#ifdef GL_ES
precision mediump float;
#endif
uniform lowp float screenCurvature;
uniform lowp float screenShadowCoeff;
uniform lowp float frameShadowCoeff;
uniform highp float qt_Opacity;
uniform lowp vec4 frameColor;
uniform mediump vec2 margin;
varying highp vec2 qt_TexCoord0;
vec2 distortCoordinates(vec2 coords){
vec2 cc = (coords - vec2(0.5));
float dist = dot(cc, cc) * screenCurvature;
return (coords + cc * (1.0 + dist) * dist);
}
" +
shaderLibrary.max2 +
shaderLibrary.min2 +
shaderLibrary.prod2 +
shaderLibrary.sum2 +
"
vec2 positiveLog(vec2 x) {
return clamp(log(x), vec2(0.0), vec2(100.0));
}
void main() {
vec2 staticCoords = qt_TexCoord0;
vec2 coords = distortCoordinates(staticCoords) * (vec2(1.0) + margin * 2.0) - margin;
vec2 vignetteCoords = staticCoords * (1.0 - staticCoords.yx);
float vignette = pow(prod2(vignetteCoords) * 15.0, 0.25);
vec3 color = frameColor.rgb * vec3(1.0 - vignette);
float alpha = 0.0;
float frameShadow = max2(positiveLog(-coords * frameShadowCoeff + vec2(1.0)) + positiveLog(coords * frameShadowCoeff - (vec2(frameShadowCoeff) - vec2(1.0))));
frameShadow = max(sqrt(frameShadow), 0.0);
color *= frameShadow;
alpha = sum2(1.0 - step(vec2(0.0), coords) + step(vec2(1.0), coords));
alpha = clamp(alpha, 0.0, 1.0);
alpha *= mix(1.0, 0.9, frameShadow);
float screenShadow = 1.0 - prod2(positiveLog(coords * screenShadowCoeff + vec2(1.0)) * positiveLog(-coords * screenShadowCoeff + vec2(screenShadowCoeff + 1.0)));
alpha = max(0.8 * screenShadow, alpha);
gl_FragColor = vec4(color * alpha, alpha);
}
"
onStatusChanged: if (log) console.log(log) //Print warning messages
}

View File

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2013 "Filippo Scognamiglio" * Copyright (c) 2013-2021 "Filippo Scognamiglio"
* https://github.com/Swordfish90/cool-retro-term * https://github.com/Swordfish90/cool-retro-term
* *
* This file is part of cool-retro-term. * This file is part of cool-retro-term.
@ -17,10 +17,9 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/ *******************************************************************************/
import QtQuick 2.2 import QtQuick 2.2
Timer{ Timer {
default property bool enableTimer: false default property bool enableTimer: false
property real time property real time

View File

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2013 "Filippo Scognamiglio" * Copyright (c) 2013-2021 "Filippo Scognamiglio"
* https://github.com/Swordfish90/cool-retro-term * https://github.com/Swordfish90/cool-retro-term
* *
* This file is part of cool-retro-term. * This file is part of cool-retro-term.
@ -17,14 +17,13 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/ *******************************************************************************/
import QtQuick 2.2 import QtQuick 2.2
import QtQuick.Window 2.1 import QtQuick.Window 2.1
import QtQuick.Controls 2.3 import QtQuick.Controls 2.3
import "menus" import "menus"
ApplicationWindow{ ApplicationWindow {
id: terminalWindow id: terminalWindow
width: 1024 width: 1024
@ -37,7 +36,7 @@ ApplicationWindow{
onHeightChanged: appSettings.height = height onHeightChanged: appSettings.height = height
// Load saved window geometry and show the window // Load saved window geometry and show the window
Component.onCompleted: { Component.onCompleted: {
x = appSettings.x x = appSettings.x
y = appSettings.y y = appSettings.y
width = appSettings.width width = appSettings.width
@ -78,7 +77,7 @@ ApplicationWindow{
text: qsTr("Fullscreen") text: qsTr("Fullscreen")
enabled: Qt.platform.os !== "osx" enabled: Qt.platform.os !== "osx"
shortcut: "Alt+F11" shortcut: "Alt+F11"
onTriggered: appSettings.fullscreen = !appSettings.fullscreen; onTriggered: appSettings.fullscreen = !appSettings.fullscreen
checkable: true checkable: true
checked: appSettings.fullscreen checked: appSettings.fullscreen
} }
@ -86,68 +85,68 @@ ApplicationWindow{
id: quitAction id: quitAction
text: qsTr("Quit") text: qsTr("Quit")
shortcut: "Ctrl+Shift+Q" shortcut: "Ctrl+Shift+Q"
onTriggered: Qt.quit(); onTriggered: Qt.quit()
} }
Action{ Action {
id: showsettingsAction id: showsettingsAction
text: qsTr("Settings") text: qsTr("Settings")
onTriggered: { onTriggered: {
settingswindow.show(); settingswindow.show()
settingswindow.requestActivate(); settingswindow.requestActivate()
settingswindow.raise(); settingswindow.raise()
} }
} }
Action{ Action {
id: copyAction id: copyAction
text: qsTr("Copy") text: qsTr("Copy")
shortcut: "Ctrl+Shift+C" shortcut: "Ctrl+Shift+C"
} }
Action{ Action {
id: pasteAction id: pasteAction
text: qsTr("Paste") text: qsTr("Paste")
shortcut: "Ctrl+Shift+V" shortcut: "Ctrl+Shift+V"
} }
Action{ Action {
id: zoomIn id: zoomIn
text: qsTr("Zoom In") text: qsTr("Zoom In")
shortcut: "Ctrl++" shortcut: "Ctrl++"
onTriggered: appSettings.incrementScaling(); onTriggered: appSettings.incrementScaling()
} }
Action{ Action {
id: zoomOut id: zoomOut
text: qsTr("Zoom Out") text: qsTr("Zoom Out")
shortcut: "Ctrl+-" shortcut: "Ctrl+-"
onTriggered: appSettings.decrementScaling(); onTriggered: appSettings.decrementScaling()
} }
Action{ Action {
id: showAboutAction id: showAboutAction
text: qsTr("About") text: qsTr("About")
onTriggered: { onTriggered: {
aboutDialog.show(); aboutDialog.show()
aboutDialog.requestActivate(); aboutDialog.requestActivate()
aboutDialog.raise(); aboutDialog.raise()
} }
} }
ApplicationSettings{ ApplicationSettings {
id: appSettings id: appSettings
} }
TerminalContainer{ TerminalContainer {
id: terminalContainer id: terminalContainer
width: parent.width width: parent.width
height: (parent.height + Math.abs(y)) height: (parent.height + Math.abs(y))
} }
SettingsWindow{ SettingsWindow {
id: settingswindow id: settingswindow
visible: false visible: false
} }
AboutDialog{ AboutDialog {
id: aboutDialog id: aboutDialog
visible: false visible: false
} }
Loader{ Loader {
anchors.centerIn: parent anchors.centerIn: parent
active: appSettings.showTerminalSize active: appSettings.showTerminalSize
sourceComponent: SizeOverlay{ sourceComponent: SizeOverlay {
z: 3 z: 3
terminalSize: terminalContainer.terminalSize terminalSize: terminalContainer.terminalSize
} }

View File

@ -17,17 +17,22 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/ *******************************************************************************/
import QtQuick 2.2 import QtQuick 2.2
import QtQuick.Controls 2.3 import QtQuick.Controls 2.3
Menu{ Menu {
id: contextmenu id: contextmenu
MenuItem { action: copyAction } MenuItem {
MenuItem { action: pasteAction } action: copyAction
MenuItem { action: showsettingsAction } }
MenuItem {
action: pasteAction
}
MenuItem {
action: showsettingsAction
}
MenuSeparator { } MenuSeparator {}
Menu { Menu {
title: qsTr("File") title: qsTr("File")
@ -37,36 +42,54 @@ Menu{
} }
Menu { Menu {
title: qsTr("Edit") title: qsTr("Edit")
MenuItem {action: copyAction} MenuItem {
MenuItem {action: pasteAction} action: copyAction
MenuSeparator { } }
MenuItem {action: showsettingsAction} MenuItem {
action: pasteAction
}
MenuSeparator {}
MenuItem {
action: showsettingsAction
}
} }
Menu{ Menu {
title: qsTr("View") title: qsTr("View")
MenuItem {action: fullscreenAction; visible: fullscreenAction.enabled} MenuItem {
MenuItem {action: showMenubarAction; visible: showMenubarAction.enabled} action: fullscreenAction
MenuItem {action: zoomIn} visible: fullscreenAction.enabled
MenuItem {action: zoomOut} }
MenuItem {
action: showMenubarAction
visible: showMenubarAction.enabled
}
MenuItem {
action: zoomIn
}
MenuItem {
action: zoomOut
}
} }
Menu{ Menu {
id: profilesMenu id: profilesMenu
title: qsTr("Profiles") title: qsTr("Profiles")
Instantiator{ Instantiator {
model: appSettings.profilesList model: appSettings.profilesList
delegate: MenuItem { delegate: MenuItem {
text: model.text text: model.text
onTriggered: { onTriggered: {
appSettings.loadProfileString(obj_string); appSettings.loadProfileString(obj_string)
appSettings.handleFontChanged(); appSettings.handleFontChanged()
} }
} }
onObjectAdded: profilesMenu.insertItem(index, object) onObjectAdded: profilesMenu.insertItem(index, object)
onObjectRemoved: profilesMenu.removeItem(object) onObjectRemoved: profilesMenu.removeItem(object)
} }
} }
Menu{ Menu {
title: qsTr("Help") title: qsTr("Help")
MenuItem {action: showAboutAction} MenuItem {
action: showAboutAction
}
} }
} }

View File

@ -17,12 +17,15 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/ *******************************************************************************/
import QtQuick 2.2 import QtQuick 2.2
import QtQuick.Controls 2.3 import QtQuick.Controls 2.3
Menu{ Menu {
id: contextmenu id: contextmenu
MenuItem { action: copyAction } MenuItem {
MenuItem { action: pasteAction } action: copyAction
}
MenuItem {
action: pasteAction
}
} }

View File

@ -17,7 +17,6 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/ *******************************************************************************/
import QtQuick 2.2 import QtQuick 2.2
import QtQuick.Controls 2.3 import QtQuick.Controls 2.3
@ -27,40 +26,60 @@ MenuBar {
Menu { Menu {
title: qsTr("File") title: qsTr("File")
MenuItem {action: quitAction} MenuItem {
action: quitAction
}
} }
Menu { Menu {
title: qsTr("Edit") title: qsTr("Edit")
MenuItem {action: copyAction} MenuItem {
MenuItem {action: pasteAction} action: copyAction
MenuSeparator { } }
MenuItem {action: showsettingsAction} MenuItem {
action: pasteAction
}
MenuSeparator {}
MenuItem {
action: showsettingsAction
}
} }
Menu{ Menu {
title: qsTr("View") title: qsTr("View")
MenuItem {action: fullscreenAction; visible: fullscreenAction.enabled} MenuItem {
MenuItem {action: showMenubarAction; visible: showMenubarAction.enabled} action: fullscreenAction
MenuItem {action: zoomIn} visible: fullscreenAction.enabled
MenuItem {action: zoomOut} }
MenuItem {
action: showMenubarAction
visible: showMenubarAction.enabled
}
MenuItem {
action: zoomIn
}
MenuItem {
action: zoomOut
}
} }
Menu{ Menu {
id: profilesMenu id: profilesMenu
title: qsTr("Profiles") title: qsTr("Profiles")
Instantiator{ Instantiator {
model: appSettings.profilesList model: appSettings.profilesList
delegate: MenuItem { delegate: MenuItem {
text: model.text text: model.text
onTriggered: { onTriggered: {
appSettings.loadProfileString(obj_string); appSettings.loadProfileString(obj_string)
appSettings.handleFontChanged(); appSettings.handleFontChanged()
} }
} }
onObjectAdded: profilesMenu.insertItem(index, object) onObjectAdded: profilesMenu.insertItem(index, object)
onObjectRemoved: profilesMenu.removeItem(object) onObjectRemoved: profilesMenu.removeItem(object)
} }
} }
Menu{ Menu {
title: qsTr("Help") title: qsTr("Help")
MenuItem {action: showAboutAction} MenuItem {
action: showAboutAction
}
} }
} }

View File

@ -40,10 +40,11 @@
<file>fonts/1977-commodore-pet/PetMe.ttf</file> <file>fonts/1977-commodore-pet/PetMe.ttf</file>
<file>BurnInEffect.qml</file> <file>BurnInEffect.qml</file>
<file>fonts/modern-terminus/TerminusTTF-4.46.0.ttf</file> <file>fonts/modern-terminus/TerminusTTF-4.46.0.ttf</file>
<file>NewTerminalFrame.qml</file> <file>TerminalFrame.qml</file>
<file>SlowBurnIn.qml</file> <file>SlowBurnIn.qml</file>
<file>menus/WindowMenu.qml</file> <file>menus/WindowMenu.qml</file>
<file>menus/FullContextMenu.qml</file> <file>menus/FullContextMenu.qml</file>
<file>menus/ShortContextMenu.qml</file> <file>menus/ShortContextMenu.qml</file>
<file>ShaderLibrary.qml</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -1,3 +1,23 @@
/*******************************************************************************
* Copyright (c) 2013-2021 "Filippo Scognamiglio"
* https://github.com/Swordfish90/cool-retro-term
*
* This file is part of cool-retro-term.
*
* cool-retro-term is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
.pragma library .pragma library
function clamp(x, min, max) { function clamp(x, min, max) {
if (x <= min) if (x <= min)
@ -6,15 +26,23 @@ function clamp(x, min, max) {
return max; return max;
return x; return x;
} }
function lint(a, b, t) { function lint(a, b, t) {
return (1 - t) * a + (t) * b; return (1 - t) * a + (t) * b;
} }
function mix(c1, c2, alpha){
function mix(c1, c2, alpha) {
return Qt.rgba(c1.r * alpha + c2.r * (1-alpha), return Qt.rgba(c1.r * alpha + c2.r * (1-alpha),
c1.g * alpha + c2.g * (1-alpha), c1.g * alpha + c2.g * (1-alpha),
c1.b * alpha + c2.b * (1-alpha), c1.b * alpha + c2.b * (1-alpha),
c1.a * alpha + c2.a * (1-alpha)) c1.a * alpha + c2.a * (1-alpha))
} }
function smoothstep(min, max, value) {
let x = Math.max(0, Math.min(1, (value - min) / (max - min)));
return x * x * (3 - 2 * x);
}
function strToColor(s){ function strToColor(s){
var r = parseInt(s.substring(1,3), 16) / 256; var r = parseInt(s.substring(1,3), 16) / 256;
var g = parseInt(s.substring(3,5), 16) / 256; var g = parseInt(s.substring(3,5), 16) / 256;