Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
462831ca66 | ||
|
|
273ac3d126 | ||
|
|
4a7e23f024 | ||
|
|
84e0feb626 | ||
|
|
906e981449 | ||
|
|
d887842bdc | ||
|
|
ed701b0ac6 | ||
|
|
e9e3732b26 | ||
|
|
2f11060364 | ||
|
|
d3d1407ca7 | ||
|
|
5586c36efe | ||
|
|
4064a38998 | ||
|
|
5978a0de70 | ||
|
|
9d7efad798 | ||
|
|
d063e888a3 | ||
|
|
c612a1d586 |
13
.gitignore
vendored
@@ -35,15 +35,4 @@ Makefile*
|
||||
|
||||
*.xcf
|
||||
|
||||
# Ubuntu SDk
|
||||
*.excludes
|
||||
*.json
|
||||
|
||||
# Excludes compiled files
|
||||
imports
|
||||
cool-retro-term
|
||||
|
||||
# Mac OSX
|
||||
|
||||
.DS_Store
|
||||
*.app
|
||||
/imports/
|
||||
|
||||
4
.gitmodules
vendored
@@ -1,4 +0,0 @@
|
||||
[submodule "qmltermwidget"]
|
||||
path = qmltermwidget
|
||||
url = https://github.com/Swordfish90/qmltermwidget
|
||||
branch = 0.1.x
|
||||
180
README.md
@@ -1,59 +1,21 @@
|
||||
# cool-retro-term
|
||||
#cool-old-term
|
||||
|
||||
|> Default Amber|C:\ IBM DOS|$ Default Green|
|
||||
|---|---|---|
|
||||
||||
|
||||
|
||||
## Description
|
||||
cool-retro-term is a terminal emulator which mimics the look and feel of the old cathode tube screens.
|
||||
##Description
|
||||
cool-old-term is a terminal emulator which tries to mimic the look and feel of the old cathode tube screens.
|
||||
It has been designed to be eye-candy, customizable, and reasonably lightweight.
|
||||
|
||||
It uses the QML port of qtermwidget (Konsole) developed by me: https://github.com/Swordfish90/qmltermwidget .
|
||||
It now uses the konsole engine which is powerful and mature.
|
||||
|
||||
This terminal emulator works under Linux and macOS and requires Qt 5.2 or higher.
|
||||
This terminal emulator requires Qt 5.2 or higher to run.
|
||||
|
||||
## Screenshots
|
||||

|
||||

|
||||

|
||||
##Screenshots
|
||||

|
||||

|
||||

|
||||
|
||||
## Get cool-retro-term
|
||||
You can either build cool-retro-term yourself (see below) or walk the easy way and install one of these packages:
|
||||
##Build instructions
|
||||
|
||||
Fedora has the `cool-retro-term` in the offcial repositories. All you have to do is `sudo dnf install cool-retro-term`.
|
||||
|
||||
Users of openSUSE can grab a package from [Open Build Service](http://software.opensuse.org/package/cool-retro-term).
|
||||
|
||||
Arch users can install this [package](https://aur.archlinux.org/packages/cool-retro-term-git/) directly via the [AUR](https://aur.archlinux.org):
|
||||
|
||||
yaourt -S aur/cool-retro-term-git
|
||||
|
||||
or use:
|
||||
|
||||
pacman -S cool-retro-term
|
||||
|
||||
to install precompiled from community repository.
|
||||
|
||||
Gentoo users can now install the second release "1.0.1" from a 3rd-party repository preferably via layman:
|
||||
|
||||
USE="git" emerge app-portage/layman
|
||||
wget https://www.gerczei.eu/files/gerczei.xml -O /etc/layman/overlays/gerczei.xml
|
||||
layman -f -a qt -a gerczei # those who've added the repo before 27/08/17 should remove, update and add it again as its source has changed
|
||||
ACCEPT_KEYWORDS="~*" emerge =x11-terms/cool-retro-term-1.0.1::gerczei
|
||||
|
||||
The live ebuild (version 9999-r1) tracking the bleeding-edge WIP codebase also remains available.
|
||||
|
||||
A word of warning: USE flags and keywords are to be added to portage's configuration files and every emerge operation should be executed with '-p' (short option for --pretend) appended to the command line first as per best practice!
|
||||
|
||||
Ubuntu users of 14.04 LTS (Trusty) up to 15.10 (Wily) can use [this PPA](https://launchpad.net/~bugs-launchpad-net-falkensweb).
|
||||
|
||||
Ubuntu 17.10 can use [this PPA](https://launchpad.net/%7Evantuz/+archive/ubuntu/cool-retro-term)
|
||||
|
||||
macOS users can grab the latest dmg from the release page: https://github.com/Swordfish90/cool-retro-term/releases
|
||||
|
||||
## Build instructions (Linux)
|
||||
|
||||
## Dependencies
|
||||
##Dependencies
|
||||
Make sure to install these first.
|
||||
|
||||
---
|
||||
@@ -64,44 +26,30 @@ Make sure to install these first.
|
||||
|
||||
---
|
||||
|
||||
**Ubuntu 16.10**
|
||||
**Debian Jessie**
|
||||
|
||||
sudo apt-get install build-essential qmlscene qt5-qmake qt5-default qtdeclarative5-dev qml-module-qtquick-controls qtdeclarative5-qtquick2-plugin libqt5qml-graphicaleffects qml-module-qtquick-dialogs qtdeclarative5-localstorage-plugin qtdeclarative5-window-plugin
|
||||
|
||||
---
|
||||
|
||||
**Ubuntu 17.04**
|
||||
|
||||
sudo apt install build-essential libqt5qml-graphicaleffects qml-module-qt-labs-folderlistmodel qml-module-qt-labs-settings qml-module-qtquick-controls qml-module-qtquick-dialogs qmlscene qt5-default qt5-qmake qtdeclarative5-dev qtdeclarative5-localstorage-plugin qtdeclarative5-qtquick2-plugin qtdeclarative5-window-plugin
|
||||
|
||||
---
|
||||
|
||||
**Ubuntu 17.10**
|
||||
|
||||
sudo apt-get install build-essential qml-module-qtgraphicaleffects qml-module-qt-labs-folderlistmodel qml-module-qt-labs-settings qml-module-qtquick-controls qml-module-qtquick-dialogs qmlscene qt5-default qt5-qmake qtdeclarative5-dev qtdeclarative5-localstorage-plugin qtdeclarative5-qtquick2-plugin qtdeclarative5-window-plugin
|
||||
|
||||
---
|
||||
|
||||
**Debian Stretch and Jessie**
|
||||
|
||||
sudo apt install build-essential qmlscene qt5-qmake qt5-default qtdeclarative5-dev qml-module-qtquick-controls qml-module-qtgraphicaleffects qml-module-qtquick-dialogs qml-module-qtquick-localstorage qml-module-qtquick-window2
|
||||
|
||||
---
|
||||
|
||||
**Debian Stretch**
|
||||
|
||||
sudo apt-get install build-essential qmlscene qt5-qmake qt5-default qtdeclarative5-dev qml-module-qtquick-controls qml-module-qtgraphicaleffects qml-module-qtquick-dialogs qml-module-qtquick-localstorage qml-module-qtquick-window2 qml-module-qt-labs-settings qml-module-qt-labs-folderlistmodel
|
||||
sudo apt-get install build-essential qmlscene qt5-qmake qt5-default qtdeclarative5-dev qml-module-qtquick-controls qml-module-qtgraphicaleffects qml-module-qtquick-dialogs qml-module-qtquick-localstorage qml-module-qtquick-window2
|
||||
|
||||
---
|
||||
|
||||
**Fedora**
|
||||
This command should install the known fedora dependencies:
|
||||
|
||||
sudo yum -y install qt5-qtbase qt5-qtbase-devel qt5-qtdeclarative qt5-qtdeclarative-devel qt5-qtgraphicaleffects qt5-qtquickcontrols redhat-rpm-config
|
||||
|
||||
```
|
||||
sudo yum -y install qt5-qtbase qt5-qtbase-devel qt5-qtdeclarative qt5-qtdeclarative-devel qt5-qtgraphicaleffects qt5-qtquickcontrols
|
||||
```
|
||||
or:
|
||||
```
|
||||
sudo dnf -y install qt5-qtbase qt5-qtbase-devel qt5-qtdeclarative qt5-qtdeclarative-devel qt5-qtgraphicaleffects qt5-qtquickcontrols
|
||||
```
|
||||
|
||||
sudo dnf -y install qt5-qtbase qt5-qtbase-devel qt5-qtdeclarative qt5-qtdeclarative-devel qt5-qtgraphicaleffects qt5-qtquickcontrols redhat-rpm-config
|
||||
Compile using the following:
|
||||
```
|
||||
git clone https://github.com/Swordifish90/cool-old-term.git
|
||||
cd cool-old-term/konsole-qml-plugin
|
||||
qmake-qt5 && make && make install
|
||||
cd ..
|
||||
./cool-old-term
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -109,17 +57,23 @@ or:
|
||||
|
||||
sudo pacman -S qt5-base qt5-declarative qt5-quickcontrols qt5-graphicaleffects
|
||||
|
||||
You can also install this [package](https://aur.archlinux.org/packages/cool-old-term-git/) directly via the [AUR](https://aur.archlinux.org):
|
||||
|
||||
yaourt -S aur/cool-old-term-git
|
||||
|
||||
---
|
||||
|
||||
**openSUSE**
|
||||
**OS X**
|
||||
|
||||
Add repository with latest Qt 5 (this is only needed on openSUSE 13.1, Factory already has it):
|
||||
|
||||
sudo zypper ar http://download.opensuse.org/repositories/KDE:/Qt5/openSUSE_13.1/ KDE:Qt5
|
||||
|
||||
Install dependencies:
|
||||
|
||||
sudo zypper install libqt5-qtbase-devel libqt5-qtdeclarative-devel libqt5-qtquickcontrols libqt5-qtgraphicaleffects
|
||||
brew install qt5
|
||||
export CPPFLAGS="-I/usr/local/opt/qt5/include"
|
||||
export LDFLAGS="-L/usr/local/opt/qt5/lib"
|
||||
export PATH=/usr/local/opt/qt5/bin:$PATH
|
||||
git clone https://github.com/Swordifish90/cool-old-term.git
|
||||
git checkout osx
|
||||
qmake && make && make install
|
||||
# Have fun!
|
||||
./cool-old-term
|
||||
|
||||
---
|
||||
|
||||
@@ -128,58 +82,20 @@ Install dependencies:
|
||||
Install Qt directly from here http://qt-project.org/downloads . Once done export them in you path (replace "_/opt/Qt5.3.1/5.3/gcc_64/bin_" with your correct folder):
|
||||
|
||||
export PATH=/opt/Qt5.3.1/5.3/gcc_64/bin/:$PATH
|
||||
---
|
||||
|
||||
### Compile
|
||||
###Compile
|
||||
Once you installed all dependencies (Qt is installed and in your path) you need to compile and run the application:
|
||||
|
||||
```bash
|
||||
# Get it from GitHub
|
||||
git clone --recursive https://github.com/Swordfish90/cool-retro-term.git
|
||||
git clone https://github.com/Swordifish90/cool-old-term.git
|
||||
|
||||
# Build it
|
||||
cd cool-retro-term
|
||||
|
||||
# Compile (Fedora and OpenSUSE user should use qmake-qt5 instead of qmake)
|
||||
qmake && make
|
||||
cd cool-old-term
|
||||
cd konsole-qml-plugin
|
||||
qmake && make && make install
|
||||
cd ..
|
||||
|
||||
# Have fun!
|
||||
./cool-retro-term
|
||||
./cool-old-term
|
||||
```
|
||||
|
||||
## Build instructions (macOS)
|
||||
|
||||
1. Install [Xcode](https://developer.apple.com/xcode/) and agree to the licence agreement
|
||||
2. Enter the following commands into the terminal:
|
||||
|
||||
**Brew**
|
||||
|
||||
```sh
|
||||
brew install qt5
|
||||
git clone --recursive https://github.com/Swordfish90/cool-retro-term.git
|
||||
export CPPFLAGS="-I/usr/local/opt/qt5/include"
|
||||
export LDFLAGS="-L/usr/local/opt/qt5/lib"
|
||||
export PATH=/usr/local/opt/qt5/bin:$PATH
|
||||
cd cool-retro-term
|
||||
qmake && make
|
||||
mkdir cool-retro-term.app/Contents/PlugIns
|
||||
cp -r qmltermwidget/QMLTermWidget cool-retro-term.app/Contents/PlugIns
|
||||
open cool-retro-term.app
|
||||
```
|
||||
|
||||
**MacPorts**
|
||||
|
||||
```sh
|
||||
sudo port install qt5
|
||||
git clone --recursive https://github.com/Swordfish90/cool-retro-term.git
|
||||
cd cool-retro-term
|
||||
/opt/local/libexec/qt5/bin/qmake && make
|
||||
mkdir cool-retro-term.app/Contents/PlugIns
|
||||
cp -r qmltermwidget/QMLTermWidget cool-retro-term.app/Contents/PlugIns
|
||||
open cool-retro-term.app
|
||||
```
|
||||
|
||||
## Donations
|
||||
I made this project in my spare time because I love what I'm doing. If you are enjoying it and you want to buy me a beer click [here](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=flscogna%40gmail%2ecom&lc=IT&item_name=Filippo%20Scognamiglio¤cy_code=EUR&bn=PP%2dDonationsBF%3abtn_donate_LG%2egif%3aNonHosted).
|
||||
|
||||
You can also add "bounties" on your favourite issues. More information on the [Bountysource](https://www.bountysource.com/teams/crt/issues) page.
|
||||
|
||||
@@ -6,10 +6,8 @@ import QtQuick.Window 2.0
|
||||
Window{
|
||||
id: dialogwindow
|
||||
title: qsTr("About")
|
||||
width: 600
|
||||
height: 400
|
||||
|
||||
modality: Qt.ApplicationModal
|
||||
width: 450
|
||||
height: 300
|
||||
|
||||
ColumnLayout{
|
||||
anchors.fill: parent
|
||||
@@ -17,7 +15,7 @@ Window{
|
||||
spacing: 15
|
||||
Text {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: "cool-retro-term"
|
||||
text: "cool-old-term"
|
||||
font {bold: true; pointSize: 18}
|
||||
}
|
||||
Loader{
|
||||
@@ -65,22 +63,18 @@ Window{
|
||||
id: defaultComponent
|
||||
ColumnLayout{
|
||||
anchors.fill: parent
|
||||
anchors.margins: 10
|
||||
spacing: 10
|
||||
Image{
|
||||
Layout.fillWidth: true
|
||||
Item{
|
||||
Layout.fillHeight: true
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
fillMode: Image.PreserveAspectFit
|
||||
source: "images/crt256.png"
|
||||
smooth: true
|
||||
}
|
||||
Text{
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: appSettings.version + "\n" +
|
||||
text: shadersettings.version + "\n" +
|
||||
qsTr("Author: ") + "Filippo Scognamiglio\n" +
|
||||
qsTr("Email: ") + "flscogna@gmail.com\n" +
|
||||
qsTr("Source: ") + "https://github.com/Swordfish90/cool-retro-term\n"
|
||||
qsTr("Email: ") + "flscogna@gmail.com\n" +
|
||||
qsTr("Source: ") + "https://github.com/Swordifish90/cool-old-term\n"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -90,9 +84,9 @@ Window{
|
||||
anchors.fill: parent
|
||||
readOnly: true
|
||||
text: "Copyright (c) 2013 Filippo Scognamiglio <flscogna@gmail.com>\n\n" +
|
||||
"https://github.com/Swordfish90/cool-retro-term\n\n" +
|
||||
"https://github.com/Swordifish90/cool-old-term\n\n" +
|
||||
|
||||
"cool-retro-term is free software: you can redistribute it and/or modify " +
|
||||
"cool-old-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.\n\n" +
|
||||
359
app/ApplicationSettings.qml
Normal file
@@ -0,0 +1,359 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordifish90/cool-old-term
|
||||
*
|
||||
* This file is part of cool-old-term.
|
||||
*
|
||||
* cool-old-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
|
||||
|
||||
|
||||
|
||||
Item{
|
||||
property string version: "0.9"
|
||||
|
||||
// GENERAL SETTINGS ///////////////////////////////////////////////////
|
||||
|
||||
property bool fullscreen: false
|
||||
property bool showMenubar: true
|
||||
|
||||
property real windowOpacity: 1.0
|
||||
property real ambient_light: 0.2
|
||||
property real contrast: 0.85
|
||||
property real brightness: 0.5
|
||||
|
||||
property bool show_terminal_size: true
|
||||
|
||||
property real window_scaling: 1.0
|
||||
onWindow_scalingChanged: handleFontChanged();
|
||||
|
||||
property real fps: 0
|
||||
|
||||
function mix(c1, c2, alpha){
|
||||
return Qt.rgba(c1.r * alpha + c2.r * (1-alpha),
|
||||
c1.g * alpha + c2.g * (1-alpha),
|
||||
c1.b * alpha + c2.b * (1-alpha),
|
||||
c1.a * alpha + c2.a * (1-alpha))
|
||||
}
|
||||
function strToColor(s){
|
||||
var r = parseInt(s.substring(1,3), 16) / 256;
|
||||
var g = parseInt(s.substring(3,5), 16) / 256;
|
||||
var b = parseInt(s.substring(5,7), 16) / 256;
|
||||
return Qt.rgba(r, g, b, 1.0);
|
||||
}
|
||||
|
||||
// PROFILE SETTINGS ///////////////////////////////////////////////////////
|
||||
|
||||
property string _background_color: "#000000"
|
||||
property string _font_color: "#ff8100"
|
||||
property color font_color: mix(strToColor(_font_color), strToColor(_background_color), 0.7 + (contrast * 0.3))
|
||||
property color background_color: mix(strToColor(_background_color), strToColor(_font_color), 0.7 + (contrast * 0.3))
|
||||
|
||||
property real noise_strength: 0.1
|
||||
property real screen_distortion: 0.1
|
||||
property real glowing_line_strength: 0.2
|
||||
property real motion_blur: 0.40
|
||||
property real bloom_strength: 0.65
|
||||
|
||||
property real jitter: 0.18
|
||||
|
||||
property real horizontal_sincronization: 0.08
|
||||
property real brightness_flickering: 0.1
|
||||
|
||||
readonly property int no_rasterization: 0
|
||||
readonly property int scanline_rasterization: 1
|
||||
readonly property int pixel_rasterization: 2
|
||||
|
||||
property int rasterization: no_rasterization
|
||||
|
||||
ListModel{
|
||||
id: framelist
|
||||
ListElement{text: "No frame"; source: "./frames/NoFrame.qml"; reflections: false}
|
||||
ListElement{text: "Simple white frame"; source: "./frames/WhiteSimpleFrame.qml"; reflections: true}
|
||||
ListElement{text: "Rough black frame"; source: "./frames/BlackRoughFrame.qml"; reflections: true}
|
||||
}
|
||||
|
||||
property string frame_source: frames_list.get(frames_index).source
|
||||
property int frames_index: 1
|
||||
property var frames_list: framelist
|
||||
|
||||
|
||||
// FONTS //////////////////////////////////////////////////////////////////
|
||||
|
||||
signal terminalFontChanged(string fontSource, int pixelSize, int lineSpacing, size virtualCharSize)
|
||||
|
||||
Loader{
|
||||
id: fontManager
|
||||
|
||||
states: [
|
||||
State { when: rasterization == no_rasterization
|
||||
PropertyChanges {target: fontManager; source: "Fonts.qml" } },
|
||||
State { when: rasterization == scanline_rasterization
|
||||
PropertyChanges {target: fontManager; source: "FontScanlines.qml" } },
|
||||
State { when: rasterization == pixel_rasterization;
|
||||
PropertyChanges {target: fontManager; source: "FontPixels.qml" } }
|
||||
]
|
||||
|
||||
onLoaded: handleFontChanged()
|
||||
}
|
||||
|
||||
signal fontScalingChanged
|
||||
property var fontScalingList: fontManager.item.fontScalingList
|
||||
property var fontScalingIndexes: [5,1,1]
|
||||
|
||||
function setScalingIndex(newScaling){
|
||||
fontScalingIndexes[rasterization] = newScaling;
|
||||
fontScalingChanged();
|
||||
handleFontChanged();
|
||||
}
|
||||
|
||||
function getScalingIndex(){
|
||||
return fontScalingIndexes[rasterization];
|
||||
}
|
||||
|
||||
property var fontIndexes: [0,0,0]
|
||||
property var fontlist: fontManager.item.fontlist
|
||||
|
||||
function handleFontChanged(){
|
||||
if(!fontManager.item) return;
|
||||
fontManager.item.selectedFontIndex = fontIndexes[rasterization];
|
||||
fontManager.item.selectedScalingIndex = fontScalingIndexes[rasterization];
|
||||
|
||||
var fontSource = fontManager.item.source;
|
||||
var pixelSize = fontManager.item.pixelSize;
|
||||
var lineSpacing = fontManager.item.lineSpacing;
|
||||
var virtualCharSize = fontManager.item.virtualCharSize;
|
||||
|
||||
terminalFontChanged(fontSource, pixelSize, lineSpacing, virtualCharSize);
|
||||
}
|
||||
|
||||
// FRAMES /////////////////////////////////////////////////////////////////
|
||||
|
||||
property bool _frameReflections: true
|
||||
property bool reflectionsAllowed: framelist.get(frames_index).reflections
|
||||
property bool frameReflections: _frameReflections && reflectionsAllowed
|
||||
|
||||
property alias profiles_list: profileslist
|
||||
property int profiles_index: 0
|
||||
|
||||
// DB STORAGE /////////////////////////////////////////////////////////////
|
||||
|
||||
Storage{id: storage}
|
||||
|
||||
function composeSettingsString(){
|
||||
var settings = {
|
||||
fps: fps,
|
||||
window_scaling: window_scaling,
|
||||
show_terminal_size: show_terminal_size,
|
||||
fontScalingIndexes: fontScalingIndexes,
|
||||
fontIndexes: fontIndexes,
|
||||
frameReflections: _frameReflections,
|
||||
showMenubar: showMenubar
|
||||
}
|
||||
return JSON.stringify(settings);
|
||||
}
|
||||
|
||||
function composeProfileString(){
|
||||
var settings = {
|
||||
background_color: _background_color,
|
||||
font_color: _font_color,
|
||||
brightness_flickering: brightness_flickering,
|
||||
horizontal_sincronization: horizontal_sincronization,
|
||||
noise_strength: noise_strength,
|
||||
screen_distortion: screen_distortion,
|
||||
glowing_line_strength: glowing_line_strength,
|
||||
frames_index: frames_index,
|
||||
motion_blur: motion_blur,
|
||||
bloom_strength: bloom_strength,
|
||||
rasterization: rasterization,
|
||||
jitter: jitter,
|
||||
brightness: brightness,
|
||||
contrast: contrast,
|
||||
ambient_light: ambient_light,
|
||||
windowOpacity: windowOpacity,
|
||||
fontIndex: fontIndexes[rasterization]
|
||||
}
|
||||
return JSON.stringify(settings);
|
||||
}
|
||||
|
||||
function loadSettings(){
|
||||
var settingsString = storage.getSetting("_CURRENT_SETTINGS");
|
||||
var profileString = storage.getSetting("_CURRENT_PROFILE");
|
||||
|
||||
if(!settingsString) return;
|
||||
if(!profileString) return;
|
||||
|
||||
loadSettingsString(settingsString);
|
||||
loadProfileString(profileString);
|
||||
|
||||
console.log("Loading settings: " + settingsString + profileString);
|
||||
}
|
||||
|
||||
function storeSettings(){
|
||||
var settingsString = composeSettingsString();
|
||||
var profileString = composeProfileString();
|
||||
|
||||
storage.setSetting("_CURRENT_SETTINGS", settingsString);
|
||||
storage.setSetting("_CURRENT_PROFILE", profileString);
|
||||
|
||||
console.log("Storing settings: " + settingsString);
|
||||
console.log("Storing profile: " + profileString);
|
||||
}
|
||||
|
||||
function loadSettingsString(settingsString){
|
||||
var settings = JSON.parse(settingsString);
|
||||
|
||||
show_terminal_size = settings.show_terminal_size !== undefined ? settings.show_terminal_size : show_terminal_size
|
||||
|
||||
fps = settings.fps !== undefined ? settings.fps: fps
|
||||
window_scaling = settings.window_scaling !== undefined ? settings.window_scaling : window_scaling
|
||||
|
||||
fontIndexes = settings.fontIndexes !== undefined ? settings.fontIndexes : fontIndexes
|
||||
fontScalingIndexes = settings.fontScalingIndexes !== undefined ? settings.fontScalingIndexes : fontScalingIndexes
|
||||
|
||||
_frameReflections = settings.frameReflections !== undefined ? settings.frameReflections : _frameReflections;
|
||||
|
||||
showMenubar = settings.showMenubar !== undefined ? settings.showMenubar : showMenubar;
|
||||
}
|
||||
|
||||
function loadProfileString(profileString){
|
||||
var settings = JSON.parse(profileString);
|
||||
|
||||
_background_color = settings.background_color !== undefined ? settings.background_color : _background_color;
|
||||
_font_color = settings.font_color !== undefined ? settings.font_color : _font_color;
|
||||
|
||||
horizontal_sincronization = settings.horizontal_sincronization !== undefined ? settings.horizontal_sincronization : horizontal_sincronization
|
||||
brightness_flickering = settings.brightness_flickering !== undefined ? settings.brightness_flickering : brightness_flickering;
|
||||
noise_strength = settings.noise_strength !== undefined ? settings.noise_strength : noise_strength;
|
||||
screen_distortion = settings.screen_distortion !== undefined ? settings.screen_distortion : screen_distortion;
|
||||
glowing_line_strength = settings.glowing_line_strength !== undefined ? settings.glowing_line_strength : glowing_line_strength;
|
||||
|
||||
motion_blur = settings.motion_blur !== undefined ? settings.motion_blur : motion_blur
|
||||
bloom_strength = settings.bloom_strength !== undefined ? settings.bloom_strength : bloom_strength
|
||||
|
||||
frames_index = settings.frames_index !== undefined ? settings.frames_index : frames_index;
|
||||
|
||||
rasterization = settings.rasterization !== undefined ? settings.rasterization : rasterization;
|
||||
|
||||
jitter = settings.jitter !== undefined ? settings.jitter : jitter;
|
||||
|
||||
ambient_light = settings.ambient_light !== undefined ? settings.ambient_light : ambient_light;
|
||||
contrast = settings.contrast !== undefined ? settings.contrast : contrast;
|
||||
brightness = settings.brightness !== undefined ? settings.brightness : brightness;
|
||||
windowOpacity = settings.windowOpacity !== undefined ? settings.windowOpacity : windowOpacity;
|
||||
|
||||
fontIndexes[rasterization] = settings.fontIndex !== undefined ? settings.fontIndex : fontIndexes[rasterization];
|
||||
}
|
||||
|
||||
function storeCustomProfiles(){
|
||||
storage.setSetting("_CUSTOM_PROFILES", composeCustomProfilesString());
|
||||
}
|
||||
|
||||
function loadCustomProfiles(){
|
||||
var customProfileString = storage.getSetting("_CUSTOM_PROFILES");
|
||||
if(customProfileString === undefined) customProfileString = "[]";
|
||||
loadCustomProfilesString(customProfileString);
|
||||
}
|
||||
|
||||
function loadCustomProfilesString(customProfilesString){
|
||||
var customProfiles = JSON.parse(customProfilesString);
|
||||
for (var i=0; i<customProfiles.length; i++) {
|
||||
var profile = customProfiles[i];
|
||||
console.log("Loading custom profile: " + JSON.stringify(profile));
|
||||
profiles_list.append(profile);
|
||||
}
|
||||
}
|
||||
|
||||
function composeCustomProfilesString(){
|
||||
var customProfiles = []
|
||||
for(var i=0; i<profileslist.count; i++){
|
||||
var profile = profileslist.get(i);
|
||||
if(profile.builtin) continue;
|
||||
customProfiles.push({text: profile.text, obj_string: profile.obj_string, builtin: false})
|
||||
}
|
||||
return JSON.stringify(customProfiles);
|
||||
}
|
||||
|
||||
function loadCurrentProfile(){
|
||||
loadProfile(profiles_index);
|
||||
}
|
||||
|
||||
function loadProfile(index){
|
||||
var profile = profileslist.get(index);
|
||||
loadProfileString(profile.obj_string);
|
||||
}
|
||||
|
||||
function addNewCustomProfile(name){
|
||||
var profileString = composeProfileString();
|
||||
profileslist.append({text: name, obj_string: profileString, builtin: false});
|
||||
}
|
||||
|
||||
// PROFILES ///////////////////////////////////////////////////////////////
|
||||
|
||||
ListModel{
|
||||
id: profileslist
|
||||
ListElement{
|
||||
text: "Default Amber"
|
||||
obj_string: '{"ambient_light":0.2,"background_color":"#000000","bloom_strength":0.65,"brightness":0.5,"brightness_flickering":0.1,"contrast":0.85,"fontIndex":0,"font_color":"#ff8100","frames_index":1,"glowing_line_strength":0.2,"horizontal_sincronization":0.08,"jitter":0.18,"motion_blur":0.4,"noise_strength":0.1,"rasterization":0,"screen_distortion":0.1,"windowOpacity":1}'
|
||||
builtin: true
|
||||
}
|
||||
ListElement{
|
||||
text: "Default Green"
|
||||
obj_string: '{"ambient_light":0.2,"background_color":"#000000","bloom_strength":0.4,"brightness":0.5,"brightness_flickering":0.1,"contrast":0.85,"fontIndex":0,"font_color":"#0ccc68","frames_index":1,"glowing_line_strength":0.2,"horizontal_sincronization":0.08,"jitter":0.18,"motion_blur":0.45,"noise_strength":0.1,"rasterization":0,"screen_distortion":0.1,"windowOpacity":1}'
|
||||
builtin: true
|
||||
}
|
||||
ListElement{
|
||||
text: "Default Scanlines"
|
||||
obj_string: '{"ambient_light":0.2,"background_color":"#000000","bloom_strength":0.4,"brightness":0.5,"brightness_flickering":0.1,"contrast":0.85,"fontIndex":0,"font_color":"#00ff5b","frames_index":1,"glowing_line_strength":0.2,"horizontal_sincronization":0.07,"jitter":0.11,"motion_blur":0.4,"noise_strength":0.05,"rasterization":1,"screen_distortion":0.1,"windowOpacity":1}'
|
||||
builtin: true
|
||||
}
|
||||
ListElement{
|
||||
text: "Default Pixelated"
|
||||
obj_string: '{"ambient_light":0.2,"background_color":"#000000","bloom_strength":0.4,"brightness":0.5,"brightness_flickering":0.1,"contrast":0.85,"fontIndex":0,"font_color":"#ff8100","frames_index":1,"glowing_line_strength":0.2,"horizontal_sincronization":0.1,"jitter":0,"motion_blur":0.45,"noise_strength":0.14,"rasterization":2,"screen_distortion":0.05,"windowOpacity":1}'
|
||||
builtin: true
|
||||
}
|
||||
ListElement{
|
||||
text: "Apple ]["
|
||||
obj_string: '{"ambient_light":0.2,"background_color":"#000000","bloom_strength":0.5,"brightness":0.5,"brightness_flickering":0.2,"contrast":0.85,"fontIndex":2,"font_color":"#2fff91","frames_index":1,"glowing_line_strength":0.22,"horizontal_sincronization":0.08,"jitter":0.1,"motion_blur":0.65,"noise_strength":0.08,"rasterization":1,"screen_distortion":0.18,"windowOpacity":1}'
|
||||
builtin: true
|
||||
}
|
||||
ListElement{
|
||||
text: "Vintage"
|
||||
obj_string: '{"ambient_light":0.2,"background_color":"#000000","bloom_strength":0.4,"brightness":0.5,"brightness_flickering":0.54,"contrast":0.85,"fontIndex":0,"font_color":"#00ff3e","frames_index":2,"glowing_line_strength":0.3,"horizontal_sincronization":0.2,"jitter":0.4,"motion_blur":0.75,"noise_strength":0.2,"rasterization":1,"screen_distortion":0.1,"windowOpacity":1}'
|
||||
builtin: true
|
||||
}
|
||||
ListElement{
|
||||
text: "IBM Dos"
|
||||
obj_string: '{"ambient_light":0.2,"background_color":"#000000","bloom_strength":0.4,"brightness":0.5,"brightness_flickering":0.07,"contrast":0.85,"fontIndex":7,"font_color":"#ffffff","frames_index":1,"glowing_line_strength":0.13,"horizontal_sincronization":0,"jitter":0.08,"motion_blur":0.3,"noise_strength":0.03,"rasterization":0,"screen_distortion":0.1,"windowOpacity":1}'
|
||||
builtin: true
|
||||
}
|
||||
ListElement{
|
||||
text: "Transparent Green"
|
||||
obj_string: '{"ambient_light":0.2,"background_color":"#000000","bloom_strength":0.4549689440993788,"brightness":0.5,"brightness_flickering":0.20341614906832298,"contrast":0.85,"fontIndex":0,"font_color":"#0ccc68","frames_index":0,"glowing_line_strength":0.15993788819875776,"horizontal_sincronization":0.05045871559633028,"jitter":0.20341614906832298,"motion_blur":0.24999999999999997,"noise_strength":0.20031055900621117,"rasterization":0,"screen_distortion":0.05045871559633028,"windowOpacity":0.5956221198156681}'
|
||||
builtin: true
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
loadSettings();
|
||||
loadCustomProfiles();
|
||||
}
|
||||
Component.onDestruction: {
|
||||
storeSettings();
|
||||
storeCustomProfiles();
|
||||
//storage.dropSettings(); //DROPS THE SETTINGS!.. REMEMBER TO DISABLE ONCE ENABLED!!
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordfish90/cool-retro-term
|
||||
* https://github.com/Swordifish90/cool-old-term
|
||||
*
|
||||
* This file is part of cool-retro-term.
|
||||
* This file is part of cool-old-term.
|
||||
*
|
||||
* cool-retro-term is free software: you can redistribute it and/or modify
|
||||
* cool-old-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.
|
||||
@@ -22,53 +22,42 @@ import QtQuick 2.2
|
||||
import QtQuick.Controls 1.1
|
||||
import QtQuick.Layouts 1.1
|
||||
|
||||
import "Components"
|
||||
|
||||
RowLayout {
|
||||
property bool enabled: true
|
||||
property alias name: check.text
|
||||
|
||||
property double value
|
||||
property double value: (check.checked) ? _value : 0.0
|
||||
property alias _value: slider.value
|
||||
property alias min_value: slider.minimumValue
|
||||
property alias max_value: slider.maximumValue
|
||||
property alias stepSize: slider.stepSize
|
||||
|
||||
signal newValue(real newValue);
|
||||
|
||||
id: setting_component
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
onValueChanged: {
|
||||
check.checked = !(value == 0);
|
||||
if(check.checked)
|
||||
slider.value = value;
|
||||
}
|
||||
spacing: 25
|
||||
|
||||
CheckBox{
|
||||
id: check
|
||||
implicitWidth: 160
|
||||
onClicked: {
|
||||
if(!checked){
|
||||
checked = false;
|
||||
slider.enabled = false;
|
||||
newValue(0);
|
||||
} else {
|
||||
checked = true;
|
||||
newValue(slider.value);
|
||||
slider.enabled = true;
|
||||
}
|
||||
}
|
||||
implicitWidth: 150
|
||||
Component.onCompleted: checked = (_value !== 0);
|
||||
enabled: parent.enabled
|
||||
}
|
||||
Slider{
|
||||
id: slider
|
||||
stepSize: parent.stepSize
|
||||
Layout.fillWidth: true
|
||||
onValueChanged: {
|
||||
newValue(value);
|
||||
}
|
||||
enabled: check.checked && parent.enabled
|
||||
}
|
||||
SizedLabel {
|
||||
anchors { top: parent.top; bottom: parent.bottom }
|
||||
text: Math.round(((value - min_value) / (max_value - min_value)) * 100) + "%"
|
||||
Text{
|
||||
id: textfield
|
||||
property string unformattedText: Math.round(((value - min_value) / (max_value - min_value)) * 100)
|
||||
text: formatNumber(unformattedText)
|
||||
}
|
||||
function formatNumber(num) {
|
||||
var n = "" + num;
|
||||
while (n.length < 3) {
|
||||
n = " " + n;
|
||||
}
|
||||
return n + "%";
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordfish90/cool-retro-term
|
||||
* https://github.com/Swordifish90/cool-old-term
|
||||
*
|
||||
* This file is part of cool-retro-term.
|
||||
* This file is part of cool-old-term.
|
||||
*
|
||||
* cool-retro-term is free software: you can redistribute it and/or modify
|
||||
* cool-old-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.
|
||||
@@ -22,10 +22,8 @@ import QtQuick 2.2
|
||||
import QtQuick.Dialogs 1.1
|
||||
|
||||
Item {
|
||||
id: rootItem
|
||||
|
||||
signal colorSelected (color color)
|
||||
property color color
|
||||
property color button_color
|
||||
property string name
|
||||
|
||||
ColorDialog {
|
||||
@@ -35,13 +33,13 @@ Item {
|
||||
visible: false
|
||||
|
||||
//This is a workaround to a Qt 5.2 bug.
|
||||
onColorChanged: if (Qt.platform.os !== "osx") colorSelected(color)
|
||||
onAccepted: if (Qt.platform.os === "osx") colorSelected(color)
|
||||
onCurrentColorChanged: colorDialog.color = colorDialog.currentColor;
|
||||
onAccepted: colorSelected(color)
|
||||
}
|
||||
Rectangle{
|
||||
anchors.fill: parent
|
||||
radius: 10
|
||||
color: rootItem.color
|
||||
color: button_color
|
||||
border.color: "black"
|
||||
Glossy {}
|
||||
Rectangle {
|
||||
@@ -54,7 +52,7 @@ Item {
|
||||
Text{
|
||||
anchors.centerIn: parent
|
||||
z: parent.z + 1
|
||||
text: name + ": " + rootItem.color
|
||||
text: name + ": " + button_color
|
||||
}
|
||||
}
|
||||
MouseArea{
|
||||
71
app/FontPixels.qml
Normal file
@@ -0,0 +1,71 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordifish90/cool-old-term
|
||||
*
|
||||
* This file is part of cool-old-term.
|
||||
*
|
||||
* cool-old-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
|
||||
|
||||
Item{
|
||||
property int selectedFontIndex
|
||||
property int selectedScalingIndex
|
||||
property alias fontlist: fontlist
|
||||
property var _font: fontlist.get(selectedFontIndex)
|
||||
property var _scaling: fontScalingList[selectedScalingIndex]
|
||||
property var source: _font.source
|
||||
property var fontScalingList: [0.75, 1.0, 1.25, 1.50, 1.75, 2.0, 2.25, 2.5]
|
||||
property int pixelSize: _font.pixelSize * _scaling
|
||||
property int lineSpacing: (_font.pixelSize / _font.virtualCharHeight) * _font.lineSpacing
|
||||
property size virtualCharSize: Qt.size(_font.virtualCharWidth,
|
||||
_font.virtualCharHeight)
|
||||
|
||||
ListModel{
|
||||
id: fontlist
|
||||
ListElement{
|
||||
text: "Commodore PET (1977)"
|
||||
source: "fonts/1977-commodore-pet/COMMODORE_PET.ttf"
|
||||
lineSpacing: 2
|
||||
virtualCharWidth: 8
|
||||
virtualCharHeight: 8
|
||||
pixelSize: 32
|
||||
}
|
||||
ListElement{
|
||||
text: "Apple ][ (1977)"
|
||||
source: "fonts/1977-apple2/PrintChar21.ttf"
|
||||
lineSpacing: 2
|
||||
virtualCharWidth: 7
|
||||
virtualCharHeight: 8
|
||||
pixelSize: 32
|
||||
}
|
||||
ListElement{
|
||||
text: "Atari 400-800 (1979)"
|
||||
source: "fonts/1979-atari-400-800/ATARI400800_original.TTF"
|
||||
lineSpacing: 3
|
||||
virtualCharWidth: 8
|
||||
virtualCharHeight: 8
|
||||
pixelSize: 32
|
||||
}
|
||||
ListElement{
|
||||
text: "Commodore 64 (1982)"
|
||||
source: "fonts/1982-commodore64/C64_User_Mono_v1.0-STYLE.ttf"
|
||||
lineSpacing: 3
|
||||
virtualCharWidth: 8
|
||||
virtualCharHeight: 8
|
||||
pixelSize: 32
|
||||
}
|
||||
}
|
||||
}
|
||||
79
app/FontScanlines.qml
Normal file
@@ -0,0 +1,79 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordifish90/cool-old-term
|
||||
*
|
||||
* This file is part of cool-old-term.
|
||||
*
|
||||
* cool-old-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
|
||||
|
||||
Item{
|
||||
property int selectedFontIndex
|
||||
property int selectedScalingIndex
|
||||
property alias fontlist: fontlist
|
||||
property var _font: fontlist.get(selectedFontIndex)
|
||||
property var _scaling: fontScalingList[selectedScalingIndex]
|
||||
property var source: _font.source
|
||||
property var fontScalingList: [0.75, 1.0, 1.25, 1.50, 1.75, 2.0, 2.25, 2.50]
|
||||
property int pixelSize: _font.pixelSize * _scaling
|
||||
property int lineSpacing: (_font.pixelSize / _font.virtualCharHeight) * _font.lineSpacing
|
||||
property size virtualCharSize: Qt.size(_font.virtualCharWidth,
|
||||
_font.virtualCharHeight)
|
||||
|
||||
ListModel{
|
||||
id: fontlist
|
||||
ListElement{
|
||||
text: "Commodore PET 2Y (1977)"
|
||||
source: "fonts/1977-commodore-pet/COMMODORE_PET_2y.ttf"
|
||||
lineSpacing: 2
|
||||
virtualCharWidth: 4
|
||||
virtualCharHeight: 8
|
||||
pixelSize: 32
|
||||
}
|
||||
ListElement{
|
||||
text: "Commodore PET (1977)"
|
||||
source: "fonts/1977-commodore-pet/COMMODORE_PET.ttf"
|
||||
lineSpacing: 2
|
||||
virtualCharWidth: 8
|
||||
virtualCharHeight: 8
|
||||
pixelSize: 32
|
||||
}
|
||||
ListElement{
|
||||
text: "Apple ][ (1977)"
|
||||
source: "fonts/1977-apple2/PrintChar21.ttf"
|
||||
lineSpacing: 2
|
||||
virtualCharWidth: 8
|
||||
virtualCharHeight: 8
|
||||
pixelSize: 32
|
||||
}
|
||||
ListElement{
|
||||
text: "Atari 400-800 (1979)"
|
||||
source: "fonts/1979-atari-400-800/ATARI400800_original.TTF"
|
||||
lineSpacing: 3
|
||||
virtualCharWidth: 8
|
||||
virtualCharHeight: 8
|
||||
pixelSize: 32
|
||||
}
|
||||
ListElement{
|
||||
text: "Commodore 64 (1982)"
|
||||
source: "fonts/1982-commodore64/C64_User_Mono_v1.0-STYLE.ttf"
|
||||
lineSpacing: 3
|
||||
virtualCharWidth: 8
|
||||
virtualCharHeight: 8
|
||||
pixelSize: 32
|
||||
}
|
||||
}
|
||||
}
|
||||
87
app/Fonts.qml
Normal file
@@ -0,0 +1,87 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordifish90/cool-old-term
|
||||
*
|
||||
* This file is part of cool-old-term.
|
||||
*
|
||||
* cool-old-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
|
||||
|
||||
Item{
|
||||
property int selectedFontIndex
|
||||
property int selectedScalingIndex
|
||||
property alias fontlist: fontlist
|
||||
property var source: fontlist.get(selectedFontIndex).source
|
||||
property var _font: fontlist.get(selectedFontIndex)
|
||||
property var _scaling: fontScalingList[selectedScalingIndex]
|
||||
property var fontScalingList: [0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5]
|
||||
property int pixelSize: _font.pixelSize * _scaling
|
||||
property int lineSpacing: pixelSize * _font.lineSpacing
|
||||
|
||||
//In this configuration lineSpacing is proportional to pixelSize.
|
||||
|
||||
ListModel{
|
||||
id: fontlist
|
||||
ListElement{
|
||||
text: "Terminus (Modern)"
|
||||
source: "fonts/modern-terminus/TerminusTTF-Bold-4.38.2.ttf"
|
||||
lineSpacing: 0.2
|
||||
pixelSize: 35
|
||||
}
|
||||
ListElement{
|
||||
text: "Commodore PET (1977)"
|
||||
source: "fonts/1977-commodore-pet/COMMODORE_PET.ttf"
|
||||
lineSpacing: 0.2
|
||||
pixelSize: 24
|
||||
}
|
||||
ListElement{
|
||||
text: "Commodore PET 2Y (1977)"
|
||||
source: "fonts/1977-commodore-pet/COMMODORE_PET_2y.ttf"
|
||||
lineSpacing: 0.2
|
||||
pixelSize: 32
|
||||
}
|
||||
ListElement{
|
||||
text: "Apple ][ (1977)"
|
||||
source: "fonts/1977-apple2/PrintChar21.ttf"
|
||||
lineSpacing: 0.2
|
||||
pixelSize: 24
|
||||
}
|
||||
ListElement{
|
||||
text: "Atari 400-800 (1979)"
|
||||
source: "fonts/1979-atari-400-800/ATARI400800_original.TTF"
|
||||
lineSpacing: 0.3
|
||||
pixelSize: 24
|
||||
}
|
||||
ListElement{
|
||||
text: "Commodore 64 (1982)"
|
||||
source: "fonts/1982-commodore64/C64_User_Mono_v1.0-STYLE.ttf"
|
||||
lineSpacing: 0.3
|
||||
pixelSize: 24
|
||||
}
|
||||
ListElement{
|
||||
text: "Atari ST (1985)"
|
||||
source: "fonts/1985-atari-st/AtariST8x16SystemFont.ttf"
|
||||
lineSpacing: 0.2
|
||||
pixelSize: 32
|
||||
}
|
||||
ListElement{
|
||||
text: "IBM DOS (1985)"
|
||||
source: "fonts/1985-ibm-pc-vga/Perfect DOS VGA 437.ttf"
|
||||
lineSpacing: 0.2
|
||||
pixelSize: 32
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordfish90/cool-retro-term
|
||||
* https://github.com/Swordifish90/cool-old-term
|
||||
*
|
||||
* This file is part of cool-retro-term.
|
||||
* This file is part of cool-old-term.
|
||||
*
|
||||
* cool-retro-term is free software: you can redistribute it and/or modify
|
||||
* cool-old-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.
|
||||
@@ -22,36 +22,16 @@ import QtQuick 2.2
|
||||
import QtQuick.Window 2.0
|
||||
import QtQuick.Controls 1.1
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtQuick.Dialogs 1.1
|
||||
|
||||
Window{
|
||||
id: insertnamedialog
|
||||
width: 400
|
||||
height: 100
|
||||
modality: Qt.ApplicationModal
|
||||
title: qsTr("Save new profile")
|
||||
title: qsTr("Save current profile")
|
||||
|
||||
property alias profileName: namefield.text
|
||||
signal nameSelected(string name)
|
||||
|
||||
MessageDialog {
|
||||
id: errorDialog
|
||||
title: qsTr("Error")
|
||||
visible: false
|
||||
|
||||
function showError(message){
|
||||
text = message;
|
||||
open();
|
||||
}
|
||||
}
|
||||
|
||||
function validateName(name){
|
||||
var profile_list = appSettings.profilesList;
|
||||
if (name === "")
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ColumnLayout{
|
||||
anchors.margins: 10
|
||||
anchors.fill: parent
|
||||
@@ -61,26 +41,16 @@ Window{
|
||||
id: namefield
|
||||
Layout.fillWidth: true
|
||||
Component.onCompleted: forceActiveFocus()
|
||||
onAccepted: okbutton.clickAction()
|
||||
}
|
||||
}
|
||||
RowLayout{
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
Button{
|
||||
id: okbutton
|
||||
text: qsTr("OK")
|
||||
onClicked: clickAction()
|
||||
function clickAction(){
|
||||
var name = namefield.text;
|
||||
switch(validateName(name)){
|
||||
case 1:
|
||||
errorDialog.showError(qsTr("The name you inserted is empty. Please choose a different one."));
|
||||
break;
|
||||
default:
|
||||
nameSelected(name);
|
||||
close();
|
||||
}
|
||||
onClicked: {
|
||||
nameSelected(namefield.text);
|
||||
close();
|
||||
}
|
||||
}
|
||||
Button{
|
||||
426
app/PreprocessedTerminal.qml
Normal file
@@ -0,0 +1,426 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordifish90/cool-old-term
|
||||
*
|
||||
* This file is part of cool-old-term.
|
||||
*
|
||||
* cool-old-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 QtGraphicalEffects 1.0
|
||||
import QtQuick.Controls 1.1
|
||||
|
||||
import org.kde.konsole 0.1
|
||||
|
||||
Item{
|
||||
id: terminalContainer
|
||||
property variant theSource: finalSource
|
||||
property variant bloomSource: bloomSourceLoader.item
|
||||
property variant rasterizationSource: rasterizationEffectSource
|
||||
property variant staticNoiseSource: staticNoiseSource
|
||||
|
||||
property alias kterminal: kterminal
|
||||
|
||||
signal sizeChanged
|
||||
onWidthChanged: sizeChanged()
|
||||
onHeightChanged: sizeChanged()
|
||||
|
||||
//The blur effect has to take into account the framerate
|
||||
property int fps: shadersettings.fps !== 0 ? shadersettings.fps : 60
|
||||
property real fpsAttenuation: Math.sqrt(60 / fps)
|
||||
property real mBlur: shadersettings.motion_blur
|
||||
property real motionBlurCoefficient: (_maxBlurCoefficient * mBlur + _minBlurCoefficient * (1 - mBlur))
|
||||
property real _minBlurCoefficient: 0.70
|
||||
property real _maxBlurCoefficient: 0.90
|
||||
|
||||
property size virtualPxSize: Qt.size(1,1)
|
||||
property size virtual_resolution: Qt.size(width / virtualPxSize.width, height / virtualPxSize.height)
|
||||
property real deltay: 0.5 / virtual_resolution.height
|
||||
property real deltax: 0.5 / virtual_resolution.width
|
||||
|
||||
property real mBloom: shadersettings.bloom_strength
|
||||
property int mScanlines: shadersettings.rasterization
|
||||
onMScanlinesChanged: restartBlurredSource()
|
||||
|
||||
property size terminalSize: kterminal.terminalSize
|
||||
property size paintedTextSize
|
||||
|
||||
onMBlurChanged: restartBlurredSource()
|
||||
|
||||
function restartBlurredSource(){
|
||||
if(!blurredSource) return;
|
||||
blurredSource.live = true;
|
||||
livetimer.restart()
|
||||
}
|
||||
function pasteClipboard(){
|
||||
kterminal.pasteClipboard();
|
||||
}
|
||||
function copyClipboard(){
|
||||
kterminal.copyClipboard();
|
||||
}
|
||||
|
||||
KTerminal {
|
||||
id: kterminal
|
||||
anchors.fill: parent
|
||||
|
||||
colorScheme: "cool-old-term"
|
||||
|
||||
session: KSession {
|
||||
id: ksession
|
||||
kbScheme: "linux"
|
||||
|
||||
onFinished: {
|
||||
Qt.quit()
|
||||
}
|
||||
}
|
||||
|
||||
FontLoader{ id: fontLoader }
|
||||
Text{id: fontMetrics; text: "B"; visible: false}
|
||||
|
||||
function getPaintedSize(pixelSize){
|
||||
fontMetrics.font.family = fontLoader.name;
|
||||
fontMetrics.font.pixelSize = pixelSize;
|
||||
return Qt.size(fontMetrics.paintedWidth, fontMetrics.paintedHeight);
|
||||
}
|
||||
function isValid(size){
|
||||
return size.width >= 0 && size.height >= 0;
|
||||
}
|
||||
function handleFontChange(fontSource, pixelSize, lineSpacing, virtualCharSize){
|
||||
fontLoader.source = fontSource;
|
||||
font.pixelSize = pixelSize * shadersettings.window_scaling;
|
||||
font.family = fontLoader.name;
|
||||
|
||||
var paintedSize = getPaintedSize(pixelSize);
|
||||
var charSize = isValid(virtualCharSize)
|
||||
? virtualCharSize
|
||||
: Qt.size(paintedSize.width / 2, paintedSize.height / 2);
|
||||
|
||||
var virtualPxSize = Qt.size((paintedSize.width / charSize.width) * shadersettings.window_scaling,
|
||||
(paintedSize.height / charSize.height) * shadersettings.window_scaling)
|
||||
|
||||
terminalContainer.virtualPxSize = virtualPxSize;
|
||||
|
||||
setLineSpacing(lineSpacing * shadersettings.window_scaling);
|
||||
restartBlurredSource();
|
||||
}
|
||||
Component.onCompleted: {
|
||||
shadersettings.terminalFontChanged.connect(handleFontChange);
|
||||
forceActiveFocus();
|
||||
}
|
||||
}
|
||||
Menu{
|
||||
id: contextmenu
|
||||
|
||||
MenuItem{action: copyAction}
|
||||
MenuItem{action: pasteAction}
|
||||
MenuSeparator{}
|
||||
MenuItem{action: fullscreenAction}
|
||||
MenuItem{action: showMenubarAction}
|
||||
}
|
||||
MouseArea{
|
||||
acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton
|
||||
anchors.fill: parent
|
||||
onWheel:{
|
||||
var coord = correctDistortion(wheel.x, wheel.y);
|
||||
var lines = wheel.angleDelta.y > 0 ? -2 : 2;
|
||||
kterminal.scrollWheel(coord.width, coord.height, lines);
|
||||
}
|
||||
onClicked: {
|
||||
if (mouse.button == Qt.RightButton){
|
||||
contextmenu.popup();
|
||||
} else if (mouse.button == Qt.MiddleButton){
|
||||
kterminal.pasteSelection();
|
||||
}
|
||||
}
|
||||
onDoubleClicked: {
|
||||
if (mouse.button == Qt.LeftButton){
|
||||
var coord = correctDistortion(mouse.x, mouse.y);
|
||||
kterminal.mouseDoubleClick(coord.width, coord.height);
|
||||
}
|
||||
}
|
||||
onPositionChanged: {
|
||||
if (pressedButtons & Qt.LeftButton){
|
||||
var coord = correctDistortion(mouse.x, mouse.y);
|
||||
kterminal.mouseMove(coord.width, coord.height);
|
||||
}
|
||||
}
|
||||
onPressed: {
|
||||
if (mouse.button == Qt.LeftButton){
|
||||
var coord = correctDistortion(mouse.x, mouse.y);
|
||||
kterminal.mousePress(coord.width, coord.height);
|
||||
}
|
||||
}
|
||||
onReleased: {
|
||||
if (mouse.button == Qt.LeftButton){
|
||||
var coord = correctDistortion(mouse.x, mouse.y);
|
||||
kterminal.mouseRelease(coord.width, coord.height);
|
||||
}
|
||||
}
|
||||
|
||||
//Frame displacement properties
|
||||
property real dtop: frame.item.displacementTop
|
||||
property real dleft:frame.item.displacementLeft
|
||||
property real dright: frame.item.displacementRight
|
||||
property real dbottom: frame.item.displacementBottom
|
||||
|
||||
function correctDistortion(x, y){
|
||||
x = x / width;
|
||||
y = y / height;
|
||||
|
||||
x = (-dleft + x * (width + dleft + dright)) / width
|
||||
y = (-dtop + y * (height + dtop + dbottom)) / height
|
||||
|
||||
var cc = Qt.size(0.5 - x, 0.5 - y);
|
||||
var distortion = (cc.height * cc.height + cc.width * cc.width) * shadersettings.screen_distortion;
|
||||
|
||||
return Qt.size((x - cc.width * (1+distortion) * distortion) * width,
|
||||
(y - cc.height * (1+distortion) * distortion) * height)
|
||||
}
|
||||
}
|
||||
ShaderEffectSource{
|
||||
id: source
|
||||
sourceItem: kterminal
|
||||
hideSource: true
|
||||
smooth: false
|
||||
}
|
||||
ShaderEffectSource{
|
||||
id: blurredSource
|
||||
sourceItem: blurredterminal
|
||||
recursive: true
|
||||
live: false
|
||||
|
||||
hideSource: true
|
||||
|
||||
smooth: false
|
||||
antialiasing: false
|
||||
|
||||
Timer{
|
||||
id: livetimer
|
||||
running: true
|
||||
onRunningChanged: running ?
|
||||
timeManager.onTimeChanged.connect(blurredSource.scheduleUpdate) :
|
||||
timeManager.onTimeChanged.disconnect(blurredSource.scheduleUpdate)
|
||||
|
||||
Component.onCompleted: kterminal.updatedImage.connect(restart);
|
||||
}
|
||||
}
|
||||
ShaderEffectSource{
|
||||
id: finalSource
|
||||
sourceItem: blurredterminal
|
||||
sourceRect: frame.sourceRect
|
||||
//format: ShaderEffectSource.Alpha
|
||||
hideSource: true
|
||||
}
|
||||
ShaderEffect {
|
||||
id: blurredterminal
|
||||
anchors.fill: parent
|
||||
property variant source: source
|
||||
property variant blurredSource: (mBlur !== 0) ? blurredSource : undefined
|
||||
property size virtual_resolution: parent.virtual_resolution
|
||||
property size delta: Qt.size((mScanlines == shadersettings.pixel_rasterization ? deltax : 0),
|
||||
mScanlines != shadersettings.no_rasterization ? deltay : 0)
|
||||
blending: false
|
||||
|
||||
fragmentShader:
|
||||
"uniform lowp float qt_Opacity;" +
|
||||
"uniform lowp sampler2D source;" +
|
||||
"uniform highp vec2 delta;" +
|
||||
|
||||
"varying highp vec2 qt_TexCoord0;
|
||||
|
||||
uniform highp vec2 virtual_resolution;" +
|
||||
|
||||
(mBlur !== 0 ?
|
||||
"uniform lowp sampler2D blurredSource;"
|
||||
: "") +
|
||||
|
||||
"void main() {" +
|
||||
"vec2 coords = qt_TexCoord0;" +
|
||||
(mScanlines != shadersettings.no_rasterization ? "
|
||||
coords.y = floor(virtual_resolution.y * coords.y) / virtual_resolution.y;" +
|
||||
(mScanlines == shadersettings.pixel_rasterization ? "
|
||||
coords.x = floor(virtual_resolution.x * coords.x) / virtual_resolution.x;" : "")
|
||||
: "") +
|
||||
"coords = coords + delta;" +
|
||||
"vec4 vcolor = texture2D(source, coords) * 256.0;
|
||||
float color = vcolor.r * 0.21 + vcolor.g * 0.72 + vcolor.b + 0.04;" +
|
||||
(mBlur !== 0 ?
|
||||
"float blurredSourceColor = texture2D(blurredSource, coords).a * 256.0;" +
|
||||
"blurredSourceColor = blurredSourceColor - blurredSourceColor * " + (1.0 - motionBlurCoefficient) * fpsAttenuation+ ";" +
|
||||
"color = step(1.0, color) * color + step(color, 1.0) * blurredSourceColor;"
|
||||
: "") +
|
||||
|
||||
|
||||
"gl_FragColor.a = floor(color) / 256.0;" +
|
||||
"}"
|
||||
|
||||
onStatusChanged: if (log) console.log(log) //Print warning messages
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// EFFECTS //////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// BLOOM ////////////////////////////////////////////////////////////////
|
||||
|
||||
Loader{
|
||||
id: bloomEffectLoader
|
||||
active: mBloom != 0
|
||||
anchors.fill: parent
|
||||
sourceComponent: FastBlur{
|
||||
radius: 48
|
||||
source: kterminal
|
||||
transparentBorder: true
|
||||
smooth: false
|
||||
}
|
||||
}
|
||||
Loader{
|
||||
id: bloomSourceLoader
|
||||
active: mBloom != 0
|
||||
sourceComponent: ShaderEffectSource{
|
||||
sourceItem: bloomEffectLoader.item
|
||||
hideSource: true
|
||||
sourceRect: frame.sourceRect
|
||||
smooth: false
|
||||
}
|
||||
}
|
||||
|
||||
// NOISE ////////////////////////////////////////////////////////////////
|
||||
|
||||
ShaderEffect {
|
||||
id: staticNoiseEffect
|
||||
anchors.fill: parent
|
||||
property size virtual_resolution: terminalContainer.virtual_resolution
|
||||
|
||||
blending: false
|
||||
|
||||
fragmentShader:
|
||||
"uniform lowp float qt_Opacity;
|
||||
varying highp vec2 qt_TexCoord0;
|
||||
uniform highp vec2 virtual_resolution;" +
|
||||
|
||||
"highp float noise(vec2 co)
|
||||
{
|
||||
highp float a = 12.9898;
|
||||
highp float b = 78.233;
|
||||
highp float c = 43758.5453;
|
||||
highp float dt= dot(co.xy ,vec2(a,b));
|
||||
highp float sn= mod(dt,3.14);
|
||||
return fract(sin(sn) * c);
|
||||
}
|
||||
|
||||
vec2 sw(vec2 p) {return vec2( floor(p.x) , floor(p.y) );}
|
||||
vec2 se(vec2 p) {return vec2( ceil(p.x) , floor(p.y) );}
|
||||
vec2 nw(vec2 p) {return vec2( floor(p.x) , ceil(p.y) );}
|
||||
vec2 ne(vec2 p) {return vec2( ceil(p.x) , ceil(p.y) );}
|
||||
|
||||
float smoothNoise(vec2 p) {
|
||||
vec2 inter = smoothstep(0., 1., fract(p));
|
||||
float s = mix(noise(sw(p)), noise(se(p)), inter.x);
|
||||
float n = mix(noise(nw(p)), noise(ne(p)), inter.x);
|
||||
return mix(s, n, inter.y);
|
||||
}" +
|
||||
|
||||
"void main() {" +
|
||||
"gl_FragColor.a = smoothNoise(qt_TexCoord0 * virtual_resolution);" +
|
||||
"}"
|
||||
|
||||
onStatusChanged: if (log) console.log(log) //Print warning messages
|
||||
}
|
||||
ShaderEffectSource{
|
||||
id: staticNoiseSource
|
||||
sourceItem: staticNoiseEffect
|
||||
textureSize: Qt.size(parent.width, parent.height)
|
||||
wrapMode: ShaderEffectSource.Repeat
|
||||
smooth: true
|
||||
hideSource: true
|
||||
//format: ShaderEffectSource.Alpha
|
||||
}
|
||||
|
||||
// RASTERIZATION //////////////////////////////////////////////////////////
|
||||
|
||||
ShaderEffect{
|
||||
id: rasterizationContainer
|
||||
width: frame.sourceRect.width
|
||||
height: frame.sourceRect.height
|
||||
property size offset: Qt.size(width - rasterizationEffect.width, height - rasterizationEffect.height)
|
||||
property size txtRes: Qt.size(width, height)
|
||||
|
||||
blending: false
|
||||
|
||||
fragmentShader:
|
||||
"uniform lowp float qt_Opacity;
|
||||
uniform highp vec2 offset;
|
||||
uniform highp vec2 txtRes;" +
|
||||
|
||||
"varying highp vec2 qt_TexCoord0;" +
|
||||
|
||||
"void main() {" +
|
||||
"float color = 1.0;
|
||||
color *= smoothstep(0.0, offset.x / txtRes.x, qt_TexCoord0.x);
|
||||
color *= smoothstep(0.0, offset.y / txtRes.y, qt_TexCoord0.y);
|
||||
color *= smoothstep(0.0, offset.x / txtRes.x, 1.0 - qt_TexCoord0.x);
|
||||
color *= smoothstep(0.0, offset.y / txtRes.y, 1.0 - qt_TexCoord0.y);" +
|
||||
|
||||
"float distance = length(vec2(0.5) - qt_TexCoord0);" +
|
||||
"color = mix(color, 0.0, 1.2 * distance * distance);" +
|
||||
|
||||
"gl_FragColor.a = color;" +
|
||||
"}"
|
||||
|
||||
ShaderEffect {
|
||||
id: rasterizationEffect
|
||||
width: terminalContainer.width
|
||||
height: terminalContainer.height
|
||||
anchors.centerIn: parent
|
||||
property size virtual_resolution: terminalContainer.virtual_resolution
|
||||
|
||||
blending: false
|
||||
|
||||
fragmentShader:
|
||||
"uniform lowp float qt_Opacity;" +
|
||||
|
||||
"varying highp vec2 qt_TexCoord0;
|
||||
uniform highp vec2 virtual_resolution;
|
||||
|
||||
float getScanlineIntensity(vec2 coords) {
|
||||
float result = 1.0;" +
|
||||
(mScanlines != shadersettings.no_rasterization ?
|
||||
"result *= abs(sin(coords.y * virtual_resolution.y * "+Math.PI+"));" : "") +
|
||||
(mScanlines == shadersettings.pixel_rasterization ?
|
||||
"result *= abs(sin(coords.x * virtual_resolution.x * "+Math.PI+"));" : "") + "
|
||||
return result;
|
||||
}" +
|
||||
|
||||
"void main() {" +
|
||||
"float color = getScanlineIntensity(qt_TexCoord0);" +
|
||||
|
||||
"float distance = length(vec2(0.5) - qt_TexCoord0);" +
|
||||
"color = mix(color, 0.0, 1.2 * distance * distance);" +
|
||||
|
||||
"gl_FragColor.a = color;" +
|
||||
"}"
|
||||
|
||||
onStatusChanged: if (log) console.log(log) //Print warning messages
|
||||
}
|
||||
onStatusChanged: if (log) console.log(log) //Print warning messages
|
||||
}
|
||||
ShaderEffectSource{
|
||||
id: rasterizationEffectSource
|
||||
sourceItem: rasterizationContainer
|
||||
hideSource: true
|
||||
smooth: true
|
||||
//format: ShaderEffectSource.Alpha
|
||||
}
|
||||
}
|
||||
79
app/SettingsEffectsTab.qml
Normal file
@@ -0,0 +1,79 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordifish90/cool-old-term
|
||||
*
|
||||
* This file is part of cool-old-term.
|
||||
*
|
||||
* cool-old-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.Controls 1.1
|
||||
import QtQuick.Layouts 1.1
|
||||
|
||||
Tab{
|
||||
GroupBox{
|
||||
title: qsTr("Effects")
|
||||
anchors.fill: parent
|
||||
ColumnLayout{
|
||||
anchors.fill: parent
|
||||
CheckableSlider{
|
||||
name: qsTr("Bloom")
|
||||
onValueChanged: shadersettings.bloom_strength = value
|
||||
_value: shadersettings.bloom_strength
|
||||
}
|
||||
CheckableSlider{
|
||||
name: qsTr("Motion Blur")
|
||||
onValueChanged: shadersettings.motion_blur = value
|
||||
_value: shadersettings.motion_blur
|
||||
}
|
||||
CheckableSlider{
|
||||
name: qsTr("Noise")
|
||||
onValueChanged: shadersettings.noise_strength = value
|
||||
_value: shadersettings.noise_strength
|
||||
}
|
||||
CheckableSlider{
|
||||
name: qsTr("Jitter")
|
||||
onValueChanged: shadersettings.jitter = value
|
||||
_value: shadersettings.jitter
|
||||
}
|
||||
CheckableSlider{
|
||||
name: qsTr("Glow")
|
||||
onValueChanged: shadersettings.glowing_line_strength = value;
|
||||
_value: shadersettings.glowing_line_strength
|
||||
}
|
||||
CheckableSlider{
|
||||
name: qsTr("Screen distortion")
|
||||
onValueChanged: shadersettings.screen_distortion = value;
|
||||
_value: shadersettings.screen_distortion;
|
||||
}
|
||||
CheckableSlider{
|
||||
name: qsTr("Ambient light")
|
||||
onValueChanged: shadersettings.ambient_light = value;
|
||||
_value: shadersettings.ambient_light
|
||||
enabled: shadersettings.frames_index !== 0
|
||||
}
|
||||
CheckableSlider{
|
||||
name: qsTr("Brightness flickering")
|
||||
onValueChanged: shadersettings.brightness_flickering= value;
|
||||
_value: shadersettings.brightness_flickering;
|
||||
}
|
||||
CheckableSlider{
|
||||
name: qsTr("Horizontal flickering")
|
||||
onValueChanged: shadersettings.horizontal_sincronization = value;
|
||||
_value: shadersettings.horizontal_sincronization;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
141
app/SettingsGeneralTab.qml
Normal file
@@ -0,0 +1,141 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordifish90/cool-old-term
|
||||
*
|
||||
* This file is part of cool-old-term.
|
||||
*
|
||||
* cool-old-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.Controls 1.1
|
||||
import QtQuick.Layouts 1.1
|
||||
|
||||
Tab{
|
||||
ColumnLayout{
|
||||
anchors.fill: parent
|
||||
GroupBox{
|
||||
Layout.fillWidth: true
|
||||
title: qsTr("Profile")
|
||||
ColumnLayout{
|
||||
anchors.fill: parent
|
||||
ComboBox{
|
||||
id: profilesbox
|
||||
Layout.fillWidth: true
|
||||
model: shadersettings.profiles_list
|
||||
currentIndex: shadersettings.profiles_index
|
||||
}
|
||||
RowLayout{
|
||||
Layout.fillWidth: true
|
||||
Button{
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Load")
|
||||
onClicked: {
|
||||
shadersettings.profiles_index = profilesbox.currentIndex
|
||||
shadersettings.loadCurrentProfile();
|
||||
shadersettings.handleFontChanged();
|
||||
}
|
||||
}
|
||||
Button{
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Store current")
|
||||
onClicked: insertname.show()
|
||||
}
|
||||
Button{
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Remove Selected")
|
||||
enabled: !shadersettings.profiles_list.get(profilesbox.currentIndex).builtin
|
||||
onClicked: {
|
||||
shadersettings.profiles_list.remove(profilesbox.currentIndex)
|
||||
profilesbox.currentIndex = profilesbox.currentIndex - 1
|
||||
}
|
||||
}
|
||||
}
|
||||
InsertNameDialog{
|
||||
id: insertname
|
||||
onNameSelected: shadersettings.addNewCustomProfile(name)
|
||||
}
|
||||
}
|
||||
}
|
||||
GroupBox{
|
||||
title: qsTr("Lights")
|
||||
Layout.fillWidth: true
|
||||
GridLayout{
|
||||
anchors.fill: parent
|
||||
columns: 2
|
||||
Text{ text: qsTr("Brightness") }
|
||||
SimpleSlider{
|
||||
onValueChanged: shadersettings.brightness = value
|
||||
value: shadersettings.brightness
|
||||
}
|
||||
Text{ text: qsTr("Contrast") }
|
||||
SimpleSlider{
|
||||
onValueChanged: shadersettings.contrast = value
|
||||
value: shadersettings.contrast
|
||||
}
|
||||
Text{ text: qsTr("Opacity") }
|
||||
SimpleSlider{
|
||||
onValueChanged: shadersettings.windowOpacity = value
|
||||
value: shadersettings.windowOpacity
|
||||
}
|
||||
}
|
||||
}
|
||||
GroupBox{
|
||||
title: qsTr("Performace")
|
||||
Layout.fillWidth: true
|
||||
Layout.columnSpan: 2
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
GridLayout{
|
||||
anchors.fill: parent
|
||||
rows: 3
|
||||
columns: 3
|
||||
CheckBox{
|
||||
Layout.columnSpan: 3
|
||||
checked: !shadersettings._frameReflections
|
||||
text: qsTr("Disable reflections")
|
||||
onCheckedChanged: shadersettings._frameReflections = !checked
|
||||
enabled: shadersettings.reflectionsAllowed
|
||||
}
|
||||
CheckBox{
|
||||
property int fps: checked ? slider.value : 0
|
||||
onFpsChanged: shadersettings.fps = fps
|
||||
checked: shadersettings.fps !== 0
|
||||
text: qsTr("Limit FPS")
|
||||
}
|
||||
Slider{
|
||||
id: slider
|
||||
Layout.fillWidth: true
|
||||
stepSize: 1
|
||||
maximumValue: 60
|
||||
minimumValue: 1
|
||||
enabled: shadersettings.fps !== 0
|
||||
value: shadersettings.fps !== 0 ? shadersettings.fps : 60
|
||||
}
|
||||
Text{text: slider.value}
|
||||
Text{text: qsTr("Texture quality")}
|
||||
Slider{
|
||||
Layout.fillWidth: true
|
||||
id: txtslider
|
||||
onValueChanged: shadersettings.window_scaling = value;
|
||||
value: shadersettings.window_scaling
|
||||
tickmarksEnabled: true
|
||||
stepSize: 0.25
|
||||
Component.onCompleted: minimumValue = 0.5 //Without this value gets set to 0.5
|
||||
}
|
||||
Text{text: Math.round(txtslider.value * 100) + "%"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
128
app/SettingsTerminalTab.qml
Normal file
@@ -0,0 +1,128 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordifish90/cool-old-term
|
||||
*
|
||||
* This file is part of cool-old-term.
|
||||
*
|
||||
* cool-old-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.Controls 1.1
|
||||
import QtQuick.Layouts 1.1
|
||||
|
||||
Tab{
|
||||
ColumnLayout{
|
||||
anchors.fill: parent
|
||||
GroupBox{
|
||||
title: qsTr("Rasterization Mode")
|
||||
Layout.fillWidth: true
|
||||
ComboBox {
|
||||
id: rasterizationBox
|
||||
property string selectedElement: model[currentIndex]
|
||||
anchors.fill: parent
|
||||
model: [qsTr("Default"), qsTr("Scanlines"), qsTr("Pixels")]
|
||||
currentIndex: shadersettings.rasterization
|
||||
onCurrentIndexChanged: {
|
||||
scalingChanger.enabled = false;
|
||||
shadersettings.rasterization = currentIndex
|
||||
fontChanger.updateIndex();
|
||||
scalingChanger.updateIndex();
|
||||
scalingChanger.enabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
GroupBox{
|
||||
title: qsTr("Font") + " (" + rasterizationBox.selectedElement + ")"
|
||||
Layout.fillWidth: true
|
||||
GridLayout{
|
||||
anchors.fill: parent
|
||||
columns: 2
|
||||
Text{ text: qsTr("Name") }
|
||||
ComboBox{
|
||||
id: fontChanger
|
||||
Layout.fillWidth: true
|
||||
model: shadersettings.fontlist
|
||||
currentIndex: updateIndex()
|
||||
onActivated: {
|
||||
shadersettings.fontIndexes[shadersettings.rasterization] = index;
|
||||
shadersettings.handleFontChanged();
|
||||
}
|
||||
function updateIndex(){
|
||||
currentIndex = shadersettings.fontIndexes[shadersettings.rasterization];
|
||||
}
|
||||
}
|
||||
Text{ text: qsTr("Scaling") }
|
||||
RowLayout{
|
||||
Layout.fillWidth: true
|
||||
Slider{
|
||||
id: scalingChanger
|
||||
Layout.fillWidth: true
|
||||
minimumValue: 0
|
||||
maximumValue: shadersettings.fontScalingList.length - 1
|
||||
stepSize: 1
|
||||
tickmarksEnabled: true
|
||||
value: updateIndex()
|
||||
onValueChanged: {
|
||||
if(!enabled) return; //Ugly and hacky solution. Look for a better solution.
|
||||
shadersettings.setScalingIndex(value);
|
||||
}
|
||||
function updateIndex(){
|
||||
value = shadersettings.getScalingIndex();
|
||||
}
|
||||
Component.onCompleted: shadersettings.fontScalingChanged.connect(updateIndex);
|
||||
}
|
||||
Text{
|
||||
text: shadersettings.fontScalingList[scalingChanger.value].toFixed(2)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
GroupBox{
|
||||
title: qsTr("Colors")
|
||||
Layout.fillWidth: true
|
||||
RowLayout{
|
||||
anchors.fill: parent
|
||||
ColorButton{
|
||||
name: qsTr("Font")
|
||||
height: 50
|
||||
Layout.fillWidth: true
|
||||
onColorSelected: shadersettings._font_color = color;
|
||||
button_color: shadersettings._font_color
|
||||
}
|
||||
ColorButton{
|
||||
name: qsTr("Background")
|
||||
height: 50
|
||||
Layout.fillWidth: true
|
||||
onColorSelected: shadersettings._background_color = color;
|
||||
button_color: shadersettings._background_color
|
||||
}
|
||||
}
|
||||
}
|
||||
GroupBox{
|
||||
title: qsTr("Frame")
|
||||
Layout.fillWidth: true
|
||||
RowLayout{
|
||||
anchors.fill: parent
|
||||
ComboBox{
|
||||
id: framescombobox
|
||||
Layout.fillWidth: true
|
||||
model: shadersettings.frames_list
|
||||
currentIndex: shadersettings.frames_index
|
||||
onCurrentIndexChanged: shadersettings.frames_index = currentIndex
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordfish90/cool-retro-term
|
||||
* https://github.com/Swordifish90/cool-old-term
|
||||
*
|
||||
* This file is part of cool-retro-term.
|
||||
* This file is part of cool-old-term.
|
||||
*
|
||||
* cool-retro-term is free software: you can redistribute it and/or modify
|
||||
* cool-old-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.
|
||||
@@ -27,44 +27,28 @@ import QtQuick.Dialogs 1.1
|
||||
Window {
|
||||
id: settings_window
|
||||
title: qsTr("Settings")
|
||||
width: 580
|
||||
height: 400
|
||||
width: 640
|
||||
height: 450
|
||||
|
||||
property int tabmargins: 15
|
||||
|
||||
TabView{
|
||||
id: tabView
|
||||
anchors.fill: parent
|
||||
anchors.margins: 10
|
||||
SettingsGeneralTab{
|
||||
id: generalTab
|
||||
title: qsTr("General")
|
||||
anchors.fill: parent
|
||||
anchors.margins: tabmargins
|
||||
}
|
||||
SettingsScreenTab{
|
||||
id: screenTab
|
||||
title: qsTr("Screen")
|
||||
anchors.fill: parent
|
||||
anchors.margins: tabmargins
|
||||
}
|
||||
SettingsTerminalTab{
|
||||
id: terminalTab
|
||||
title: qsTr("Terminal")
|
||||
anchors.fill: parent
|
||||
anchors.margins: tabmargins
|
||||
}
|
||||
SettingsEffectsTab{
|
||||
id: effectsTab
|
||||
title: qsTr("Effects")
|
||||
anchors.fill: parent
|
||||
anchors.margins: tabmargins
|
||||
}
|
||||
SettingsPerformanceTab{
|
||||
id: performanceTab
|
||||
title: qsTr("Performance")
|
||||
anchors.fill: parent
|
||||
anchors.margins: tabmargins
|
||||
}
|
||||
}
|
||||
}
|
||||
200
app/ShaderTerminal.qml
Normal file
@@ -0,0 +1,200 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordifish90/cool-old-term
|
||||
*
|
||||
* This file is part of cool-old-term.
|
||||
*
|
||||
* cool-old-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 QtGraphicalEffects 1.0
|
||||
|
||||
ShaderEffect {
|
||||
property color font_color: shadersettings.font_color
|
||||
property color background_color: shadersettings.background_color
|
||||
property variant source: terminal.theSource
|
||||
property variant bloomSource: terminal.bloomSource
|
||||
property variant rasterizationSource: terminal.rasterizationSource
|
||||
property variant noiseSource: terminal.staticNoiseSource
|
||||
property size txt_Size: Qt.size(frame.sourceRect.width, frame.sourceRect.height)
|
||||
property real bloom: shadersettings.bloom_strength * 2.5
|
||||
|
||||
property int rasterization: shadersettings.rasterization
|
||||
|
||||
property real jitter: shadersettings.jitter * 0.007
|
||||
|
||||
property real noise_strength: shadersettings.noise_strength
|
||||
property real screen_distorsion: shadersettings.screen_distortion
|
||||
property real glowing_line_strength: shadersettings.glowing_line_strength
|
||||
|
||||
property real brightness_flickering: shadersettings.brightness_flickering
|
||||
property real horizontal_sincronization: shadersettings.horizontal_sincronization
|
||||
|
||||
property bool frameReflections: shadersettings.frameReflections
|
||||
|
||||
property real disp_top: frame.item.displacementTop * shadersettings.window_scaling
|
||||
property real disp_bottom: frame.item.displacementBottom * shadersettings.window_scaling
|
||||
property real disp_left: frame.item.displacementLeft * shadersettings.window_scaling
|
||||
property real disp_right: frame.item.displacementRight * shadersettings.window_scaling
|
||||
|
||||
property real brightness: shadersettings.brightness * 1.5 + 0.5
|
||||
|
||||
property real time: timeManager.time
|
||||
property variant randomFunctionSource: randfuncsource
|
||||
|
||||
blending: false
|
||||
|
||||
//Smooth random texture used for flickering effect.
|
||||
Image{
|
||||
id: randtexture
|
||||
source: "frames/images/randfunction.png"
|
||||
width: 512
|
||||
height: 512
|
||||
sourceSize.width: 512
|
||||
sourceSize.height: 256
|
||||
fillMode: Image.TileVertically
|
||||
}
|
||||
ShaderEffectSource{
|
||||
id: randfuncsource
|
||||
sourceItem: randtexture
|
||||
live: false
|
||||
hideSource: true
|
||||
wrapMode: ShaderEffectSource.Repeat
|
||||
}
|
||||
|
||||
//Print the number with a reasonable precision for the shader.
|
||||
function str(num){
|
||||
return num.toFixed(8);
|
||||
}
|
||||
|
||||
vertexShader: "
|
||||
uniform highp mat4 qt_Matrix;
|
||||
uniform highp float time;
|
||||
uniform sampler2D randomFunctionSource;
|
||||
uniform highp vec2 txt_Size;
|
||||
|
||||
attribute highp vec4 qt_Vertex;
|
||||
attribute highp vec2 qt_MultiTexCoord0;
|
||||
|
||||
varying highp vec2 qt_TexCoord0;" +
|
||||
|
||||
(brightness_flickering !== 0.0 ?"
|
||||
varying lowp float brightness;" : "") +
|
||||
(horizontal_sincronization !== 0.0 ?"
|
||||
varying lowp float horizontal_distortion;" : "") +
|
||||
"
|
||||
void main() {
|
||||
qt_TexCoord0.x = -"+str(disp_left)+"/txt_Size.x + qt_MultiTexCoord0.x / ((txt_Size.x -("+str(disp_left+disp_right)+")) / txt_Size.x);" + "
|
||||
qt_TexCoord0.y = -"+str(disp_top)+"/txt_Size.y + qt_MultiTexCoord0.y / ((txt_Size.y -("+str(disp_top+disp_bottom)+")) / txt_Size.y);" + "
|
||||
vec2 coords = vec2(fract(time/(1024.0*2.0)), fract(time/(1024.0*1024.0)));" +
|
||||
(brightness_flickering !== 0.0 ? "
|
||||
brightness = 1.0 + (texture2D(randomFunctionSource, coords).g - 0.5) * "+str(brightness_flickering)+";"
|
||||
: "") +
|
||||
|
||||
(horizontal_sincronization !== 0.0 ? "
|
||||
float randval = 1.5 * texture2D(randomFunctionSource,(vec2(1.0) -coords) * 0.5).g;
|
||||
float negsinc = 1.0 - "+str(0.6*horizontal_sincronization)+";
|
||||
horizontal_distortion = step(negsinc, randval) * (randval - negsinc) * "+str(0.3*horizontal_sincronization)+";"
|
||||
: "") +
|
||||
|
||||
"gl_Position = qt_Matrix * qt_Vertex;
|
||||
}"
|
||||
|
||||
fragmentShader: "
|
||||
uniform sampler2D source;
|
||||
uniform highp float qt_Opacity;
|
||||
uniform highp float time;
|
||||
uniform highp vec2 txt_Size;
|
||||
varying highp vec2 qt_TexCoord0;
|
||||
|
||||
uniform highp vec4 font_color;
|
||||
uniform highp vec4 background_color;
|
||||
uniform highp sampler2D rasterizationSource;" +
|
||||
|
||||
(bloom !== 0 ? "
|
||||
uniform highp sampler2D bloomSource;" : "") +
|
||||
(noise_strength !== 0 ? "
|
||||
uniform highp float noise_strength;" : "") +
|
||||
(noise_strength !== 0 || jitter !== 0 ? "
|
||||
uniform lowp sampler2D noiseSource;" : "") +
|
||||
(screen_distorsion !== 0 ? "
|
||||
uniform highp float screen_distorsion;" : "")+
|
||||
(glowing_line_strength !== 0 ? "
|
||||
uniform highp float glowing_line_strength;" : "")+
|
||||
(brightness_flickering !== 0 ? "
|
||||
varying lowp float brightness;" : "") +
|
||||
(horizontal_sincronization !== 0 ? "
|
||||
varying lowp float horizontal_distortion;" : "") +
|
||||
|
||||
(glowing_line_strength !== 0 ? "
|
||||
float randomPass(vec2 coords){
|
||||
return fract(smoothstep(-0.2, 0.0, coords.y - 3.0 * fract(time * 0.0001))) * glowing_line_strength;
|
||||
}" : "") +
|
||||
|
||||
|
||||
"void main() {" +
|
||||
"vec2 cc = vec2(0.5) - qt_TexCoord0;" +
|
||||
"float distance = length(cc);" +
|
||||
|
||||
(noise_strength ? "
|
||||
float noise = noise_strength;" : "") +
|
||||
|
||||
(screen_distorsion !== 0 ? "
|
||||
float distortion = dot(cc, cc) * screen_distorsion;
|
||||
vec2 coords = (qt_TexCoord0 - cc * (1.0 + distortion) * distortion);"
|
||||
:"
|
||||
vec2 coords = qt_TexCoord0;") +
|
||||
|
||||
(frameReflections ? "
|
||||
vec2 inside = step(0.0, coords) - step(1.0, coords);
|
||||
coords = abs(mod(floor(coords), 2.0) - fract(coords)) * clamp(inside.x + inside.y, 0.0, 1.0);" : "") +
|
||||
|
||||
(horizontal_sincronization !== 0 ? "
|
||||
float h_distortion = 0.5 * sin(time*0.001 + coords.y*10.0*fract(time/10.0));
|
||||
h_distortion += 0.5 * cos(time*0.04 + 0.03 + coords.y*50.0*fract(time/10.0 + 0.4));
|
||||
coords.x = coords.x + h_distortion * horizontal_distortion;" +
|
||||
(noise_strength ? "
|
||||
noise += horizontal_distortion;" : "")
|
||||
: "") +
|
||||
|
||||
(jitter !== 0 ? "
|
||||
vec2 offset = vec2(texture2D(noiseSource, coords + fract(time / 57.0)).a,
|
||||
texture2D(noiseSource, coords + fract(time / 251.0)).a) - 0.5;
|
||||
vec2 txt_coords = coords + offset * "+str(jitter)+";"
|
||||
: "vec2 txt_coords = coords;") +
|
||||
|
||||
"float color = texture2D(source, txt_coords).a;" +
|
||||
|
||||
(noise_strength !== 0 ? "
|
||||
float noiseVal = texture2D(noiseSource, qt_TexCoord0 + vec2(fract(time / 51.0), fract(time / 237.0))).a;
|
||||
color += noiseVal * noise * (1.0 - distance * 1.3);" : "") +
|
||||
|
||||
(glowing_line_strength !== 0 ? "
|
||||
color += randomPass(coords) * glowing_line_strength;" : "") +
|
||||
|
||||
"vec3 finalColor = mix(background_color, font_color, color).rgb;" +
|
||||
"finalColor *= texture2D(rasterizationSource, coords).a;" +
|
||||
|
||||
(bloom !== 0 ? "
|
||||
finalColor += font_color.rgb * texture2D(bloomSource, coords).r *" + str(bloom) + ";" : "") +
|
||||
|
||||
(brightness_flickering !== 0 ? "
|
||||
finalColor *= brightness;" : "") +
|
||||
|
||||
"gl_FragColor = vec4(finalColor *"+str(brightness)+", qt_Opacity);
|
||||
}"
|
||||
|
||||
onStatusChanged: if (log) console.log(log) //Print warning messages
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordfish90/cool-retro-term
|
||||
* https://github.com/Swordifish90/cool-old-term
|
||||
*
|
||||
* This file is part of cool-retro-term.
|
||||
* This file is part of cool-old-term.
|
||||
*
|
||||
* cool-retro-term is free software: you can redistribute it and/or modify
|
||||
* cool-old-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.
|
||||
@@ -22,8 +22,6 @@ import QtQuick 2.2
|
||||
import QtQuick.Controls 1.1
|
||||
import QtQuick.Layouts 1.1
|
||||
|
||||
import "Components"
|
||||
|
||||
RowLayout {
|
||||
property alias value: slider.value
|
||||
property alias stepSize: slider.stepSize
|
||||
@@ -38,7 +36,15 @@ RowLayout {
|
||||
stepSize: parent.stepSize
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
SizedLabel{
|
||||
text: Math.round(value * maxMultiplier) + "%"
|
||||
Text{
|
||||
id: textfield
|
||||
text: formatNumber(Math.round(value * maxMultiplier))
|
||||
}
|
||||
function formatNumber(num) {
|
||||
var n = "" + num;
|
||||
while (n.length < 3) {
|
||||
n = " " + n;
|
||||
}
|
||||
return n + "%";
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordfish90/cool-retro-term
|
||||
* https://github.com/Swordifish90/cool-old-term
|
||||
*
|
||||
* This file is part of cool-retro-term.
|
||||
* This file is part of cool-old-term.
|
||||
*
|
||||
* cool-retro-term is free software: you can redistribute it and/or modify
|
||||
* cool-old-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.
|
||||
@@ -1,10 +1,10 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordfish90/cool-retro-term
|
||||
* https://github.com/Swordifish90/cool-old-term
|
||||
*
|
||||
* This file is part of cool-retro-term.
|
||||
* This file is part of cool-old-term.
|
||||
*
|
||||
* cool-retro-term is free software: you can redistribute it and/or modify
|
||||
* cool-old-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.
|
||||
@@ -21,11 +21,11 @@
|
||||
import QtQuick 2.2
|
||||
import QtQuick.LocalStorage 2.0
|
||||
|
||||
QtObject {
|
||||
Item {
|
||||
property bool initialized: false
|
||||
|
||||
function getDatabase() {
|
||||
return LocalStorage.openDatabaseSync("coolretroterm", "1.0", "StorageDatabase", 100000);
|
||||
return LocalStorage.openDatabaseSync("coololdterm", "1.0", "StorageDatabase", 100000);
|
||||
}
|
||||
|
||||
function initialize() {
|
||||
@@ -1,10 +1,10 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordfish90/cool-retro-term
|
||||
* https://github.com/Swordifish90/cool-old-term
|
||||
*
|
||||
* This file is part of cool-retro-term.
|
||||
* This file is part of cool-old-term.
|
||||
*
|
||||
* cool-retro-term is free software: you can redistribute it and/or modify
|
||||
* cool-old-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.
|
||||
@@ -27,13 +27,13 @@ Timer{
|
||||
NumberAnimation on time {
|
||||
from: 0
|
||||
to: 100000
|
||||
running: appSettings.fps === 0 && enableTimer
|
||||
running: shadersettings.fps === 0 && enableTimer
|
||||
duration: 100000
|
||||
loops: Animation.Infinite
|
||||
}
|
||||
|
||||
onTriggered: time += interval
|
||||
running: appSettings.fps !== 0 && enableTimer
|
||||
interval: Math.round(1000 / appSettings.fps)
|
||||
running: shadersettings.fps !== 0 && enableTimer
|
||||
interval: Math.round(1000 / shadersettings.fps)
|
||||
repeat: true
|
||||
}
|
||||
36
app/app.pro
@@ -1,36 +0,0 @@
|
||||
QT += qml quick widgets sql
|
||||
TARGET = cool-retro-term
|
||||
|
||||
DESTDIR = $$OUT_PWD/../
|
||||
|
||||
HEADERS += \
|
||||
fileio.h
|
||||
|
||||
SOURCES = main.cpp \
|
||||
fileio.cpp
|
||||
|
||||
macx:ICON = icons/crt.icns
|
||||
|
||||
RESOURCES += qml/resources.qrc
|
||||
|
||||
#########################################
|
||||
## INTALLS
|
||||
#########################################
|
||||
|
||||
target.path += /usr/bin/
|
||||
|
||||
INSTALLS += target
|
||||
|
||||
# Install icons
|
||||
unix {
|
||||
icon32.files = icons/32x32/cool-retro-term.png
|
||||
icon32.path = /usr/share/icons/hicolor/32x32/apps
|
||||
icon64.files = icons/64x64/cool-retro-term.png
|
||||
icon64.path = /usr/share/icons/hicolor/64x64/apps
|
||||
icon128.files = icons/128x128/cool-retro-term.png
|
||||
icon128.path = /usr/share/icons/hicolor/128x128/apps
|
||||
icon256.files = icons/256x256/cool-retro-term.png
|
||||
icon256.path = /usr/share/icons/hicolor/256x256/apps
|
||||
|
||||
INSTALLS += icon32 icon64 icon128 icon256
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
#include "fileio.h"
|
||||
|
||||
FileIO::FileIO()
|
||||
{
|
||||
}
|
||||
|
||||
bool FileIO::write(const QString& sourceUrl, const QString& data) {
|
||||
if (sourceUrl.isEmpty())
|
||||
return false;
|
||||
|
||||
QUrl url(sourceUrl);
|
||||
QFile file(url.toLocalFile());
|
||||
if (!file.open(QFile::WriteOnly | QFile::Truncate))
|
||||
return false;
|
||||
|
||||
QTextStream out(&file);
|
||||
out << data;
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
QString FileIO::read(const QString& sourceUrl) {
|
||||
if (sourceUrl.isEmpty())
|
||||
return "";
|
||||
|
||||
QUrl url(sourceUrl);
|
||||
QFile file(url.toLocalFile());
|
||||
if (!file.open(QFile::ReadOnly))
|
||||
return "";
|
||||
|
||||
QTextStream in(&file);
|
||||
QString result = in.readAll();
|
||||
|
||||
file.close();
|
||||
|
||||
return result;
|
||||
}
|
||||
21
app/fileio.h
@@ -1,21 +0,0 @@
|
||||
#ifndef FILEIO_H
|
||||
#define FILEIO_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
#include <QUrl>
|
||||
|
||||
class FileIO : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
FileIO();
|
||||
|
||||
public slots:
|
||||
bool write(const QString& sourceUrl, const QString& data);
|
||||
QString read(const QString& sourceUrl);
|
||||
};
|
||||
|
||||
#endif // FILEIO_H
|
||||
BIN
app/fonts/1979-atari-400-800/ATARI400800_rounded.TTF
Normal file
28
app/frames/BlackRoughFrame.qml
Normal file
@@ -0,0 +1,28 @@
|
||||
import QtQuick 2.2
|
||||
import "utils"
|
||||
|
||||
TerminalFrame{
|
||||
id: frame
|
||||
z: 2.1
|
||||
anchors.fill: parent
|
||||
addedWidth: 200
|
||||
addedHeight: 370
|
||||
borderLeft: 148
|
||||
borderRight: 148
|
||||
borderTop: 232
|
||||
borderBottom: 232
|
||||
imageSource: "../images/black-frame.png"
|
||||
normalsSource: "../images/black-frame-normals.png"
|
||||
|
||||
rectX: 20
|
||||
rectY: 20
|
||||
|
||||
distortionCoefficient: 1.9
|
||||
|
||||
displacementLeft: 70.0
|
||||
displacementTop: 55.0
|
||||
displacementRight: 50.0
|
||||
displacementBottom: 38.0
|
||||
|
||||
shaderString: "FrameShader.qml"
|
||||
}
|
||||
22
app/frames/NoFrame.qml
Normal file
@@ -0,0 +1,22 @@
|
||||
import QtQuick 2.2
|
||||
import "utils"
|
||||
|
||||
TerminalFrame{
|
||||
id: frame
|
||||
z: 2.1
|
||||
anchors.fill: parent
|
||||
addedWidth: 0
|
||||
addedHeight: 0
|
||||
borderLeft: 0
|
||||
borderRight: 0
|
||||
borderTop: 0
|
||||
borderBottom: 0
|
||||
|
||||
rectX: 15
|
||||
rectY: 15
|
||||
|
||||
displacementLeft: 0
|
||||
displacementTop: 0
|
||||
displacementRight: 0
|
||||
displacementBottom: 0
|
||||
}
|
||||
@@ -14,11 +14,15 @@ TerminalFrame{
|
||||
imageSource: "../images/screen-frame.png"
|
||||
normalsSource: "../images/screen-frame-normals.png"
|
||||
|
||||
displacementLeft: 55
|
||||
displacementTop: 50
|
||||
displacementRight: 55
|
||||
displacementBottom: 50
|
||||
rectX: 15
|
||||
rectY: 15
|
||||
|
||||
staticDiffuseComponent: 1.0
|
||||
dinamycDiffuseComponent: 0.6
|
||||
distortionCoefficient: 1.5
|
||||
|
||||
displacementLeft: 45
|
||||
displacementTop: 40
|
||||
displacementRight: 38.0
|
||||
displacementBottom: 28.0
|
||||
|
||||
shaderString: "FrameShader.qml"
|
||||
}
|
||||
BIN
app/frames/images/black-frame-normals.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 1.2 MiB |
BIN
app/frames/images/randfunction.png
Normal file
|
After Width: | Height: | Size: 132 KiB |
BIN
app/frames/images/screen-frame-normals.png
Normal file
|
After Width: | Height: | Size: 507 KiB |
|
Before Width: | Height: | Size: 571 KiB After Width: | Height: | Size: 571 KiB |
|
Before Width: | Height: | Size: 811 KiB After Width: | Height: | Size: 811 KiB |
91
app/frames/utils/FrameShader.qml
Normal file
@@ -0,0 +1,91 @@
|
||||
import QtQuick 2.2
|
||||
import QtGraphicalEffects 1.0
|
||||
|
||||
ShaderEffect{
|
||||
property variant source: framesource
|
||||
property variant normals: framesourcenormals
|
||||
property real screen_distorsion: shadersettings.screen_distortion * framecontainer.distortionCoefficient
|
||||
property real ambient_light: shadersettings.ambient_light
|
||||
property color font_color: shadersettings.font_color
|
||||
property color background_color: shadersettings.background_color
|
||||
property real brightness: shadersettings.brightness * 1.5 + 0.5
|
||||
|
||||
property bool frameReflections: shadersettings.frameReflections
|
||||
property variant lightSource: reflectionEffectSourceLoader.item
|
||||
|
||||
Loader{
|
||||
id: reflectionEffectLoader
|
||||
width: parent.width * 0.33
|
||||
height: parent.height * 0.33
|
||||
active: frameReflections
|
||||
|
||||
sourceComponent: FastBlur{
|
||||
id: frameReflectionEffect
|
||||
radius: 128
|
||||
source: terminal.kterminal
|
||||
smooth: false
|
||||
}
|
||||
}
|
||||
|
||||
Loader{
|
||||
id: reflectionEffectSourceLoader
|
||||
active: frameReflections
|
||||
sourceComponent: ShaderEffectSource{
|
||||
id: frameReflectionSource
|
||||
sourceItem: reflectionEffectLoader.item
|
||||
hideSource: true
|
||||
smooth: true
|
||||
}
|
||||
}
|
||||
|
||||
blending: true
|
||||
|
||||
fragmentShader: "
|
||||
uniform sampler2D source;
|
||||
uniform sampler2D normals;
|
||||
uniform highp float screen_distorsion;
|
||||
uniform highp float ambient_light;
|
||||
uniform highp float qt_Opacity;" +
|
||||
|
||||
(frameReflections ?
|
||||
"uniform sampler2D lightSource;" : "") + "
|
||||
|
||||
uniform vec4 font_color;
|
||||
uniform vec4 background_color;
|
||||
varying lowp float brightness;
|
||||
|
||||
varying highp vec2 qt_TexCoord0;
|
||||
|
||||
vec2 distortCoordinates(vec2 coords){
|
||||
vec2 cc = coords - vec2(0.5);
|
||||
float dist = dot(cc, cc) * screen_distorsion;
|
||||
return (coords + cc * (1.0 + dist) * dist);
|
||||
}
|
||||
|
||||
void main(){
|
||||
vec2 coords = distortCoordinates(qt_TexCoord0);
|
||||
vec4 txt_color = texture2D(source, coords);
|
||||
vec4 txt_normal = texture2D(normals, coords);
|
||||
vec3 normal = normalize(txt_normal.rgb * 2.0 - 1.0);
|
||||
vec3 light_direction = normalize(vec3(0.5, 0.5, 0.0) - vec3(qt_TexCoord0, 0.0));
|
||||
|
||||
float dotProd = dot(normal, light_direction);" +
|
||||
|
||||
(frameReflections ? "
|
||||
float screenLight = texture2D(lightSource, coords).r;
|
||||
float clampedDotProd = clamp(dotProd, 0.05, 1.0);
|
||||
float diffuseReflection = clamp(screenLight * 1.5 * clampedDotProd, 0.0, 0.35);
|
||||
float reflectionAlpha = mix(1.0, 0.90, dotProd);"
|
||||
: "
|
||||
float diffuseReflection = 0.0;
|
||||
float reflectionAlpha = 1.0;") + "
|
||||
|
||||
vec3 back_color = background_color.rgb * (0.2 + 0.5 * dotProd);
|
||||
vec3 front_color = font_color.rgb * (0.05 + diffuseReflection);
|
||||
|
||||
vec4 dark_color = vec4((back_color + front_color) * txt_normal.a, txt_normal.a * reflectionAlpha);
|
||||
gl_FragColor = mix(dark_color, txt_color, ambient_light);
|
||||
}"
|
||||
|
||||
onStatusChanged: if (log) console.log(log) //Print warning messages
|
||||
}
|
||||
23
app/frames/utils/NoFrameShader.qml
Normal file
@@ -0,0 +1,23 @@
|
||||
import QtQuick 2.2
|
||||
|
||||
ShaderEffect{
|
||||
property variant source: framesource
|
||||
property real screen_distorsion: shadersettings.screen_distortion
|
||||
|
||||
fragmentShader: "
|
||||
uniform sampler2D source;
|
||||
uniform highp float screen_distorsion;
|
||||
varying highp vec2 qt_TexCoord0;
|
||||
|
||||
vec2 distortCoordinates(vec2 coords){
|
||||
vec2 cc = coords - vec2(0.5);
|
||||
float dist = dot(cc, cc) * screen_distorsion;
|
||||
return (coords + cc * (1.0 + dist) * dist);
|
||||
}
|
||||
|
||||
void main(){
|
||||
vec2 coords = distortCoordinates(qt_TexCoord0);
|
||||
float inside = texture2D(source, coords).a;
|
||||
gl_FragColor = vec4(vec3(0.0), inside);
|
||||
}"
|
||||
}
|
||||
81
app/frames/utils/TerminalFrame.qml
Normal file
@@ -0,0 +1,81 @@
|
||||
import QtQuick 2.2
|
||||
|
||||
Item{
|
||||
id: framecontainer
|
||||
property int textureWidth: terminalWindow.width
|
||||
property int textureHeight: terminalWindow.height
|
||||
|
||||
property int addedWidth
|
||||
property int addedHeight
|
||||
property int borderLeft
|
||||
property int borderRight
|
||||
property int borderTop
|
||||
property int borderBottom
|
||||
property string imageSource
|
||||
property string normalsSource
|
||||
property string shaderString
|
||||
|
||||
//Value used to create the rect used to add the border to the texture
|
||||
property real rectX
|
||||
property real rectY
|
||||
|
||||
//Values used to displace the texture in the screen. Used to make reflections correct.
|
||||
property real displacementLeft
|
||||
property real displacementTop
|
||||
property real displacementRight
|
||||
property real displacementBottom
|
||||
|
||||
property real distortionCoefficient
|
||||
|
||||
property rect sourceRect: Qt.rect(-rectX * shadersettings.window_scaling,
|
||||
-rectY * shadersettings.window_scaling,
|
||||
terminal.width + 2*rectX * shadersettings.window_scaling,
|
||||
terminal.height + 2*rectY * shadersettings.window_scaling)
|
||||
|
||||
BorderImage{
|
||||
id: frameimage
|
||||
anchors.centerIn: parent
|
||||
width: textureWidth + addedWidth
|
||||
height: textureHeight + addedHeight
|
||||
|
||||
border.bottom: borderBottom
|
||||
border.top: borderTop
|
||||
border.left: borderLeft
|
||||
border.right: borderRight
|
||||
|
||||
source: imageSource
|
||||
horizontalTileMode: BorderImage.Stretch
|
||||
verticalTileMode: BorderImage.Stretch
|
||||
}
|
||||
BorderImage{
|
||||
id: framenormals
|
||||
anchors.fill: frameimage
|
||||
|
||||
border.bottom: borderBottom
|
||||
border.top: borderTop
|
||||
border.left: borderLeft
|
||||
border.right: borderRight
|
||||
|
||||
source: normalsSource
|
||||
horizontalTileMode: BorderImage.Stretch
|
||||
verticalTileMode: BorderImage.Stretch
|
||||
}
|
||||
ShaderEffectSource{
|
||||
id: framesource
|
||||
sourceItem: frameimage
|
||||
hideSource: true
|
||||
textureSize: Qt.size(parent.width, parent.height)
|
||||
}
|
||||
ShaderEffectSource{
|
||||
id: framesourcenormals
|
||||
sourceItem: framenormals
|
||||
hideSource: true
|
||||
textureSize: Qt.size(parent.width, parent.height)
|
||||
}
|
||||
Loader{
|
||||
anchors.centerIn: parent
|
||||
width: parent.width + (addedWidth / textureWidth) * parent.width
|
||||
height: parent.height + (addedHeight / textureHeight) * parent.height
|
||||
source: shaderString
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 8.4 KiB |
|
Before Width: | Height: | Size: 19 KiB |
107
app/main.cpp
@@ -1,107 +0,0 @@
|
||||
#include <QtQml/QQmlApplicationEngine>
|
||||
#include <QtGui/QGuiApplication>
|
||||
|
||||
#include <QQmlContext>
|
||||
#include <QStringList>
|
||||
|
||||
#include <QtWidgets/QApplication>
|
||||
#include <QIcon>
|
||||
|
||||
#include <QDebug>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <fileio.h>
|
||||
|
||||
QString getNamedArgument(QStringList args, QString name, QString defaultName)
|
||||
{
|
||||
int index = args.indexOf(name);
|
||||
return (index != -1) ? args[index + 1] : QString(defaultName);
|
||||
}
|
||||
|
||||
QString getNamedArgument(QStringList args, QString name)
|
||||
{
|
||||
return getNamedArgument(args, name, "");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// Some environmental variable are necessary on certain platforms.
|
||||
|
||||
// This disables QT appmenu under Ubuntu, which is not working with QML apps.
|
||||
setenv("QT_QPA_PLATFORMTHEME", "", 1);
|
||||
|
||||
#if defined(Q_OS_MAC)
|
||||
// This allows UTF-8 characters usage in OSX.
|
||||
setenv("LC_CTYPE", "UTF-8", 1);
|
||||
#endif
|
||||
|
||||
QApplication app(argc, argv);
|
||||
// set application attributes
|
||||
// Has no effects, see https://bugreports.qt.io/browse/QTBUG-51293
|
||||
// app.setAttribute(Qt::AA_MacDontSwapCtrlAndMeta, true);
|
||||
|
||||
QQmlApplicationEngine engine;
|
||||
FileIO fileIO;
|
||||
|
||||
#if !defined(Q_OS_MAC)
|
||||
app.setWindowIcon(QIcon::fromTheme("cool-retro-term", QIcon(":../icons/32x32/cool-retro-term.png")));
|
||||
#else
|
||||
app.setWindowIcon(QIcon(":../icons/32x32/cool-retro-term.png"));
|
||||
#endif
|
||||
|
||||
// Manage command line arguments from the cpp side
|
||||
QStringList args = app.arguments();
|
||||
if (args.contains("-h") || args.contains("--help")) {
|
||||
// BUG: This usage help text goes to stderr, should go to stdout.
|
||||
// BUG: First line of output is surrounded by double quotes.
|
||||
qDebug() << "Usage: " + args.at(0) + " [--default-settings] [--workdir <dir>] [--program <prog>] [-p|--profile <prof>] [--fullscreen] [-h|--help]";
|
||||
qDebug() << " --default-settings Run cool-retro-term with the default settings";
|
||||
qDebug() << " --workdir <dir> Change working directory to 'dir'";
|
||||
qDebug() << " -e <cmd> Command to execute. This option will catch all following arguments, so use it as the last option.";
|
||||
qDebug() << " -T <title> Set window title to 'title'.";
|
||||
qDebug() << " --fullscreen Run cool-retro-term in fullscreen.";
|
||||
qDebug() << " -p|--profile <prof> Run cool-retro-term with the given profile.";
|
||||
qDebug() << " -h|--help Print this help.";
|
||||
qDebug() << " --verbose Print additional information such as profiles and settings.";
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (args.contains("-v") || args.contains("--version")) {
|
||||
qDebug() << "cool-retro-term 1.0.1";
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Manage default command
|
||||
QStringList cmdList;
|
||||
if (args.contains("-e")) {
|
||||
cmdList << args.mid(args.indexOf("-e") + 1);
|
||||
}
|
||||
QVariant command(cmdList.empty() ? QVariant() : cmdList[0]);
|
||||
QVariant commandArgs(cmdList.size() <= 1 ? QVariant() : QVariant(cmdList.mid(1)));
|
||||
engine.rootContext()->setContextProperty("defaultCmd", command);
|
||||
engine.rootContext()->setContextProperty("defaultCmdArgs", commandArgs);
|
||||
|
||||
engine.rootContext()->setContextProperty("workdir", getNamedArgument(args, "--workdir", "$HOME"));
|
||||
engine.rootContext()->setContextProperty("fileIO", &fileIO);
|
||||
|
||||
engine.rootContext()->setContextProperty("devicePixelRatio", app.devicePixelRatio());
|
||||
|
||||
// Manage import paths for Linux and OSX.
|
||||
QStringList importPathList = engine.importPathList();
|
||||
importPathList.prepend(QCoreApplication::applicationDirPath() + "/qmltermwidget");
|
||||
importPathList.prepend(QCoreApplication::applicationDirPath() + "/../PlugIns");
|
||||
importPathList.prepend(QCoreApplication::applicationDirPath() + "/../../../qmltermwidget");
|
||||
engine.setImportPathList(importPathList);
|
||||
|
||||
engine.load(QUrl(QStringLiteral ("qrc:/main.qml")));
|
||||
|
||||
if (engine.rootObjects().isEmpty()) {
|
||||
qDebug() << "Cannot load QML interface";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Quit the application when the engine closes.
|
||||
QObject::connect((QObject*) &engine, SIGNAL(quit()), (QObject*) &app, SLOT(quit()));
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
193
app/main.qml
Normal file
@@ -0,0 +1,193 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordifish90/cool-old-term
|
||||
*
|
||||
* This file is part of cool-old-term.
|
||||
*
|
||||
* cool-old-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.Window 2.1
|
||||
import QtQuick.Controls 1.1
|
||||
import QtGraphicalEffects 1.0
|
||||
|
||||
import org.kde.konsole 0.1
|
||||
|
||||
ApplicationWindow{
|
||||
id: terminalWindow
|
||||
|
||||
width: 1024
|
||||
height: 768
|
||||
minimumWidth: 320
|
||||
minimumHeight: 240
|
||||
|
||||
property bool fullscreen: shadersettings.fullscreen
|
||||
onFullscreenChanged: visibility = (fullscreen ? Window.FullScreen : Window.Windowed)
|
||||
|
||||
flags: Qt.WA_TranslucentBackground
|
||||
color: "#00000000"
|
||||
title: qsTr("cool-old-term")
|
||||
|
||||
Action {
|
||||
id: showMenubarAction
|
||||
text: qsTr("Show Menubar")
|
||||
checkable: true
|
||||
checked: shadersettings.showMenubar
|
||||
onTriggered: shadersettings.showMenubar = !shadersettings.showMenubar
|
||||
}
|
||||
Action {
|
||||
id: fullscreenAction
|
||||
text: qsTr("&Fullscreen")
|
||||
shortcut: "Alt+F11"
|
||||
onTriggered: shadersettings.fullscreen = !shadersettings.fullscreen;
|
||||
checkable: true
|
||||
checked: shadersettings.fullscreen
|
||||
}
|
||||
Action {
|
||||
id: quitAction
|
||||
text: qsTr("&Quit")
|
||||
shortcut: "Ctrl+Q"
|
||||
onTriggered: terminalWindow.close();
|
||||
}
|
||||
Action{
|
||||
id: showsettingsAction
|
||||
text: qsTr("&Settings")
|
||||
onTriggered: settingswindow.show();
|
||||
}
|
||||
Action{
|
||||
id: copyAction
|
||||
text: qsTr("&Copy")
|
||||
shortcut: "Ctrl+Shift+C"
|
||||
onTriggered: terminal.copyClipboard()
|
||||
}
|
||||
Action{
|
||||
id: pasteAction
|
||||
text: qsTr("&Paste")
|
||||
shortcut: "Ctrl+Shift+V"
|
||||
onTriggered: terminal.pasteClipboard()
|
||||
}
|
||||
Action{
|
||||
id: zoomIn
|
||||
text: qsTr("&Zoom In")
|
||||
shortcut: "Ctrl++"
|
||||
onTriggered: {
|
||||
var oldScaling = shadersettings.fontScalingIndexes[shadersettings.rasterization];
|
||||
var maxScalingIndex = shadersettings.fontScalingList.length - 1;
|
||||
shadersettings.setScalingIndex(Math.min(oldScaling + 1, maxScalingIndex));
|
||||
}
|
||||
}
|
||||
Action{
|
||||
id: zoomOut
|
||||
text: qsTr("&Zoom Out")
|
||||
shortcut: "Ctrl+-"
|
||||
onTriggered: {
|
||||
var oldScaling = shadersettings.fontScalingIndexes[shadersettings.rasterization];
|
||||
shadersettings.setScalingIndex(Math.max(oldScaling - 1, 0));
|
||||
}
|
||||
}
|
||||
Action{
|
||||
id: showAboutAction
|
||||
text: qsTr("About")
|
||||
onTriggered: {
|
||||
aboutDialog.show();
|
||||
}
|
||||
}
|
||||
|
||||
menuBar: MenuBar {
|
||||
id: menubar
|
||||
Menu {
|
||||
title: qsTr("File")
|
||||
visible: shadersettings.showMenubar
|
||||
MenuItem {action: quitAction}
|
||||
}
|
||||
Menu {
|
||||
title: qsTr("Edit")
|
||||
visible: shadersettings.showMenubar
|
||||
MenuItem {action: copyAction}
|
||||
MenuItem {action: pasteAction}
|
||||
MenuSeparator{}
|
||||
MenuItem {action: showsettingsAction}
|
||||
}
|
||||
Menu{
|
||||
title: qsTr("View")
|
||||
visible: shadersettings.showMenubar
|
||||
MenuItem {action: fullscreenAction}
|
||||
MenuItem {action: showMenubarAction}
|
||||
MenuSeparator{}
|
||||
MenuItem {action: zoomIn}
|
||||
MenuItem {action: zoomOut}
|
||||
}
|
||||
Menu{
|
||||
title: qsTr("Help")
|
||||
visible: shadersettings.showMenubar
|
||||
MenuItem {action: showAboutAction}
|
||||
}
|
||||
}
|
||||
ApplicationSettings{
|
||||
id: shadersettings
|
||||
}
|
||||
TimeManager{
|
||||
id: timeManager
|
||||
enableTimer: terminalWindow.visible
|
||||
}
|
||||
Item{
|
||||
id: maincontainer
|
||||
anchors.centerIn: parent
|
||||
width: parent.width * shadersettings.window_scaling
|
||||
height: parent.height * shadersettings.window_scaling
|
||||
scale: 1.0 / shadersettings.window_scaling
|
||||
smooth: false
|
||||
antialiasing: false
|
||||
opacity: shadersettings.windowOpacity * 0.3 + 0.7
|
||||
|
||||
Loader{
|
||||
id: frame
|
||||
anchors.fill: parent
|
||||
|
||||
property rect sourceRect: item.sourceRect
|
||||
|
||||
z: 2.1
|
||||
source: shadersettings.frame_source
|
||||
}
|
||||
PreprocessedTerminal{
|
||||
id: terminal
|
||||
anchors.fill: parent
|
||||
anchors.margins: 30
|
||||
}
|
||||
ShaderTerminal{
|
||||
id: shadercontainer
|
||||
anchors.fill: parent
|
||||
z: 1.9
|
||||
}
|
||||
}
|
||||
SettingsWindow{
|
||||
id: settingswindow
|
||||
visible: false
|
||||
}
|
||||
AboutDialog{
|
||||
id: aboutDialog
|
||||
visible: false
|
||||
}
|
||||
Loader{
|
||||
id: sizeoverlayloader
|
||||
z: 3
|
||||
anchors.centerIn: parent
|
||||
active: shadersettings.show_terminal_size
|
||||
sourceComponent: SizeOverlay{
|
||||
terminalSize: terminal.terminalSize
|
||||
}
|
||||
}
|
||||
Component.onCompleted: shadersettings.handleFontChanged();
|
||||
}
|
||||
@@ -1,508 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "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.Controls 1.0
|
||||
|
||||
import "utils.js" as Utils
|
||||
|
||||
QtObject{
|
||||
property string version: "1.0.1"
|
||||
|
||||
// STATIC CONSTANTS ////////////////////////////////////////////////////////
|
||||
|
||||
readonly property real minimumFontScaling: 0.25
|
||||
readonly property real maximumFontScaling: 2.50
|
||||
|
||||
// GENERAL SETTINGS ///////////////////////////////////////////////////////
|
||||
|
||||
property int x: 100
|
||||
property int y: 100
|
||||
property int width: 1024
|
||||
property int height: 768
|
||||
|
||||
property bool fullscreen: false
|
||||
property bool showMenubar: true
|
||||
|
||||
property string wintitle: "cool-retro-term"
|
||||
|
||||
property real windowOpacity: 1.0
|
||||
property real ambientLight: 0.2
|
||||
property real contrast: 0.85
|
||||
property real brightness: 0.5
|
||||
|
||||
property bool showTerminalSize: true
|
||||
property real windowScaling: 1.0
|
||||
|
||||
property real fps: 24
|
||||
property bool verbose: false
|
||||
|
||||
onWindowScalingChanged: handleFontChanged();
|
||||
|
||||
// PROFILE SETTINGS ///////////////////////////////////////////////////////
|
||||
|
||||
property bool useCustomCommand: false
|
||||
property string customCommand: ""
|
||||
|
||||
property string _backgroundColor: "#000000"
|
||||
property string _fontColor: "#ff8100"
|
||||
property string saturatedColor: Utils.mix(Utils.strToColor("#FFFFFF"), Utils.strToColor(_fontColor), saturationColor * 0.5)
|
||||
property color fontColor: Utils.mix(Utils.strToColor(saturatedColor), Utils.strToColor(_backgroundColor), 0.7 + (contrast * 0.3))
|
||||
property color backgroundColor: Utils.mix(Utils.strToColor(_backgroundColor), Utils.strToColor(saturatedColor), 0.7 + (contrast * 0.3))
|
||||
|
||||
property real staticNoise: 0.1
|
||||
property real screenCurvature: 0.1
|
||||
property real glowingLine: 0.2
|
||||
property real burnIn: 0.40
|
||||
property real bloom: 0.65
|
||||
|
||||
property real bloomQuality: 0.5
|
||||
property real burnInQuality: 0.5
|
||||
|
||||
property real chromaColor: 0.0
|
||||
property real saturationColor: 0.0
|
||||
|
||||
property real jitter: 0.18
|
||||
|
||||
property real horizontalSync: 0.08
|
||||
property real flickering: 0.1
|
||||
|
||||
property real rbgShift: 0.0
|
||||
|
||||
readonly property int no_rasterization: 0
|
||||
readonly property int scanline_rasterization: 1
|
||||
readonly property int pixel_rasterization: 2
|
||||
|
||||
property int rasterization: no_rasterization
|
||||
|
||||
// FONTS //////////////////////////////////////////////////////////////////
|
||||
|
||||
property real fontScaling: 1.0
|
||||
property real fontWidth: 1.0
|
||||
|
||||
property bool lowResolutionFont: false
|
||||
|
||||
property var fontNames: ["TERMINUS_SCALED", "COMMODORE_PET", "COMMODORE_PET"]
|
||||
property var fontlist: fontManager.item.fontlist
|
||||
|
||||
signal terminalFontChanged(string fontSource, int pixelSize, int lineSpacing, real screenScaling, real fontWidth)
|
||||
|
||||
signal initializedSettings()
|
||||
|
||||
property Loader fontManager: Loader{
|
||||
states: [
|
||||
State { when: rasterization == no_rasterization
|
||||
PropertyChanges {target: fontManager; source: "Fonts.qml" } },
|
||||
State { when: rasterization == scanline_rasterization
|
||||
PropertyChanges {target: fontManager; source: "FontScanlines.qml" } },
|
||||
State { when: rasterization == pixel_rasterization;
|
||||
PropertyChanges {target: fontManager; source: "FontPixels.qml" } }
|
||||
]
|
||||
|
||||
onLoaded: handleFontChanged()
|
||||
}
|
||||
|
||||
onFontScalingChanged: handleFontChanged();
|
||||
onFontWidthChanged: handleFontChanged();
|
||||
|
||||
function getIndexByName(name) {
|
||||
for (var i = 0; i < fontlist.count; i++) {
|
||||
if (name === fontlist.get(i).name)
|
||||
return i;
|
||||
}
|
||||
return 0; // If the font is not available default to 0.
|
||||
}
|
||||
|
||||
function incrementScaling(){
|
||||
fontScaling = Math.min(fontScaling + 0.05, maximumFontScaling);
|
||||
handleFontChanged();
|
||||
}
|
||||
|
||||
function decrementScaling(){
|
||||
fontScaling = Math.max(fontScaling - 0.05, minimumFontScaling);
|
||||
handleFontChanged();
|
||||
}
|
||||
|
||||
function handleFontChanged(){
|
||||
if (!fontManager.item) return;
|
||||
|
||||
var index = getIndexByName(fontNames[rasterization]);
|
||||
if (index === undefined) return;
|
||||
|
||||
fontManager.item.selectedFontIndex = index;
|
||||
fontManager.item.scaling = fontScaling * windowScaling;
|
||||
|
||||
var fontSource = fontManager.item.source;
|
||||
var pixelSize = fontManager.item.pixelSize;
|
||||
var lineSpacing = fontManager.item.lineSpacing;
|
||||
var screenScaling = fontManager.item.screenScaling;
|
||||
var fontWidth = fontManager.item.defaultFontWidth * appSettings.fontWidth;
|
||||
|
||||
lowResolutionFont = fontManager.item.lowResolutionFont;
|
||||
|
||||
terminalFontChanged(fontSource, pixelSize, lineSpacing, screenScaling, fontWidth);
|
||||
}
|
||||
|
||||
// FRAMES /////////////////////////////////////////////////////////////////
|
||||
|
||||
property ListModel framesList: ListModel{
|
||||
ListElement{
|
||||
name: "NO_FRAME"
|
||||
text: "No frame"
|
||||
source: ""
|
||||
reflections: false
|
||||
}
|
||||
ListElement{
|
||||
name: "SIMPLE_WHITE_FRAME"
|
||||
text: "Simple white frame"
|
||||
source: "./frames/WhiteSimpleFrame.qml"
|
||||
reflections: true
|
||||
}
|
||||
ListElement{
|
||||
name: "ROUGH_BLACK_FRAME"
|
||||
text: "Rough black frame"
|
||||
source: "./frames/BlackRoughFrame.qml"
|
||||
reflections: true
|
||||
}
|
||||
}
|
||||
|
||||
function getFrameIndexByName(name) {
|
||||
for (var i = 0; i < framesList.count; i++) {
|
||||
if (name === framesList.get(i).name)
|
||||
return i;
|
||||
}
|
||||
return 0; // If the frame is not available default to 0.
|
||||
}
|
||||
|
||||
property string frameSource: "./frames/WhiteSimpleFrame.qml"
|
||||
property string frameName: "SIMPLE_WHITE_FRAME"
|
||||
|
||||
property bool _frameReflections: false
|
||||
property bool reflectionsAllowed: true
|
||||
property bool frameReflections: _frameReflections && reflectionsAllowed
|
||||
|
||||
onFrameNameChanged: {
|
||||
var index = getFrameIndexByName(frameName);
|
||||
frameSource = framesList.get(index).source;
|
||||
reflectionsAllowed = framesList.get(index).reflections;
|
||||
}
|
||||
|
||||
// DB STORAGE /////////////////////////////////////////////////////////////
|
||||
|
||||
property Storage storage: Storage{ }
|
||||
|
||||
function stringify(obj) {
|
||||
var replacer = function(key, val) {
|
||||
return val.toFixed ? Number(val.toFixed(4)) : val;
|
||||
}
|
||||
return JSON.stringify(obj, replacer, 2);
|
||||
}
|
||||
|
||||
function composeSettingsString(){
|
||||
var settings = {
|
||||
fps: fps,
|
||||
x: x,
|
||||
y: y,
|
||||
width: width,
|
||||
height: height,
|
||||
windowScaling: windowScaling,
|
||||
showTerminalSize: showTerminalSize,
|
||||
fontScaling: fontScaling,
|
||||
fontNames: fontNames,
|
||||
frameReflections: _frameReflections,
|
||||
showMenubar: showMenubar,
|
||||
bloomQuality: bloomQuality,
|
||||
burnInQuality: burnInQuality
|
||||
}
|
||||
return stringify(settings);
|
||||
}
|
||||
|
||||
function composeProfileObject(){
|
||||
var settings = {
|
||||
backgroundColor: _backgroundColor,
|
||||
fontColor: _fontColor,
|
||||
flickering: flickering,
|
||||
horizontalSync: horizontalSync,
|
||||
staticNoise: staticNoise,
|
||||
chromaColor: chromaColor,
|
||||
saturationColor: saturationColor,
|
||||
screenCurvature: screenCurvature,
|
||||
glowingLine: glowingLine,
|
||||
frameName: frameName,
|
||||
burnIn: burnIn,
|
||||
bloom: bloom,
|
||||
rasterization: rasterization,
|
||||
jitter: jitter,
|
||||
rbgShift: rbgShift,
|
||||
brightness: brightness,
|
||||
contrast: contrast,
|
||||
ambientLight: ambientLight,
|
||||
windowOpacity: windowOpacity,
|
||||
fontName: fontNames[rasterization],
|
||||
fontWidth: fontWidth,
|
||||
useCustomCommand: useCustomCommand,
|
||||
customCommand: customCommand
|
||||
}
|
||||
return settings;
|
||||
}
|
||||
|
||||
function composeProfileString() {
|
||||
return stringify(composeProfileObject());
|
||||
}
|
||||
|
||||
function loadSettings(){
|
||||
var settingsString = storage.getSetting("_CURRENT_SETTINGS");
|
||||
var profileString = storage.getSetting("_CURRENT_PROFILE");
|
||||
|
||||
if(!settingsString) return;
|
||||
if(!profileString) return;
|
||||
|
||||
loadSettingsString(settingsString);
|
||||
loadProfileString(profileString);
|
||||
|
||||
if (verbose)
|
||||
console.log("Loading settings: " + settingsString + profileString);
|
||||
}
|
||||
|
||||
function storeSettings(){
|
||||
var settingsString = composeSettingsString();
|
||||
var profileString = composeProfileString();
|
||||
|
||||
storage.setSetting("_CURRENT_SETTINGS", settingsString);
|
||||
storage.setSetting("_CURRENT_PROFILE", profileString);
|
||||
|
||||
if (verbose) {
|
||||
console.log("Storing settings: " + settingsString);
|
||||
console.log("Storing profile: " + profileString);
|
||||
}
|
||||
}
|
||||
|
||||
function loadSettingsString(settingsString){
|
||||
var settings = JSON.parse(settingsString);
|
||||
|
||||
showTerminalSize = settings.showTerminalSize !== undefined ? settings.showTerminalSize : showTerminalSize
|
||||
|
||||
fps = settings.fps !== undefined ? settings.fps: fps
|
||||
windowScaling = settings.windowScaling !== undefined ? settings.windowScaling : windowScaling
|
||||
|
||||
x = settings.x !== undefined ? settings.x : x
|
||||
y = settings.y !== undefined ? settings.y : y
|
||||
width = settings.width !== undefined ? settings.width : width
|
||||
height = settings.height !== undefined ? settings.height : height
|
||||
|
||||
fontNames = settings.fontNames !== undefined ? settings.fontNames : fontNames
|
||||
fontScaling = settings.fontScaling !== undefined ? settings.fontScaling : fontScaling
|
||||
|
||||
_frameReflections = settings.frameReflections !== undefined ? settings.frameReflections : _frameReflections;
|
||||
|
||||
showMenubar = settings.showMenubar !== undefined ? settings.showMenubar : showMenubar;
|
||||
|
||||
bloomQuality = settings.bloomQuality !== undefined ? settings.bloomQuality : bloomQuality;
|
||||
burnInQuality = settings.burnInQuality !== undefined ? settings.burnInQuality : burnInQuality;
|
||||
}
|
||||
|
||||
function loadProfileString(profileString){
|
||||
var settings = JSON.parse(profileString);
|
||||
|
||||
_backgroundColor = settings.backgroundColor !== undefined ? settings.backgroundColor : _backgroundColor;
|
||||
_fontColor = settings.fontColor !== undefined ? settings.fontColor : _fontColor;
|
||||
|
||||
horizontalSync = settings.horizontalSync !== undefined ? settings.horizontalSync : horizontalSync
|
||||
flickering = settings.flickering !== undefined ? settings.flickering : flickering;
|
||||
staticNoise = settings.staticNoise !== undefined ? settings.staticNoise : staticNoise;
|
||||
chromaColor = settings.chromaColor !== undefined ? settings.chromaColor : chromaColor;
|
||||
saturationColor = settings.saturationColor !== undefined ? settings.saturationColor : saturationColor;
|
||||
screenCurvature = settings.screenCurvature !== undefined ? settings.screenCurvature : screenCurvature;
|
||||
glowingLine = settings.glowingLine !== undefined ? settings.glowingLine : glowingLine;
|
||||
|
||||
burnIn = settings.burnIn !== undefined ? settings.burnIn : burnIn
|
||||
bloom = settings.bloom !== undefined ? settings.bloom : bloom
|
||||
|
||||
frameName = settings.frameName !== undefined ? settings.frameName : frameName;
|
||||
|
||||
rasterization = settings.rasterization !== undefined ? settings.rasterization : rasterization;
|
||||
|
||||
jitter = settings.jitter !== undefined ? settings.jitter : jitter;
|
||||
|
||||
rbgShift = settings.rbgShift !== undefined ? settings.rbgShift : rbgShift;
|
||||
|
||||
ambientLight = settings.ambientLight !== undefined ? settings.ambientLight : ambientLight;
|
||||
contrast = settings.contrast !== undefined ? settings.contrast : contrast;
|
||||
brightness = settings.brightness !== undefined ? settings.brightness : brightness;
|
||||
windowOpacity = settings.windowOpacity !== undefined ? settings.windowOpacity : windowOpacity;
|
||||
|
||||
fontNames[rasterization] = settings.fontName !== undefined ? settings.fontName : fontNames[rasterization];
|
||||
fontWidth = settings.fontWidth !== undefined ? settings.fontWidth : fontWidth;
|
||||
|
||||
useCustomCommand = settings.useCustomCommand !== undefined ? settings.useCustomCommand : useCustomCommand
|
||||
customCommand = settings.customCommand !== undefined ? settings.customCommand : customCommand
|
||||
|
||||
handleFontChanged();
|
||||
}
|
||||
|
||||
function storeCustomProfiles(){
|
||||
storage.setSetting("_CUSTOM_PROFILES", composeCustomProfilesString());
|
||||
}
|
||||
|
||||
function loadCustomProfiles(){
|
||||
var customProfileString = storage.getSetting("_CUSTOM_PROFILES");
|
||||
if(customProfileString === undefined) customProfileString = "[]";
|
||||
loadCustomProfilesString(customProfileString);
|
||||
}
|
||||
|
||||
function loadCustomProfilesString(customProfilesString){
|
||||
var customProfiles = JSON.parse(customProfilesString);
|
||||
for (var i=0; i<customProfiles.length; i++) {
|
||||
var profile = customProfiles[i];
|
||||
|
||||
if (verbose)
|
||||
console.log("Loading custom profile: " + stringify(profile));
|
||||
|
||||
profilesList.append(profile);
|
||||
}
|
||||
}
|
||||
|
||||
function composeCustomProfilesString(){
|
||||
var customProfiles = []
|
||||
for(var i=0; i<profilesList.count; i++){
|
||||
var profile = profilesList.get(i);
|
||||
if(profile.builtin) continue;
|
||||
customProfiles.push({text: profile.text, obj_string: profile.obj_string, builtin: false})
|
||||
}
|
||||
return stringify(customProfiles);
|
||||
}
|
||||
|
||||
function loadProfile(index){
|
||||
var profile = profilesList.get(index);
|
||||
loadProfileString(profile.obj_string);
|
||||
}
|
||||
|
||||
function appendCustomProfile(name, profileString) {
|
||||
profilesList.append({text: name, obj_string: profileString, builtin: false});
|
||||
}
|
||||
|
||||
// PROFILES ///////////////////////////////////////////////////////////////
|
||||
|
||||
property ListModel profilesList: ListModel{
|
||||
ListElement{
|
||||
text: "Default Amber"
|
||||
obj_string: '{"ambientLight":0.16,"backgroundColor":"#000000","bloom":0.65,"brightness":0.5,"flickering":0.1,"contrast":0.85,"fontName":"TERMINUS_SCALED","fontColor":"#ff8100","frameName":"SIMPLE_WHITE_FRAME","glowingLine":0.2,"horizontalSync":0.16,"jitter":0.18,"burnIn":0.4,"staticNoise":0.1,"rasterization":0,"screenCurvature":0.1,"windowOpacity":1,"chromaColor":0,"saturationColor":0,"rbgShift":0,"fontWidth":1.0,"useCustomCommand":false,"customCommand":""}'
|
||||
builtin: true
|
||||
}
|
||||
ListElement{
|
||||
text: "Default Green"
|
||||
obj_string: '{"ambientLight":0.16,"backgroundColor":"#000000","bloom":0.4,"brightness":0.5,"flickering":0.1,"contrast":0.85,"fontName":"TERMINUS_SCALED","fontColor":"#0ccc68","frameName":"SIMPLE_WHITE_FRAME","glowingLine":0.2,"horizontalSync":0.16,"jitter":0.18,"burnIn":0.45,"staticNoise":0.1,"rasterization":0,"screenCurvature":0.1,"windowOpacity":1,"chromaColor":0,"saturationColor":0,"rbgShift":0,"fontWidth":1.0,"useCustomCommand":false,"customCommand":""}'
|
||||
builtin: true
|
||||
}
|
||||
ListElement{
|
||||
text: "Default Scanlines"
|
||||
obj_string: '{"ambientLight":0.16,"backgroundColor":"#000000","bloom":0.4,"brightness":0.5,"flickering":0.1,"contrast":0.85,"fontName":"COMMODORE_PET","fontColor":"#00ff5b","frameName":"SIMPLE_WHITE_FRAME","glowingLine":0.2,"horizontalSync":0.14,"jitter":0.11,"burnIn":0.4,"staticNoise":0.05,"rasterization":1,"screenCurvature":0.1,"windowOpacity":1,"chromaColor":0,"saturationColor":0,"rbgShift":0,"fontWidth":1.0,"useCustomCommand":false,"customCommand":""}'
|
||||
builtin: true
|
||||
}
|
||||
ListElement{
|
||||
text: "Default Pixelated"
|
||||
obj_string: '{"ambientLight":0.16,"backgroundColor":"#000000","bloom":0,"brightness":0.5,"flickering":0.2,"contrast":0.85,"fontName":"COMMODORE_PET","fontColor":"#ffffff","frameName":"ROUGH_BLACK_FRAME","glowingLine":0.2,"horizontalSync":0.2,"jitter":0,"burnIn":0.45,"staticNoise":0.19,"rasterization":2,"screenCurvature":0.05,"windowOpacity":1,"chromaColor":0,"saturationColor":0,"rbgShift":0,"fontWidth":1.0,"useCustomCommand":false,"customCommand":""}'
|
||||
builtin: true
|
||||
}
|
||||
ListElement{
|
||||
text: "Apple ]["
|
||||
obj_string: '{"ambientLight":0.16,"backgroundColor":"#000000","bloom":0.5,"brightness":0.5,"flickering":0.2,"contrast":0.85,"fontName":"APPLE_II","fontColor":"#2fff91","frameName":"SIMPLE_WHITE_FRAME","glowingLine":0.22,"horizontalSync":0.16,"jitter":0.1,"burnIn":0.65,"staticNoise":0.08,"rasterization":1,"screenCurvature":0.18,"windowOpacity":1,"chromaColor":0,"saturationColor":0,"rbgShift":0,"fontWidth":1.0,"useCustomCommand":false,"customCommand":""}'
|
||||
builtin: true
|
||||
}
|
||||
ListElement{
|
||||
text: "Vintage"
|
||||
obj_string: '{"ambientLight":0.5,"backgroundColor":"#000000","bloom":0.4,"brightness":0.5,"flickering":0.9,"contrast":0.80,"fontName":"COMMODORE_PET","fontColor":"#00ff3e","frameName":"ROUGH_BLACK_FRAME","glowingLine":0.3,"horizontalSync":0.42,"jitter":0.4,"burnIn":0.75,"staticNoise":0.2,"rasterization":1,"screenCurvature":0.1,"windowOpacity":1,"chromaColor":0,"saturationColor":0,"rbgShift":0,"fontWidth":1.0,"useCustomCommand":false,"customCommand":""}'
|
||||
builtin: true
|
||||
}
|
||||
ListElement{
|
||||
text: "IBM Dos"
|
||||
obj_string: '{"ambientLight":0.16,"backgroundColor":"#000000","bloom":0.4,"brightness":0.5,"flickering":0.07,"contrast":0.85,"fontName":"IBM_DOS","fontColor":"#ffffff","frameName":"SIMPLE_WHITE_FRAME","glowingLine":0.13,"horizontalSync":0,"jitter":0.16,"burnIn":0.3,"staticNoise":0.03,"rasterization":0,"screenCurvature":0.1,"windowOpacity":1,"chromaColor":1,"saturationColor":0,"rbgShift":0.35,"fontWidth":1.0,"useCustomCommand":false,"customCommand":""}'
|
||||
builtin: true
|
||||
}
|
||||
ListElement{
|
||||
text: "IBM 3278"
|
||||
obj_string: '{"ambientLight":0.1,"backgroundColor":"#000000","bloom":0.15,"brightness":0.5,"flickering":0,"contrast":0.85,"fontName":"IBM_3278","fontColor":"#0ccc68","frameName":"SIMPLE_WHITE_FRAME","glowingLine":0,"horizontalSync":0,"jitter":0,"burnIn":0.6,"staticNoise":0,"rasterization":0,"screenCurvature":0.1,"windowOpacity":1,"chromaColor":0,"saturationColor":0,"rbgShift":0,"fontWidth":1.0,"useCustomCommand":false,"customCommand":""}'
|
||||
builtin: true
|
||||
}
|
||||
ListElement{
|
||||
text: "Knight TV"
|
||||
obj_string: '{"ambientLight":0.16,"backgroundColor":"#000000","bloom":0.45,"brightness":0.5,"burnIn":0.3,"chromaColor":0,"contrast":0.85,"customCommand":"","flickering":0.1,"fontColor":"#0ccc68","fontName":"Knight_TV","fontWidth":1,"frameName":"SIMPLE_WHITE_FRAME","glowingLine":0,"horizontalSync":0.16,"jitter":0,"rasterization":0,"rbgShift":0,"saturationColor":0,"screenCurvature":0.07,"staticNoise":0,"useCustomCommand":false,"windowOpacity":1}'
|
||||
builtin: true
|
||||
}
|
||||
ListElement{
|
||||
text: "Transparent Green"
|
||||
obj_string: '{"ambientLight":0.2,"backgroundColor":"#000000","bloom":0.45,"brightness":0.5,"flickering":0.20,"contrast":0.85,"fontName":"TERMINUS_SCALED","fontColor":"#0ccc68","frameName":"NO_FRAME","glowingLine":0.16,"horizontalSync":0.1,"jitter":0.20,"burnIn":0.25,"staticNoise":0.20,"rasterization":0,"screenCurvature":0.05,"windowOpacity":0.60,"chromaColor":0,"saturationColor":0,"rbgShift":0,"fontWidth":1.0,"useCustomCommand":false,"customCommand":""}'
|
||||
builtin: true
|
||||
}
|
||||
}
|
||||
|
||||
function getProfileIndexByName(name) {
|
||||
for (var i = 0; i < profilesList.count; i++) {
|
||||
if(profilesList.get(i).text === name)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
// Manage the arguments from the QML side.
|
||||
var args = Qt.application.arguments;
|
||||
if (args.indexOf("--verbose") !== -1) {
|
||||
verbose = true;
|
||||
}
|
||||
if (args.indexOf("--default-settings") === -1) {
|
||||
loadSettings();
|
||||
}
|
||||
|
||||
loadCustomProfiles();
|
||||
|
||||
var profileArgPosition = args.indexOf("--profile");
|
||||
if (profileArgPosition !== -1) {
|
||||
var profileIndex = getProfileIndexByName(args[profileArgPosition + 1]);
|
||||
if (profileIndex !== -1)
|
||||
loadProfile(profileIndex);
|
||||
else
|
||||
console.log("Warning: selected profile is not valid; ignoring it");
|
||||
}
|
||||
|
||||
if (args.indexOf("--fullscreen") !== -1) {
|
||||
fullscreen = true;
|
||||
showMenubar = false;
|
||||
}
|
||||
|
||||
if (args.indexOf("-T") !== -1) {
|
||||
wintitle = args[args.indexOf("-T") + 1]
|
||||
}
|
||||
|
||||
initializedSettings();
|
||||
}
|
||||
Component.onDestruction: {
|
||||
storeSettings();
|
||||
storeCustomProfiles();
|
||||
//storage.dropSettings(); //DROPS THE SETTINGS!.. REMEMBER TO DISABLE ONCE ENABLED!!
|
||||
}
|
||||
|
||||
// VARS ///////////////////////////////////////////////////////////////////
|
||||
|
||||
property Label _sampleLabel: Label {
|
||||
text: "100%"
|
||||
}
|
||||
property real labelWidth: _sampleLabel.width
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.1
|
||||
|
||||
MenuBar {
|
||||
id: defaultMenuBar
|
||||
property bool visible: true
|
||||
Menu {
|
||||
title: qsTr("File")
|
||||
visible: defaultMenuBar.visible
|
||||
MenuItem {action: quitAction}
|
||||
}
|
||||
Menu {
|
||||
title: qsTr("Edit")
|
||||
visible: defaultMenuBar.visible
|
||||
MenuItem {action: copyAction}
|
||||
MenuItem {action: pasteAction}
|
||||
MenuSeparator{visible: Qt.platform.os !== "osx"}
|
||||
MenuItem {action: showsettingsAction}
|
||||
}
|
||||
Menu{
|
||||
title: qsTr("View")
|
||||
visible: defaultMenuBar.visible
|
||||
MenuItem {action: fullscreenAction; visible: fullscreenAction.enabled}
|
||||
MenuItem {action: showMenubarAction; visible: showMenubarAction.enabled}
|
||||
MenuSeparator{visible: showMenubarAction.enabled}
|
||||
MenuItem {action: zoomIn}
|
||||
MenuItem {action: zoomOut}
|
||||
}
|
||||
Menu{
|
||||
id: profilesMenu
|
||||
title: qsTr("Profiles")
|
||||
visible: defaultMenuBar.visible
|
||||
Instantiator{
|
||||
model: appSettings.profilesList
|
||||
delegate: MenuItem {
|
||||
text: model.text
|
||||
onTriggered: {
|
||||
appSettings.loadProfileString(obj_string);
|
||||
appSettings.handleFontChanged();
|
||||
}
|
||||
}
|
||||
onObjectAdded: profilesMenu.insertItem(index, object)
|
||||
onObjectRemoved: profilesMenu.removeItem(object)
|
||||
}
|
||||
}
|
||||
Menu{
|
||||
title: qsTr("Help")
|
||||
visible: defaultMenuBar.visible
|
||||
MenuItem {action: showAboutAction}
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "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.Controls 1.0
|
||||
|
||||
// This component is simply a label with a predefined size.
|
||||
// Used to improve alignment.
|
||||
|
||||
Item {
|
||||
property alias text: textfield.text
|
||||
width: appSettings.labelWidth
|
||||
Label{
|
||||
id: textfield
|
||||
anchors { right: parent.right; verticalCenter: parent.verticalCenter }
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "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
|
||||
|
||||
QtObject{
|
||||
property int selectedFontIndex
|
||||
property real scaling
|
||||
property var _font: fontlist.get(selectedFontIndex)
|
||||
property var source: _font.source
|
||||
property int pixelSize: _font.pixelSize
|
||||
property int lineSpacing: _font.lineSpacing
|
||||
property real screenScaling: scaling * _font.baseScaling
|
||||
property real defaultFontWidth: fontlist.get(selectedFontIndex).fontWidth
|
||||
property bool lowResolutionFont: true
|
||||
|
||||
property ListModel fontlist: ListModel{
|
||||
ListElement{
|
||||
name: "COMMODORE_PET"
|
||||
text: "Commodore PET (1977)"
|
||||
source: "fonts/1977-commodore-pet/COMMODORE_PET.ttf"
|
||||
lineSpacing: 2
|
||||
pixelSize: 8
|
||||
baseScaling: 4.0
|
||||
fontWidth: 0.8
|
||||
}
|
||||
ListElement{
|
||||
name: "PROGGY_TINY"
|
||||
text: "Proggy Tiny (Modern)"
|
||||
source: "fonts/modern-proggy-tiny/ProggyTiny.ttf"
|
||||
lineSpacing: 1
|
||||
pixelSize: 16
|
||||
baseScaling: 4.0
|
||||
fontWidth: 0.9
|
||||
}
|
||||
ListElement{
|
||||
name: "TERMINUS_SCALED"
|
||||
text: "Terminus (Modern)"
|
||||
source: "fonts/modern-terminus/TerminusTTF-4.38.2.ttf"
|
||||
lineSpacing: 1
|
||||
pixelSize: 12
|
||||
baseScaling: 3.0
|
||||
fontWidth: 1.0
|
||||
}
|
||||
ListElement{
|
||||
name: "PRO_FONT_SCALED"
|
||||
text: "Pro Font (Modern)"
|
||||
source: "fonts/modern-pro-font-win-tweaked/ProFontWindows.ttf"
|
||||
lineSpacing: 1
|
||||
pixelSize: 12
|
||||
baseScaling: 3.0
|
||||
fontWidth: 1.0
|
||||
}
|
||||
ListElement{
|
||||
name: "APPLE_II"
|
||||
text: "Apple ][ (1977)"
|
||||
source: "fonts/1977-apple2/PrintChar21.ttf"
|
||||
lineSpacing: 2
|
||||
pixelSize: 8
|
||||
baseScaling: 4.0
|
||||
fontWidth: 0.9
|
||||
}
|
||||
ListElement{
|
||||
name: "ATARI_400"
|
||||
text: "Atari 400-800 (1979)"
|
||||
source: "fonts/1979-atari-400-800/ATARI400800_original.TTF"
|
||||
lineSpacing: 3
|
||||
pixelSize: 8
|
||||
baseScaling: 4.0
|
||||
fontWidth: 0.8
|
||||
}
|
||||
ListElement{
|
||||
name: "COMMODORE_64"
|
||||
text: "Commodore 64 (1982)"
|
||||
source: "fonts/1982-commodore64/C64_Pro_Mono_v1.0-STYLE.ttf"
|
||||
lineSpacing: 3
|
||||
pixelSize: 8
|
||||
baseScaling: 4.0
|
||||
fontWidth: 0.8
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "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
|
||||
|
||||
QtObject{
|
||||
property int selectedFontIndex
|
||||
property real scaling
|
||||
property var _font: fontlist.get(selectedFontIndex)
|
||||
property var source: _font.source
|
||||
property int pixelSize: _font.pixelSize
|
||||
property int lineSpacing: _font.lineSpacing
|
||||
property real screenScaling: scaling * _font.baseScaling
|
||||
property real defaultFontWidth: fontlist.get(selectedFontIndex).fontWidth
|
||||
property bool lowResolutionFont: true
|
||||
|
||||
property ListModel fontlist: ListModel{
|
||||
ListElement{
|
||||
name: "COMMODORE_PET"
|
||||
text: "Commodore PET (1977)"
|
||||
source: "fonts/1977-commodore-pet/COMMODORE_PET.ttf"
|
||||
lineSpacing: 2
|
||||
pixelSize: 8
|
||||
baseScaling: 4.0
|
||||
fontWidth: 0.7
|
||||
}
|
||||
ListElement{
|
||||
name: "PROGGY_TINY"
|
||||
text: "Proggy Tiny (Modern)"
|
||||
source: "fonts/modern-proggy-tiny/ProggyTiny.ttf"
|
||||
lineSpacing: 1
|
||||
pixelSize: 16
|
||||
baseScaling: 4.0
|
||||
fontWidth: 0.9
|
||||
}
|
||||
ListElement{
|
||||
name: "TERMINUS_SCALED"
|
||||
text: "Terminus (Modern)"
|
||||
source: "fonts/modern-terminus/TerminusTTF-4.38.2.ttf"
|
||||
lineSpacing: 1
|
||||
pixelSize: 12
|
||||
baseScaling: 3.0
|
||||
fontWidth: 1.0
|
||||
}
|
||||
ListElement{
|
||||
name: "PRO_FONT_SCALED"
|
||||
text: "Pro Font (Modern)"
|
||||
source: "fonts/modern-pro-font-win-tweaked/ProFontWindows.ttf"
|
||||
lineSpacing: 1
|
||||
pixelSize: 12
|
||||
baseScaling: 3.0
|
||||
fontWidth: 1.0
|
||||
}
|
||||
ListElement{
|
||||
name: "APPLE_II"
|
||||
text: "Apple ][ (1977)"
|
||||
source: "fonts/1977-apple2/PrintChar21.ttf"
|
||||
lineSpacing: 2
|
||||
pixelSize: 8
|
||||
baseScaling: 4.0
|
||||
fontWidth: 0.8
|
||||
}
|
||||
ListElement{
|
||||
name: "ATARI_400"
|
||||
text: "Atari 400-800 (1979)"
|
||||
source: "fonts/1979-atari-400-800/ATARI400800_original.TTF"
|
||||
lineSpacing: 3
|
||||
pixelSize: 8
|
||||
baseScaling: 4.0
|
||||
fontWidth: 0.7
|
||||
}
|
||||
ListElement{
|
||||
name: "COMMODORE_64"
|
||||
text: "Commodore 64 (1982)"
|
||||
source: "fonts/1982-commodore64/C64_Pro_Mono_v1.0-STYLE.ttf"
|
||||
lineSpacing: 3
|
||||
pixelSize: 8
|
||||
baseScaling: 4.0
|
||||
fontWidth: 0.7
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,218 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "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
|
||||
|
||||
QtObject{
|
||||
property int selectedFontIndex
|
||||
property real scaling
|
||||
property var source: fontlist.get(selectedFontIndex).source
|
||||
property var _font: fontlist.get(selectedFontIndex)
|
||||
property bool lowResolutionFont: _font.lowResolutionFont
|
||||
|
||||
property int pixelSize: lowResolutionFont
|
||||
? _font.pixelSize
|
||||
: _font.pixelSize * scaling
|
||||
|
||||
property int lineSpacing: lowResolutionFont
|
||||
? _font.lineSpacing
|
||||
: pixelSize * _font.lineSpacing
|
||||
|
||||
property real screenScaling: lowResolutionFont
|
||||
? _font.baseScaling * scaling
|
||||
: 1.0
|
||||
|
||||
property real defaultFontWidth: fontlist.get(selectedFontIndex).fontWidth
|
||||
|
||||
// There are two kind of fonts: low resolution and high resolution.
|
||||
// Low resolution font sets the lowResolutionFont property to true.
|
||||
// They are rendered at a fixed pixel size and the texture is upscaled
|
||||
// to fill the screen (they are much faster to render).
|
||||
// High resolution fonts are instead drawn on a texture which has the
|
||||
// size of the screen, and the scaling directly controls their pixels size.
|
||||
// Those are slower to render but are not pixelated.
|
||||
|
||||
property ListModel fontlist: ListModel{
|
||||
ListElement{
|
||||
name: "TERMINUS_SCALED"
|
||||
text: "Terminus (Modern)"
|
||||
source: "fonts/modern-terminus/TerminusTTF-4.38.2.ttf"
|
||||
lineSpacing: 1
|
||||
pixelSize: 12
|
||||
baseScaling: 3.0
|
||||
fontWidth: 1.0
|
||||
lowResolutionFont: true
|
||||
}
|
||||
ListElement{
|
||||
name: "PRO_FONT_SCALED"
|
||||
text: "Pro Font (Modern)"
|
||||
source: "fonts/modern-pro-font-win-tweaked/ProFontWindows.ttf"
|
||||
lineSpacing: 1
|
||||
pixelSize: 12
|
||||
baseScaling: 3.0
|
||||
fontWidth: 1.0
|
||||
lowResolutionFont: true
|
||||
}
|
||||
ListElement{
|
||||
name: "EXCELSIOR_SCALED"
|
||||
text: "Fixedsys Excelsior (Modern)"
|
||||
source: "fonts/modern-fixedsys-excelsior/FSEX301-L2.ttf"
|
||||
lineSpacing: 0
|
||||
pixelSize: 16
|
||||
baseScaling: 2.4
|
||||
fontWidth: 1.0
|
||||
lowResolutionFont: true
|
||||
}
|
||||
ListElement{
|
||||
name: "COMMODORE_PET_SCALED"
|
||||
text: "Commodore PET (1977)"
|
||||
source: "fonts/1977-commodore-pet/COMMODORE_PET.ttf"
|
||||
lineSpacing: 2
|
||||
pixelSize: 8
|
||||
baseScaling: 3.5
|
||||
fontWidth: 0.7
|
||||
lowResolutionFont: true
|
||||
}
|
||||
ListElement{
|
||||
name: "PROGGY_TINY_SCALED"
|
||||
text: "Proggy Tiny (Modern)"
|
||||
source: "fonts/modern-proggy-tiny/ProggyTiny.ttf"
|
||||
lineSpacing: 1
|
||||
pixelSize: 16
|
||||
baseScaling: 3.0
|
||||
fontWidth: 0.9
|
||||
lowResolutionFont: true
|
||||
}
|
||||
ListElement{
|
||||
name: "APPLE_II_SCALED"
|
||||
text: "Apple ][ (1977)"
|
||||
source: "fonts/1977-apple2/PrintChar21.ttf"
|
||||
lineSpacing: 2
|
||||
pixelSize: 8
|
||||
baseScaling: 3.5
|
||||
fontWidth: 0.8
|
||||
lowResolutionFont: true
|
||||
}
|
||||
ListElement{
|
||||
name: "ATARI_400_SCALED"
|
||||
text: "Atari 400-800 (1979)"
|
||||
source: "fonts/1979-atari-400-800/ATARI400800_original.TTF"
|
||||
lineSpacing: 3
|
||||
pixelSize: 8
|
||||
baseScaling: 3.5
|
||||
fontWidth: 0.7
|
||||
lowResolutionFont: true
|
||||
}
|
||||
ListElement{
|
||||
name: "COMMODORE_64_SCALED"
|
||||
text: "Commodore 64 (1982)"
|
||||
source: "fonts/1982-commodore64/C64_Pro_Mono_v1.0-STYLE.ttf"
|
||||
lineSpacing: 3
|
||||
pixelSize: 8
|
||||
baseScaling: 3.5
|
||||
fontWidth: 0.7
|
||||
lowResolutionFont: true
|
||||
}
|
||||
ListElement{
|
||||
name: "ATARI_ST_SCALED"
|
||||
text: "Atari ST (1985)"
|
||||
source: "fonts/1985-atari-st/AtariST8x16SystemFont.ttf"
|
||||
lineSpacing: 3
|
||||
pixelSize: 16
|
||||
baseScaling: 2.0
|
||||
fontWidth: 1.0
|
||||
lowResolutionFont: true
|
||||
}
|
||||
ListElement{
|
||||
name: "IBM_DOS"
|
||||
text: "IBM DOS (1985)"
|
||||
source: "fonts/1985-ibm-pc-vga/Perfect DOS VGA 437 Win.ttf"
|
||||
lineSpacing: 3
|
||||
pixelSize: 16
|
||||
baseScaling: 2.0
|
||||
fontWidth: 1.0
|
||||
lowResolutionFont: true
|
||||
}
|
||||
ListElement{
|
||||
name: "HERMIT"
|
||||
text: "HD: Hermit (Modern)"
|
||||
source: "fonts/modern-hermit/Hermit-medium.otf"
|
||||
lineSpacing: 0.05
|
||||
pixelSize: 28
|
||||
fontWidth: 1.0
|
||||
lowResolutionFont: false
|
||||
}
|
||||
ListElement{
|
||||
name: "TERMINUS"
|
||||
text: "HD: Terminus (Modern)"
|
||||
source: "fonts/modern-terminus/TerminusTTF-4.38.2.ttf"
|
||||
lineSpacing: 0.1
|
||||
pixelSize: 35
|
||||
fontWidth: 1.0
|
||||
lowResolutionFont: false
|
||||
}
|
||||
ListElement{
|
||||
name: "PRO_FONT"
|
||||
text: "HD: Pro Font (Modern)"
|
||||
source: "fonts/modern-pro-font-win-tweaked/ProFontWindows.ttf"
|
||||
lineSpacing: 0.1
|
||||
pixelSize: 35
|
||||
fontWidth: 1.0
|
||||
lowResolutionFont: false
|
||||
}
|
||||
ListElement{
|
||||
name: "MONACO"
|
||||
text: "HD: Monaco (Modern)"
|
||||
source: "fonts/modern-monaco/monaco.ttf"
|
||||
lineSpacing: 0.1
|
||||
pixelSize: 30
|
||||
fontWidth: 1.0
|
||||
lowResolutionFont: false
|
||||
}
|
||||
ListElement{
|
||||
name: "INCONSOLATA"
|
||||
text: "HD: Inconsolata (Modern)"
|
||||
source: "fonts/modern-inconsolata/Inconsolata.otf"
|
||||
lineSpacing: 0.1
|
||||
pixelSize: 35
|
||||
fontWidth: 1.0
|
||||
lowResolutionFont: false
|
||||
}
|
||||
ListElement{
|
||||
name: "IBM_3278"
|
||||
text: "HD: IBM 3278 (1971)"
|
||||
source: "fonts/1971-ibm-3278/3270Medium.ttf"
|
||||
lineSpacing: 0.2
|
||||
pixelSize: 32
|
||||
fontWidth: 1.0
|
||||
lowResolutionFont: false
|
||||
}
|
||||
ListElement{
|
||||
name: "Knight_TV"
|
||||
text: "Knight TV (1975)"
|
||||
source: "fonts/1975-knight-tv/KnightTVMedium.ttf"
|
||||
lineSpacing: 0.2
|
||||
pixelSize: 10
|
||||
fontWidth: 1.0
|
||||
baseScaling: 3.0
|
||||
lowResolutionFont: true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,351 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "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.Controls 1.1
|
||||
|
||||
import QMLTermWidget 1.0
|
||||
|
||||
import "utils.js" as Utils
|
||||
|
||||
Item{
|
||||
id: terminalContainer
|
||||
|
||||
property size virtualResolution: Qt.size(kterminal.width, kterminal.height)
|
||||
property alias mainTerminal: kterminal
|
||||
property ShaderEffectSource mainSource: kterminalSource
|
||||
property ShaderEffectSource blurredSource: blurredSourceLoader.item
|
||||
|
||||
property real fontWidth: 1.0
|
||||
property real screenScaling: 1.0
|
||||
property real scaleTexture: 1.0
|
||||
property alias title: ksession.title
|
||||
property alias kterminal: kterminal
|
||||
|
||||
anchors.leftMargin: frame.displacementLeft * appSettings.windowScaling
|
||||
anchors.rightMargin: frame.displacementRight * appSettings.windowScaling
|
||||
anchors.topMargin: frame.displacementTop * appSettings.windowScaling
|
||||
anchors.bottomMargin: frame.displacementBottom * appSettings.windowScaling
|
||||
|
||||
//Parameters for the burnIn effect.
|
||||
property real burnIn: appSettings.burnIn
|
||||
property real fps: appSettings.fps !== 0 ? appSettings.fps : 60
|
||||
property real burnInFadeTime: Utils.lint(_minBurnInFadeTime, _maxBurnInFadeTime, burnIn)
|
||||
property real motionBlurCoefficient: 1.0 / (fps * burnInFadeTime)
|
||||
property real _minBurnInFadeTime: 0.16
|
||||
property real _maxBurnInFadeTime: 1.6
|
||||
|
||||
property size terminalSize: kterminal.terminalSize
|
||||
property size fontMetrics: kterminal.fontMetrics
|
||||
|
||||
// Manage copy and paste
|
||||
Connections{
|
||||
target: copyAction
|
||||
onTriggered: kterminal.copyClipboard();
|
||||
}
|
||||
Connections{
|
||||
target: pasteAction
|
||||
onTriggered: kterminal.pasteClipboard()
|
||||
}
|
||||
|
||||
//When settings are updated sources need to be redrawn.
|
||||
Connections{
|
||||
target: appSettings
|
||||
onFontScalingChanged: terminalContainer.updateSources();
|
||||
onFontWidthChanged: terminalContainer.updateSources();
|
||||
}
|
||||
Connections{
|
||||
target: terminalContainer
|
||||
onWidthChanged: terminalContainer.updateSources();
|
||||
onHeightChanged: terminalContainer.updateSources();
|
||||
}
|
||||
function updateSources() {
|
||||
kterminal.update();
|
||||
}
|
||||
|
||||
QMLTermWidget {
|
||||
id: kterminal
|
||||
width: Math.floor(parent.width / (screenScaling * fontWidth))
|
||||
height: Math.floor(parent.height / screenScaling)
|
||||
|
||||
colorScheme: "cool-retro-term"
|
||||
|
||||
smooth: !appSettings.lowResolutionFont
|
||||
enableBold: false
|
||||
fullCursorHeight: true
|
||||
|
||||
session: QMLTermSession {
|
||||
id: ksession
|
||||
|
||||
onFinished: {
|
||||
Qt.quit()
|
||||
}
|
||||
}
|
||||
|
||||
QMLTermScrollbar {
|
||||
id: kterminalScrollbar
|
||||
terminal: kterminal
|
||||
anchors.margins: width * 0.5
|
||||
width: terminal.fontMetrics.width * 0.75
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.topMargin: 1
|
||||
anchors.bottomMargin: 1
|
||||
color: "white"
|
||||
radius: width * 0.25
|
||||
opacity: 0.7
|
||||
}
|
||||
}
|
||||
|
||||
FontLoader{ id: fontLoader }
|
||||
|
||||
function handleFontChange(fontSource, pixelSize, lineSpacing, screenScaling, fontWidth){
|
||||
fontLoader.source = fontSource;
|
||||
|
||||
kterminal.antialiasText = !appSettings.lowResolutionFont;
|
||||
font.pixelSize = pixelSize;
|
||||
font.family = fontLoader.name;
|
||||
|
||||
terminalContainer.fontWidth = fontWidth;
|
||||
terminalContainer.screenScaling = screenScaling;
|
||||
scaleTexture = Math.max(1.0, Math.floor(screenScaling * appSettings.windowScaling));
|
||||
|
||||
kterminal.lineSpacing = lineSpacing;
|
||||
}
|
||||
function startSession() {
|
||||
appSettings.initializedSettings.disconnect(startSession);
|
||||
|
||||
// Retrieve the variable set in main.cpp if arguments are passed.
|
||||
if (defaultCmd) {
|
||||
ksession.setShellProgram(defaultCmd);
|
||||
ksession.setArgs(defaultCmdArgs);
|
||||
} else if (appSettings.useCustomCommand) {
|
||||
var args = Utils.tokenizeCommandLine(appSettings.customCommand);
|
||||
ksession.setShellProgram(args[0]);
|
||||
ksession.setArgs(args.slice(1));
|
||||
} else if (!defaultCmd && Qt.platform.os === "osx") {
|
||||
// OSX Requires the following default parameters for auto login.
|
||||
ksession.setArgs(["-i", "-l"]);
|
||||
}
|
||||
|
||||
if (workdir)
|
||||
ksession.initialWorkingDirectory = workdir;
|
||||
|
||||
ksession.startShellProgram();
|
||||
forceActiveFocus();
|
||||
}
|
||||
Component.onCompleted: {
|
||||
appSettings.terminalFontChanged.connect(handleFontChange);
|
||||
appSettings.initializedSettings.connect(startSession);
|
||||
}
|
||||
}
|
||||
Component {
|
||||
id: linuxContextMenu
|
||||
Menu{
|
||||
id: contextmenu
|
||||
MenuItem{action: copyAction}
|
||||
MenuItem{action: pasteAction}
|
||||
MenuSeparator{}
|
||||
MenuItem{action: fullscreenAction}
|
||||
MenuItem{action: showMenubarAction}
|
||||
MenuSeparator{visible: !appSettings.showMenubar}
|
||||
CRTMainMenuBar{visible: !appSettings.showMenubar}
|
||||
}
|
||||
}
|
||||
Component {
|
||||
id: osxContextMenu
|
||||
Menu{
|
||||
id: contextmenu
|
||||
MenuItem{action: copyAction}
|
||||
MenuItem{action: pasteAction}
|
||||
}
|
||||
}
|
||||
Loader {
|
||||
id: menuLoader
|
||||
sourceComponent: (Qt.platform.os === "osx" ? osxContextMenu : linuxContextMenu)
|
||||
}
|
||||
property alias contextmenu: menuLoader.item
|
||||
|
||||
MouseArea{
|
||||
acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton
|
||||
anchors.fill: parent
|
||||
cursorShape: kterminal.terminalUsesMouse ? Qt.ArrowCursor : Qt.IBeamCursor
|
||||
onWheel:{
|
||||
if(wheel.modifiers & Qt.ControlModifier){
|
||||
wheel.angleDelta.y > 0 ? zoomIn.trigger() : zoomOut.trigger();
|
||||
} else {
|
||||
var coord = correctDistortion(wheel.x, wheel.y);
|
||||
kterminal.simulateWheel(coord.x, coord.y, wheel.buttons, wheel.modifiers, wheel.angleDelta);
|
||||
}
|
||||
}
|
||||
onDoubleClicked: {
|
||||
var coord = correctDistortion(mouse.x, mouse.y);
|
||||
kterminal.simulateMouseDoubleClick(coord.x, coord.y, mouse.button, mouse.buttons, mouse.modifiers);
|
||||
}
|
||||
onPressed: {
|
||||
if((!kterminal.terminalUsesMouse || mouse.modifiers & Qt.ShiftModifier) && mouse.button == Qt.RightButton) {
|
||||
contextmenu.popup();
|
||||
} else {
|
||||
var coord = correctDistortion(mouse.x, mouse.y);
|
||||
kterminal.simulateMousePress(coord.x, coord.y, mouse.button, mouse.buttons, mouse.modifiers)
|
||||
}
|
||||
}
|
||||
onReleased: {
|
||||
var coord = correctDistortion(mouse.x, mouse.y);
|
||||
kterminal.simulateMouseRelease(coord.x, coord.y, mouse.button, mouse.buttons, mouse.modifiers);
|
||||
}
|
||||
onPositionChanged: {
|
||||
var coord = correctDistortion(mouse.x, mouse.y);
|
||||
kterminal.simulateMouseMove(coord.x, coord.y, mouse.button, mouse.buttons, mouse.modifiers);
|
||||
}
|
||||
|
||||
function correctDistortion(x, y){
|
||||
x = x / width;
|
||||
y = y / height;
|
||||
|
||||
var cc = Qt.size(0.5 - x, 0.5 - y);
|
||||
var distortion = (cc.height * cc.height + cc.width * cc.width) * appSettings.screenCurvature;
|
||||
|
||||
return Qt.point((x - cc.width * (1+distortion) * distortion) * kterminal.width,
|
||||
(y - cc.height * (1+distortion) * distortion) * kterminal.height)
|
||||
}
|
||||
}
|
||||
ShaderEffectSource{
|
||||
id: kterminalSource
|
||||
sourceItem: kterminal
|
||||
hideSource: true
|
||||
wrapMode: ShaderEffectSource.ClampToEdge
|
||||
visible: false
|
||||
textureSize: Qt.size(kterminal.width * scaleTexture, kterminal.height * scaleTexture);
|
||||
}
|
||||
Loader{
|
||||
id: blurredSourceLoader
|
||||
asynchronous: true
|
||||
active: burnIn !== 0
|
||||
|
||||
sourceComponent: ShaderEffectSource{
|
||||
property bool updateBurnIn: false
|
||||
|
||||
id: _blurredSourceEffect
|
||||
sourceItem: blurredTerminalLoader.item
|
||||
recursive: true
|
||||
live: false
|
||||
hideSource: true
|
||||
wrapMode: kterminalSource.wrapMode
|
||||
|
||||
visible: false
|
||||
|
||||
function restartBlurSource(){
|
||||
livetimer.restart();
|
||||
}
|
||||
|
||||
// This updates the burnin synched with the timer.
|
||||
Connections {
|
||||
target: updateBurnIn ? mainShader : null
|
||||
ignoreUnknownSignals: false
|
||||
onTimeChanged: _blurredSourceEffect.scheduleUpdate();
|
||||
}
|
||||
|
||||
Timer{
|
||||
id: livetimer
|
||||
|
||||
// The interval assumes 60 fps. This is the time needed burnout a white pixel.
|
||||
// We multiply 1.1 to have a little bit of margin over the theoretical value.
|
||||
// This solution is not extremely clean, but it's probably the best to avoid measuring fps.
|
||||
|
||||
interval: burnInFadeTime * 1000 * 1.1
|
||||
running: true
|
||||
onTriggered: _blurredSourceEffect.updateBurnIn = false;
|
||||
}
|
||||
Connections{
|
||||
target: kterminal
|
||||
onImagePainted:{
|
||||
_blurredSourceEffect.scheduleUpdate();
|
||||
_blurredSourceEffect.updateBurnIn = true;
|
||||
livetimer.restart();
|
||||
}
|
||||
}
|
||||
// Restart blurred source settings change.
|
||||
Connections{
|
||||
target: appSettings
|
||||
onBurnInChanged: _blurredSourceEffect.restartBlurSource();
|
||||
onTerminalFontChanged: _blurredSourceEffect.restartBlurSource();
|
||||
onRasterizationChanged: _blurredSourceEffect.restartBlurSource();
|
||||
onBurnInQualityChanged: _blurredSourceEffect.restartBlurSource();
|
||||
}
|
||||
Connections {
|
||||
target: kterminalScrollbar
|
||||
onOpacityChanged: _blurredSourceEffect.restartBlurSource();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loader{
|
||||
id: blurredTerminalLoader
|
||||
|
||||
property int burnInScaling: scaleTexture * appSettings.burnInQuality
|
||||
|
||||
width: appSettings.lowResolutionFont
|
||||
? kterminal.width * Math.max(1, burnInScaling)
|
||||
: kterminal.width * scaleTexture * appSettings.burnInQuality
|
||||
height: appSettings.lowResolutionFont
|
||||
? kterminal.height * Math.max(1, burnInScaling)
|
||||
: kterminal.height * scaleTexture * appSettings.burnInQuality
|
||||
|
||||
active: burnIn !== 0
|
||||
asynchronous: true
|
||||
|
||||
sourceComponent: ShaderEffect {
|
||||
property variant txt_source: kterminalSource
|
||||
property variant blurredSource: blurredSourceLoader.item
|
||||
property real blurCoefficient: motionBlurCoefficient
|
||||
|
||||
blending: false
|
||||
|
||||
fragmentShader:
|
||||
"#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif\n" +
|
||||
|
||||
"uniform lowp float qt_Opacity;" +
|
||||
"uniform lowp sampler2D txt_source;" +
|
||||
|
||||
"varying highp vec2 qt_TexCoord0;
|
||||
|
||||
uniform lowp sampler2D blurredSource;
|
||||
uniform highp float blurCoefficient;" +
|
||||
|
||||
"float rgb2grey(vec3 v){
|
||||
return dot(v, vec3(0.21, 0.72, 0.04));
|
||||
}" +
|
||||
|
||||
"void main() {" +
|
||||
"vec2 coords = qt_TexCoord0;" +
|
||||
"vec3 origColor = texture2D(txt_source, coords).rgb;" +
|
||||
"vec3 blur_color = texture2D(blurredSource, coords).rgb - vec3(blurCoefficient);" +
|
||||
"vec3 color = min(origColor + blur_color, max(origColor, blur_color));" +
|
||||
|
||||
"gl_FragColor = vec4(color, rgb2grey(color - origColor));" +
|
||||
"}"
|
||||
|
||||
onStatusChanged: if (log) console.log(log) //Print warning messages
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "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.Controls 1.1
|
||||
import QtQuick.Layouts 1.1
|
||||
|
||||
Tab{
|
||||
GroupBox{
|
||||
title: qsTr("Effects")
|
||||
anchors.fill: parent
|
||||
ColumnLayout{
|
||||
anchors.fill: parent
|
||||
spacing: 2
|
||||
CheckableSlider{
|
||||
name: qsTr("Bloom")
|
||||
onNewValue: appSettings.bloom = newValue
|
||||
value: appSettings.bloom
|
||||
}
|
||||
CheckableSlider{
|
||||
name: qsTr("BurnIn")
|
||||
onNewValue: appSettings.burnIn = newValue
|
||||
value: appSettings.burnIn
|
||||
}
|
||||
CheckableSlider{
|
||||
name: qsTr("Static Noise")
|
||||
onNewValue: appSettings.staticNoise = newValue
|
||||
value: appSettings.staticNoise
|
||||
}
|
||||
CheckableSlider{
|
||||
name: qsTr("Jitter")
|
||||
onNewValue: appSettings.jitter = newValue
|
||||
value: appSettings.jitter
|
||||
}
|
||||
CheckableSlider{
|
||||
name: qsTr("Glow Line")
|
||||
onNewValue: appSettings.glowingLine = newValue;
|
||||
value: appSettings.glowingLine
|
||||
}
|
||||
CheckableSlider{
|
||||
name: qsTr("Screen Curvature")
|
||||
onNewValue: appSettings.screenCurvature = newValue;
|
||||
value: appSettings.screenCurvature;
|
||||
}
|
||||
CheckableSlider{
|
||||
name: qsTr("Ambient Light")
|
||||
onNewValue: appSettings.ambientLight = newValue;
|
||||
value: appSettings.ambientLight
|
||||
enabled: appSettings.framesIndex !== 0
|
||||
}
|
||||
CheckableSlider{
|
||||
name: qsTr("Flickering")
|
||||
onNewValue: appSettings.flickering = newValue;
|
||||
value: appSettings.flickering;
|
||||
}
|
||||
CheckableSlider{
|
||||
name: qsTr("Horizontal Sync")
|
||||
onNewValue: appSettings.horizontalSync = newValue;
|
||||
value: appSettings.horizontalSync;
|
||||
}
|
||||
CheckableSlider{
|
||||
name: qsTr("RGB Shift")
|
||||
onNewValue: appSettings.rbgShift = newValue;
|
||||
value: appSettings.rbgShift;
|
||||
enabled: appSettings.chromaColor !== 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,235 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "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.Controls 1.1
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtQuick.Dialogs 1.1
|
||||
|
||||
Tab{
|
||||
ColumnLayout{
|
||||
anchors.fill: parent
|
||||
GroupBox{
|
||||
anchors {left: parent.left; right: parent.right}
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
title: qsTr("Profile")
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
TableView {
|
||||
id: profilesView
|
||||
Layout.fillWidth: true
|
||||
anchors { top: parent.top; bottom: parent.bottom; }
|
||||
model: appSettings.profilesList
|
||||
headerVisible: false
|
||||
TableViewColumn {
|
||||
title: qsTr("Profile")
|
||||
role: "text"
|
||||
width: parent.width * 0.5
|
||||
}
|
||||
onActivated: {
|
||||
appSettings.loadProfile(row);
|
||||
}
|
||||
}
|
||||
ColumnLayout {
|
||||
anchors { top: parent.top; bottom: parent.bottom }
|
||||
Layout.fillWidth: false
|
||||
Button{
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("New")
|
||||
onClicked: {
|
||||
insertname.profileName = "";
|
||||
insertname.show()
|
||||
}
|
||||
}
|
||||
Button{
|
||||
Layout.fillWidth: true
|
||||
property alias currentIndex: profilesView.currentRow
|
||||
enabled: currentIndex >= 0
|
||||
text: qsTr("Load")
|
||||
onClicked: {
|
||||
var index = profilesView.currentRow;
|
||||
if (index >= 0)
|
||||
appSettings.loadProfile(index);
|
||||
}
|
||||
}
|
||||
Button{
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Remove")
|
||||
property alias currentIndex: profilesView.currentRow
|
||||
|
||||
enabled: currentIndex >= 0 && !appSettings.profilesList.get(currentIndex).builtin
|
||||
onClicked: {
|
||||
appSettings.profilesList.remove(currentIndex);
|
||||
profilesView.selection.clear();
|
||||
|
||||
// TODO This is a very ugly workaround. The view didn't update on Qt 5.3.2.
|
||||
profilesView.model = 0;
|
||||
profilesView.model = appSettings.profilesList;
|
||||
}
|
||||
}
|
||||
Item {
|
||||
// Spacing
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
Button{
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Import")
|
||||
onClicked: {
|
||||
fileDialog.selectExisting = true;
|
||||
fileDialog.callBack = function (url) {loadFile(url);};
|
||||
fileDialog.open();
|
||||
}
|
||||
function loadFile(url) {
|
||||
try {
|
||||
if (appSettings.verbose)
|
||||
console.log("Loading file: " + url);
|
||||
|
||||
var profileObject = JSON.parse(fileIO.read(url));
|
||||
var name = profileObject.name;
|
||||
|
||||
if (!name)
|
||||
throw "Profile doesn't have a name";
|
||||
|
||||
delete profileObject.name;
|
||||
|
||||
appSettings.appendCustomProfile(name, JSON.stringify(profileObject));
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
messageDialog.text = qsTr("There has been an error reading the file.")
|
||||
messageDialog.open();
|
||||
}
|
||||
}
|
||||
}
|
||||
Button{
|
||||
property alias currentIndex: profilesView.currentRow
|
||||
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: qsTr("Export")
|
||||
enabled: currentIndex >= 0 && !appSettings.profilesList.get(currentIndex).builtin
|
||||
onClicked: {
|
||||
fileDialog.selectExisting = false;
|
||||
fileDialog.callBack = function (url) {storeFile(url);};
|
||||
fileDialog.open();
|
||||
}
|
||||
function storeFile(url) {
|
||||
try {
|
||||
var urlString = url.toString();
|
||||
|
||||
// Fix the extension if it's missing.
|
||||
var extension = urlString.substring(urlString.length - 5, urlString.length);
|
||||
var urlTail = (extension === ".json" ? "" : ".json");
|
||||
url += urlTail;
|
||||
|
||||
if (true)
|
||||
console.log("Storing file: " + url);
|
||||
|
||||
var profileObject = appSettings.profilesList.get(currentIndex);
|
||||
var profileSettings = JSON.parse(profileObject.obj_string);
|
||||
profileSettings["name"] = profileObject.text;
|
||||
|
||||
var result = fileIO.write(url, JSON.stringify(profileSettings, undefined, 2));
|
||||
if (!result)
|
||||
throw "The file could not be written.";
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
messageDialog.text = qsTr("There has been an error storing the file.")
|
||||
messageDialog.open();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GroupBox{
|
||||
anchors {left: parent.left; right: parent.right}
|
||||
title: qsTr("Command")
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
CheckBox{
|
||||
id: useCustomCommand
|
||||
text: qsTr("Use custom command instead of shell at startup")
|
||||
checked: appSettings.useCustomCommand
|
||||
onCheckedChanged: appSettings.useCustomCommand = checked
|
||||
}
|
||||
// Workaround for QTBUG-31627 for pre 5.3.0
|
||||
Binding{
|
||||
target: useCustomCommand
|
||||
property: "checked"
|
||||
value: appSettings.useCustomCommand
|
||||
}
|
||||
TextField{
|
||||
id: customCommand
|
||||
anchors {left: parent.left; right: parent.right}
|
||||
text: appSettings.customCommand
|
||||
enabled: useCustomCommand.checked
|
||||
onEditingFinished: appSettings.customCommand = text
|
||||
|
||||
// Save text even if user forgets to press enter or unfocus
|
||||
function saveSetting() {
|
||||
appSettings.customCommand = text;
|
||||
}
|
||||
Component.onCompleted: settings_window.closing.connect(saveSetting)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DIALOGS ////////////////////////////////////////////////////////////////
|
||||
InsertNameDialog{
|
||||
id: insertname
|
||||
onNameSelected: {
|
||||
appSettings.appendCustomProfile(name, appSettings.composeProfileString());
|
||||
}
|
||||
}
|
||||
MessageDialog {
|
||||
id: messageDialog
|
||||
title: qsTr("File Error")
|
||||
onAccepted: {
|
||||
messageDialog.close();
|
||||
}
|
||||
}
|
||||
Loader {
|
||||
property var callBack
|
||||
property bool selectExisting: false
|
||||
id: fileDialog
|
||||
|
||||
sourceComponent: FileDialog{
|
||||
nameFilters: ["Json files (*.json)"]
|
||||
selectMultiple: false
|
||||
selectFolder: false
|
||||
selectExisting: fileDialog.selectExisting
|
||||
onAccepted: callBack(fileUrl);
|
||||
}
|
||||
|
||||
onSelectExistingChanged: reload()
|
||||
|
||||
function open() {
|
||||
item.open();
|
||||
}
|
||||
|
||||
function reload() {
|
||||
active = false;
|
||||
active = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "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.Controls 1.1
|
||||
import QtQuick.Layouts 1.1
|
||||
|
||||
import "Components"
|
||||
|
||||
Tab{
|
||||
ColumnLayout{
|
||||
anchors.fill: parent
|
||||
GroupBox{
|
||||
title: qsTr("General")
|
||||
Layout.fillWidth: true
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
GridLayout{
|
||||
anchors.fill: parent
|
||||
rows: 2
|
||||
columns: 3
|
||||
Label{text: qsTr("Effects FPS")}
|
||||
Slider{
|
||||
Layout.fillWidth: true
|
||||
id: fpsSlider
|
||||
onValueChanged: {
|
||||
if (enabled) {
|
||||
appSettings.fps = value !== 60 ? value + 1 : 0;
|
||||
}
|
||||
}
|
||||
stepSize: 1
|
||||
enabled: false
|
||||
Component.onCompleted: {
|
||||
minimumValue = 0;
|
||||
maximumValue = 60;
|
||||
value = appSettings.fps !== 0 ? appSettings.fps - 1 : 60;
|
||||
enabled = true;
|
||||
}
|
||||
}
|
||||
SizedLabel{text: appSettings.fps !== 0 ? appSettings.fps : qsTr("Max")}
|
||||
Label{text: qsTr("Texture Quality")}
|
||||
Slider{
|
||||
Layout.fillWidth: true
|
||||
id: txtslider
|
||||
onValueChanged: if (enabled) appSettings.windowScaling = value;
|
||||
stepSize: 0.05
|
||||
enabled: false
|
||||
Component.onCompleted: {
|
||||
minimumValue = 0.25 //Without this value gets set to 0.5
|
||||
value = appSettings.windowScaling;
|
||||
enabled = true;
|
||||
}
|
||||
}
|
||||
SizedLabel{text: Math.round(txtslider.value * 100) + "%"}
|
||||
}
|
||||
}
|
||||
GroupBox{
|
||||
title: qsTr("Bloom")
|
||||
Layout.fillWidth: true
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
GridLayout{
|
||||
id: bloomQualityContainer
|
||||
anchors.fill: parent
|
||||
Label{text: qsTr("Bloom Quality")}
|
||||
Slider{
|
||||
Layout.fillWidth: true
|
||||
id: bloomSlider
|
||||
onValueChanged: if (enabled) appSettings.bloomQuality = value;
|
||||
stepSize: 0.05
|
||||
enabled: false
|
||||
Component.onCompleted: {
|
||||
minimumValue = 0.25
|
||||
value = appSettings.bloomQuality;
|
||||
enabled = true;
|
||||
}
|
||||
}
|
||||
SizedLabel{text: Math.round(bloomSlider.value * 100) + "%"}
|
||||
}
|
||||
}
|
||||
GroupBox{
|
||||
title: qsTr("BurnIn")
|
||||
Layout.fillWidth: true
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
GridLayout{
|
||||
id: blurQualityContainer
|
||||
anchors.fill: parent
|
||||
|
||||
Label{text: qsTr("BurnIn Quality")}
|
||||
Slider{
|
||||
Layout.fillWidth: true
|
||||
id: burnInSlider
|
||||
onValueChanged: if (enabled) appSettings.burnInQuality = value;
|
||||
stepSize: 0.05
|
||||
enabled: false
|
||||
Component.onCompleted: {
|
||||
minimumValue = 0.25
|
||||
value = appSettings.burnInQuality;
|
||||
enabled = true;
|
||||
}
|
||||
}
|
||||
SizedLabel{text: Math.round(burnInSlider.value * 100) + "%"}
|
||||
}
|
||||
}
|
||||
GroupBox{
|
||||
title: qsTr("Frame")
|
||||
Layout.fillWidth: true
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
CheckBox{
|
||||
checked: appSettings._frameReflections
|
||||
text: qsTr("Frame Reflections")
|
||||
onCheckedChanged: appSettings._frameReflections = checked
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "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.Controls 1.1
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtQuick.Dialogs 1.1
|
||||
|
||||
Tab{
|
||||
ColumnLayout{
|
||||
anchors.fill: parent
|
||||
GroupBox{
|
||||
title: qsTr("Rasterization Mode")
|
||||
Layout.fillWidth: true
|
||||
ComboBox {
|
||||
id: rasterizationBox
|
||||
property string selectedElement: model[currentIndex]
|
||||
anchors.fill: parent
|
||||
model: [qsTr("Default"), qsTr("Scanlines"), qsTr("Pixels")]
|
||||
currentIndex: appSettings.rasterization
|
||||
onCurrentIndexChanged: {
|
||||
appSettings.rasterization = currentIndex
|
||||
}
|
||||
}
|
||||
}
|
||||
GroupBox{
|
||||
title: qsTr("Lights")
|
||||
Layout.fillWidth: true
|
||||
GridLayout{
|
||||
anchors.fill: parent
|
||||
columns: 2
|
||||
Label{ text: qsTr("Brightness") }
|
||||
SimpleSlider{
|
||||
onValueChanged: appSettings.brightness = value
|
||||
value: appSettings.brightness
|
||||
}
|
||||
Label{ text: qsTr("Contrast") }
|
||||
SimpleSlider{
|
||||
onValueChanged: appSettings.contrast = value
|
||||
value: appSettings.contrast
|
||||
}
|
||||
Label{ text: qsTr("Opacity") }
|
||||
SimpleSlider{
|
||||
onValueChanged: appSettings.windowOpacity = value
|
||||
value: appSettings.windowOpacity
|
||||
}
|
||||
}
|
||||
}
|
||||
GroupBox{
|
||||
title: qsTr("Frame")
|
||||
Layout.fillWidth: true
|
||||
RowLayout{
|
||||
anchors.fill: parent
|
||||
ComboBox{
|
||||
id: framescombobox
|
||||
Layout.fillWidth: true
|
||||
model: appSettings.framesList
|
||||
currentIndex: appSettings.framesIndex
|
||||
onActivated: {
|
||||
appSettings.frameName = appSettings.framesList.get(index).name;
|
||||
}
|
||||
function updateIndex(){
|
||||
var name = appSettings.frameName;
|
||||
var index = appSettings.getFrameIndexByName(name);
|
||||
if (index !== undefined)
|
||||
currentIndex = index;
|
||||
}
|
||||
Component.onCompleted: updateIndex();
|
||||
Connections {
|
||||
target: appSettings
|
||||
onFrameNameChanged: framescombobox.updateIndex();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "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.Controls 1.1
|
||||
import QtQuick.Layouts 1.1
|
||||
|
||||
import "Components"
|
||||
|
||||
Tab{
|
||||
ColumnLayout{
|
||||
anchors.fill: parent
|
||||
GroupBox{
|
||||
property var rasterization: [qsTr("Default"), qsTr("Scanlines"), qsTr("Pixels")][appSettings.rasterization]
|
||||
title: qsTr("Font" + "(" + rasterization + ")")
|
||||
anchors { left: parent.left; right: parent.right }
|
||||
GridLayout{
|
||||
anchors.fill: parent
|
||||
columns: 2
|
||||
Label{ text: qsTr("Name") }
|
||||
ComboBox{
|
||||
id: fontChanger
|
||||
Layout.fillWidth: true
|
||||
model: appSettings.fontlist
|
||||
onActivated: {
|
||||
var name = appSettings.fontlist.get(index).name;
|
||||
appSettings.fontNames[appSettings.rasterization] = name;
|
||||
appSettings.handleFontChanged();
|
||||
}
|
||||
function updateIndex(){
|
||||
var name = appSettings.fontNames[appSettings.rasterization];
|
||||
var index = appSettings.getIndexByName(name);
|
||||
if (index !== undefined)
|
||||
currentIndex = index;
|
||||
}
|
||||
Connections{
|
||||
target: appSettings
|
||||
onTerminalFontChanged: fontChanger.updateIndex();
|
||||
}
|
||||
Component.onCompleted: updateIndex();
|
||||
}
|
||||
Label{ text: qsTr("Scaling") }
|
||||
RowLayout{
|
||||
Layout.fillWidth: true
|
||||
Slider{
|
||||
Layout.fillWidth: true
|
||||
id: fontScalingChanger
|
||||
onValueChanged: if(enabled) appSettings.fontScaling = value
|
||||
stepSize: 0.05
|
||||
enabled: false // Another trick to fix initial bad behavior.
|
||||
Component.onCompleted: {
|
||||
minimumValue = appSettings.minimumFontScaling;
|
||||
maximumValue = appSettings.maximumFontScaling;
|
||||
value = appSettings.fontScaling;
|
||||
enabled = true;
|
||||
}
|
||||
Connections{
|
||||
target: appSettings
|
||||
onFontScalingChanged: fontScalingChanger.value = appSettings.fontScaling;
|
||||
}
|
||||
}
|
||||
SizedLabel{
|
||||
text: Math.round(fontScalingChanger.value * 100) + "%"
|
||||
}
|
||||
}
|
||||
Label{ text: qsTr("Font Width") }
|
||||
RowLayout{
|
||||
Layout.fillWidth: true
|
||||
Slider{
|
||||
Layout.fillWidth: true
|
||||
id: widthChanger
|
||||
onValueChanged: appSettings.fontWidth = value;
|
||||
value: appSettings.fontWidth
|
||||
stepSize: 0.05
|
||||
Component.onCompleted: {
|
||||
// This is needed to avoid unnecessary chnaged events.
|
||||
minimumValue = 0.5;
|
||||
maximumValue = 1.5;
|
||||
}
|
||||
}
|
||||
SizedLabel{
|
||||
text: Math.round(widthChanger.value * 100) + "%"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
GroupBox{
|
||||
title: qsTr("Colors")
|
||||
anchors { left: parent.left; right: parent.right }
|
||||
ColumnLayout{
|
||||
anchors.fill: parent
|
||||
ColumnLayout{
|
||||
Layout.fillWidth: true
|
||||
CheckableSlider{
|
||||
name: qsTr("Chroma Color")
|
||||
onNewValue: appSettings.chromaColor = newValue
|
||||
value: appSettings.chromaColor
|
||||
}
|
||||
CheckableSlider{
|
||||
name: qsTr("Saturation Color")
|
||||
onNewValue: appSettings.saturationColor = newValue
|
||||
value: appSettings.saturationColor
|
||||
enabled: appSettings.chromaColor !== 0
|
||||
}
|
||||
}
|
||||
RowLayout{
|
||||
Layout.fillWidth: true
|
||||
ColorButton{
|
||||
name: qsTr("Font")
|
||||
height: 50
|
||||
Layout.fillWidth: true
|
||||
onColorSelected: appSettings._fontColor = color;
|
||||
color: appSettings._fontColor
|
||||
}
|
||||
ColorButton{
|
||||
name: qsTr("Background")
|
||||
height: 50
|
||||
Layout.fillWidth: true
|
||||
onColorSelected: appSettings._backgroundColor = color;
|
||||
color: appSettings._backgroundColor
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,337 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "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 QtGraphicalEffects 1.0
|
||||
|
||||
import "utils.js" as Utils
|
||||
|
||||
ShaderEffect {
|
||||
property ShaderEffectSource source
|
||||
property ShaderEffectSource blurredSource
|
||||
property ShaderEffectSource bloomSource
|
||||
|
||||
property color fontColor: appSettings.fontColor
|
||||
property color backgroundColor: appSettings.backgroundColor
|
||||
property real bloom: appSettings.bloom * 2.5
|
||||
|
||||
property real burnIn: appSettings.burnIn
|
||||
|
||||
property real jitter: appSettings.jitter * 0.007
|
||||
property real staticNoise: appSettings.staticNoise
|
||||
property size scaleNoiseSize: Qt.size((width) / (noiseTexture.width * appSettings.windowScaling * appSettings.fontScaling),
|
||||
(height) / (noiseTexture.height * appSettings.windowScaling * appSettings.fontScaling))
|
||||
|
||||
property real screenCurvature: appSettings.screenCurvature
|
||||
property real glowingLine: appSettings.glowingLine * 0.2
|
||||
|
||||
property real chromaColor: appSettings.chromaColor;
|
||||
|
||||
property real rbgShift: appSettings.rbgShift * 0.2
|
||||
|
||||
property real flickering: appSettings.flickering
|
||||
property real horizontalSync: appSettings.horizontalSync * 0.5
|
||||
|
||||
property bool frameReflections: appSettings.frameReflections
|
||||
|
||||
property real disp_top: (frame.displacementTop * appSettings.windowScaling) / height
|
||||
property real disp_bottom: (frame.displacementBottom * appSettings.windowScaling) / height
|
||||
property real disp_left: (frame.displacementLeft * appSettings.windowScaling) / width
|
||||
property real disp_right: (frame.displacementRight * appSettings.windowScaling) / width
|
||||
|
||||
property real screen_brightness: appSettings.brightness * 1.5 + 0.5
|
||||
|
||||
// This is the average value of the abs(sin) function. Needed to avoid aliasing.
|
||||
readonly property real absSinAvg: 0.63661828335466886
|
||||
property size rasterizationSmooth: Qt.size(
|
||||
Utils.clamp(2.0 * virtual_resolution.width / (width * devicePixelRatio), 0.0, 1.0),
|
||||
Utils.clamp(2.0 * virtual_resolution.height / (height * devicePixelRatio), 0.0, 1.0))
|
||||
|
||||
property real dispX
|
||||
property real dispY
|
||||
property size virtual_resolution
|
||||
|
||||
TimeManager{
|
||||
id: timeManager
|
||||
enableTimer: terminalWindow.visible
|
||||
}
|
||||
|
||||
property alias time: timeManager.time
|
||||
property ShaderEffectSource noiseSource: noiseShaderSource
|
||||
|
||||
// If something goes wrong activate the fallback version of the shader.
|
||||
property bool fallBack: false
|
||||
|
||||
blending: false
|
||||
|
||||
//Smooth random texture used for flickering effect.
|
||||
Image{
|
||||
id: noiseTexture
|
||||
source: "images/allNoise512.png"
|
||||
width: 512
|
||||
height: 512
|
||||
fillMode: Image.Tile
|
||||
visible: false
|
||||
}
|
||||
ShaderEffectSource{
|
||||
id: noiseShaderSource
|
||||
sourceItem: noiseTexture
|
||||
wrapMode: ShaderEffectSource.Repeat
|
||||
visible: false
|
||||
smooth: true
|
||||
}
|
||||
|
||||
//Print the number with a reasonable precision for the shader.
|
||||
function str(num){
|
||||
return num.toFixed(8);
|
||||
}
|
||||
|
||||
vertexShader: "
|
||||
uniform highp mat4 qt_Matrix;
|
||||
uniform highp float time;
|
||||
|
||||
uniform highp float disp_left;
|
||||
uniform highp float disp_right;
|
||||
uniform highp float disp_top;
|
||||
uniform highp float disp_bottom;
|
||||
|
||||
attribute highp vec4 qt_Vertex;
|
||||
attribute highp vec2 qt_MultiTexCoord0;
|
||||
|
||||
varying highp vec2 qt_TexCoord0;" +
|
||||
|
||||
(!fallBack ? "
|
||||
uniform sampler2D noiseSource;" : "") +
|
||||
|
||||
(!fallBack && flickering !== 0.0 ?"
|
||||
varying lowp float brightness;
|
||||
uniform lowp float flickering;" : "") +
|
||||
(!fallBack && horizontalSync !== 0.0 ?"
|
||||
uniform lowp float horizontalSync;
|
||||
varying lowp float distortionScale;
|
||||
varying lowp float distortionFreq;" : "") +
|
||||
|
||||
"
|
||||
void main() {
|
||||
qt_TexCoord0.x = (qt_MultiTexCoord0.x - disp_left) / (1.0 - disp_left - disp_right);
|
||||
qt_TexCoord0.y = (qt_MultiTexCoord0.y - disp_top) / (1.0 - disp_top - disp_bottom);
|
||||
vec2 coords = vec2(fract(time/(1024.0*2.0)), fract(time/(1024.0*1024.0)));" +
|
||||
|
||||
(!fallBack && (flickering !== 0.0 || horizontalSync !== 0.0) ?
|
||||
"vec4 initialNoiseTexel = texture2D(noiseSource, coords);"
|
||||
: "") +
|
||||
(!fallBack && flickering !== 0.0 ? "
|
||||
brightness = 1.0 + (initialNoiseTexel.g - 0.5) * flickering;"
|
||||
: "") +
|
||||
|
||||
(!fallBack && horizontalSync !== 0.0 ? "
|
||||
float randval = horizontalSync - initialNoiseTexel.r;
|
||||
distortionScale = step(0.0, randval) * randval * horizontalSync;
|
||||
distortionFreq = mix(4.0, 40.0, initialNoiseTexel.g);"
|
||||
: "") +
|
||||
|
||||
"gl_Position = qt_Matrix * qt_Vertex;
|
||||
}"
|
||||
|
||||
fragmentShader: "
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
uniform sampler2D source;
|
||||
uniform highp float qt_Opacity;
|
||||
uniform highp float time;
|
||||
varying highp vec2 qt_TexCoord0;
|
||||
|
||||
uniform highp vec4 fontColor;
|
||||
uniform highp vec4 backgroundColor;
|
||||
uniform lowp float screen_brightness;
|
||||
|
||||
uniform highp vec2 virtual_resolution;
|
||||
uniform highp vec2 rasterizationSmooth;
|
||||
uniform highp float dispX;
|
||||
uniform highp float dispY;" +
|
||||
|
||||
(bloom !== 0 ? "
|
||||
uniform highp sampler2D bloomSource;
|
||||
uniform lowp float bloom;" : "") +
|
||||
(burnIn !== 0 ? "
|
||||
uniform sampler2D blurredSource;" : "") +
|
||||
(staticNoise !== 0 ? "
|
||||
uniform highp float staticNoise;" : "") +
|
||||
(((staticNoise !== 0 || jitter !== 0 || rbgShift)
|
||||
||(fallBack && (flickering || horizontalSync))) ? "
|
||||
uniform lowp sampler2D noiseSource;
|
||||
uniform highp vec2 scaleNoiseSize;" : "") +
|
||||
(screenCurvature !== 0 ? "
|
||||
uniform highp float screenCurvature;" : "") +
|
||||
(glowingLine !== 0 ? "
|
||||
uniform highp float glowingLine;" : "") +
|
||||
(chromaColor !== 0 ? "
|
||||
uniform lowp float chromaColor;" : "") +
|
||||
(jitter !== 0 ? "
|
||||
uniform lowp float jitter;" : "") +
|
||||
(rbgShift !== 0 ? "
|
||||
uniform lowp float rbgShift;" : "") +
|
||||
|
||||
(fallBack && horizontalSync !== 0 ? "
|
||||
uniform lowp float horizontalSync;" : "") +
|
||||
(fallBack && flickering !== 0.0 ?"
|
||||
uniform lowp float flickering;" : "") +
|
||||
(!fallBack && flickering !== 0 ? "
|
||||
varying lowp float brightness;"
|
||||
: "") +
|
||||
(!fallBack && horizontalSync !== 0 ? "
|
||||
varying lowp float distortionScale;
|
||||
varying lowp float distortionFreq;" : "") +
|
||||
|
||||
(glowingLine !== 0 ? "
|
||||
float randomPass(vec2 coords){
|
||||
return fract(smoothstep(-120.0, 0.0, coords.y - (virtual_resolution.y + 120.0) * fract(time * 0.00015)));
|
||||
}" : "") +
|
||||
|
||||
"highp float getScanlineIntensity(vec2 coords) {
|
||||
highp float result = 1.0;" +
|
||||
|
||||
(appSettings.rasterization != appSettings.no_rasterization ?
|
||||
"float val = abs(sin(coords.y * virtual_resolution.y * "+Math.PI+"));
|
||||
result *= mix(val, " + absSinAvg + ", rasterizationSmooth.y);" : "") +
|
||||
(appSettings.rasterization == appSettings.pixel_rasterization ?
|
||||
"val = abs(sin(coords.x * virtual_resolution.x * "+Math.PI+"));
|
||||
result *= mix(val, " + absSinAvg + ", rasterizationSmooth.x);" : "") + "
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
float rgb2grey(vec3 v){
|
||||
return dot(v, vec3(0.21, 0.72, 0.04));
|
||||
}" +
|
||||
|
||||
"void main() {" +
|
||||
"vec2 cc = vec2(0.5) - qt_TexCoord0;" +
|
||||
"float distance = length(cc);" +
|
||||
|
||||
//FallBack if there are problems
|
||||
(fallBack && (flickering !== 0.0 || horizontalSync !== 0.0) ?
|
||||
"vec2 initialCoords = vec2(fract(time/(1024.0*2.0)), fract(time/(1024.0*1024.0)));
|
||||
vec4 initialNoiseTexel = texture2D(noiseSource, initialCoords);"
|
||||
: "") +
|
||||
(fallBack && flickering !== 0.0 ? "
|
||||
float brightness = 1.0 + (initialNoiseTexel.g - 0.5) * flickering;"
|
||||
: "") +
|
||||
(fallBack && horizontalSync !== 0.0 ? "
|
||||
float randval = horizontalSync - initialNoiseTexel.r;
|
||||
float distortionScale = step(0.0, randval) * randval * horizontalSync;
|
||||
float distortionFreq = mix(4.0, 40.0, initialNoiseTexel.g);"
|
||||
: "") +
|
||||
|
||||
(staticNoise ? "
|
||||
float noise = staticNoise;" : "") +
|
||||
|
||||
(screenCurvature !== 0 ? "
|
||||
float distortion = dot(cc, cc) * screenCurvature;
|
||||
vec2 staticCoords = (qt_TexCoord0 - cc * (1.0 + distortion) * distortion);"
|
||||
:"
|
||||
vec2 staticCoords = qt_TexCoord0;") +
|
||||
|
||||
"vec2 coords = staticCoords;" +
|
||||
|
||||
(horizontalSync !== 0 ? "
|
||||
float dst = sin((coords.y + time * 0.001) * distortionFreq);
|
||||
coords.x += dst * distortionScale;" +
|
||||
(staticNoise ? "
|
||||
noise += distortionScale * 7.0;" : "")
|
||||
: "") +
|
||||
|
||||
(jitter !== 0 || staticNoise !== 0 ?
|
||||
"vec4 noiseTexel = texture2D(noiseSource, scaleNoiseSize * coords + vec2(fract(time / 51.0), fract(time / 237.0)));"
|
||||
: "") +
|
||||
|
||||
(jitter !== 0 ? "
|
||||
vec2 offset = vec2(noiseTexel.b, noiseTexel.a) - vec2(0.5);
|
||||
vec2 txt_coords = coords + offset * jitter;"
|
||||
: "vec2 txt_coords = coords;") +
|
||||
|
||||
"float color = 0.0;" +
|
||||
|
||||
(staticNoise !== 0 ? "
|
||||
float noiseVal = noiseTexel.a;
|
||||
color += noiseVal * noise * (1.0 - distance * 1.3);" : "") +
|
||||
|
||||
(glowingLine !== 0 ? "
|
||||
color += randomPass(coords * virtual_resolution) * glowingLine;" : "") +
|
||||
|
||||
"vec3 txt_color = texture2D(source, txt_coords).rgb;" +
|
||||
|
||||
(burnIn !== 0 ? "
|
||||
vec4 txt_blur = texture2D(blurredSource, txt_coords);
|
||||
txt_color = txt_color + txt_blur.rgb * txt_blur.a;"
|
||||
: "") +
|
||||
|
||||
"float greyscale_color = rgb2grey(txt_color) + color;" +
|
||||
|
||||
(chromaColor !== 0 ?
|
||||
(rbgShift !== 0 ? "
|
||||
float rgb_noise = abs(texture2D(noiseSource, vec2(fract(time/(1024.0 * 256.0)), fract(time/(1024.0*1024.0)))).a - 0.5);
|
||||
float rcolor = texture2D(source, txt_coords + vec2(0.1, 0.0) * rbgShift * rgb_noise).r;
|
||||
float bcolor = texture2D(source, txt_coords - vec2(0.1, 0.0) * rbgShift * rgb_noise).b;
|
||||
txt_color.r = rcolor;
|
||||
txt_color.b = bcolor;
|
||||
greyscale_color = 0.33 * (rcolor + bcolor);" : "") +
|
||||
|
||||
"vec3 mixedColor = mix(fontColor.rgb, txt_color * fontColor.rgb, chromaColor);
|
||||
vec3 finalBackColor = mix(backgroundColor.rgb, mixedColor, greyscale_color);
|
||||
vec3 finalColor = mix(finalBackColor, fontColor.rgb, color).rgb;"
|
||||
:
|
||||
"vec3 finalColor = mix(backgroundColor.rgb, fontColor.rgb, greyscale_color);") +
|
||||
|
||||
"finalColor *= getScanlineIntensity(coords);" +
|
||||
|
||||
(bloom !== 0 ?
|
||||
"vec4 bloomFullColor = texture2D(bloomSource, coords);
|
||||
vec3 bloomColor = bloomFullColor.rgb;
|
||||
float bloomAlpha = bloomFullColor.a;" +
|
||||
(chromaColor !== 0 ?
|
||||
"bloomColor = fontColor.rgb * mix(vec3(rgb2grey(bloomColor)), bloomColor, chromaColor);"
|
||||
:
|
||||
"bloomColor = fontColor.rgb * rgb2grey(bloomColor);") +
|
||||
"finalColor += bloomColor * bloom * bloomAlpha;"
|
||||
: "") +
|
||||
|
||||
"finalColor *= smoothstep(-dispX, 0.0, staticCoords.x) - smoothstep(1.0, 1.0 + dispX, staticCoords.x);
|
||||
finalColor *= smoothstep(-dispY, 0.0, staticCoords.y) - smoothstep(1.0, 1.0 + dispY, staticCoords.y);" +
|
||||
|
||||
(flickering !== 0 ? "
|
||||
finalColor *= brightness;" : "") +
|
||||
|
||||
"gl_FragColor = vec4(finalColor * screen_brightness, qt_Opacity);" +
|
||||
"}"
|
||||
|
||||
onStatusChanged: {
|
||||
// Print warning messages
|
||||
if (log)
|
||||
console.log(log);
|
||||
|
||||
// Activate fallback mode
|
||||
if (status == ShaderEffect.Error) {
|
||||
fallBack = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
import QtQuick 2.2
|
||||
import QtGraphicalEffects 1.0
|
||||
|
||||
import "utils.js" as Utils
|
||||
|
||||
ShaderTerminal{
|
||||
property alias title: terminal.title
|
||||
property alias terminalSize: terminal.terminalSize
|
||||
|
||||
id: mainShader
|
||||
opacity: appSettings.windowOpacity * 0.3 + 0.7
|
||||
|
||||
blending: false
|
||||
|
||||
source: terminal.mainSource
|
||||
blurredSource: terminal.blurredSource
|
||||
dispX: (12 / width) * appSettings.windowScaling
|
||||
dispY: (12 / height) * appSettings.windowScaling
|
||||
virtual_resolution: terminal.virtualResolution
|
||||
|
||||
Loader{
|
||||
id: frame
|
||||
anchors.fill: parent
|
||||
|
||||
property real displacementLeft: item ? item.displacementLeft : 0
|
||||
property real displacementTop: item ? item.displacementTop : 0
|
||||
property real displacementRight: item ? item.displacementRight : 0
|
||||
property real displacementBottom: item ? item.displacementBottom : 0
|
||||
|
||||
asynchronous: true
|
||||
visible: status === Loader.Ready
|
||||
|
||||
z: 2.1
|
||||
source: appSettings.frameSource
|
||||
}
|
||||
|
||||
PreprocessedTerminal{
|
||||
id: terminal
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
// EFFECTS ////////////////////////////////////////////////////////////////
|
||||
|
||||
Loader{
|
||||
id: bloomEffectLoader
|
||||
active: appSettings.bloom
|
||||
asynchronous: true
|
||||
width: parent.width * appSettings.bloomQuality
|
||||
height: parent.height * appSettings.bloomQuality
|
||||
|
||||
sourceComponent: FastBlur{
|
||||
radius: Utils.lint(16, 48, appSettings.bloomQuality * appSettings.windowScaling);
|
||||
source: terminal.mainSource
|
||||
transparentBorder: true
|
||||
}
|
||||
}
|
||||
Loader{
|
||||
id: bloomSourceLoader
|
||||
active: appSettings.bloom !== 0
|
||||
asynchronous: true
|
||||
sourceComponent: ShaderEffectSource{
|
||||
id: _bloomEffectSource
|
||||
sourceItem: bloomEffectLoader.item
|
||||
hideSource: true
|
||||
smooth: true
|
||||
visible: false
|
||||
}
|
||||
}
|
||||
|
||||
bloomSource: bloomSourceLoader.item
|
||||
|
||||
// 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
|
||||
// }
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
Copyright (c) 2011-2017, Ricardo Banffy.
|
||||
Copyright (c) 1993-2011, Paul Mattes.
|
||||
Copyright (c) 2004-2005, Don Russell.
|
||||
Copyright (c) 2004, Dick Altenbern.
|
||||
Copyright (c) 1990, Jeff Sparkes.
|
||||
Copyright (c) 1989, Georgia Tech Research Corporation (GTRC), Atlanta, GA 30332.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of Ricardo Banffy, Paul Mattes, Don Russell,
|
||||
Dick Altenbern, Jeff Sparkes, GTRC nor the names of their contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL RICARDO BANFFY, PAUL MATTES, DON RUSSELL, DICK ALTENBERN, JEFF
|
||||
SPARKES OR GTRC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
The Debian Logo glyph is based on the Debian Open Use Logo and is
|
||||
Copyright (c) 1999 Software in the Public Interest, Inc., and it is
|
||||
incorporated here under the terms of the Creative Commons
|
||||
Attribution-ShareAlike 3.0 Unported License. The logo is released
|
||||
under the terms of the GNU Lesser General Public License, version 3 or
|
||||
any later version, or, at your option, of the Creative Commons
|
||||
Attribution-ShareAlike 3.0 Unported License.
|
||||
|
||||
Ubuntu, the Ubuntu logo and the Circle of Friends symbol are
|
||||
registered trademarks of Canonical Ltd.
|
||||
|
||||
The Fontforge SFD font description file is optionally licensed under
|
||||
the SIL Open Font License v1.1 with no Reserved Font Name. This
|
||||
license is available with a FAQ at http://scripts.sil.org/OFL.
|
||||
@@ -1,101 +0,0 @@
|
||||
3270font: A font for the nostalgic
|
||||
==================================
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
A little bit of history
|
||||
-----------------------
|
||||
|
||||
This font is derived from the x3270 font, which, in turn, was
|
||||
translated from the one in Georgia Tech's 3270tool, which was itself
|
||||
hand-copied from a 3270 series terminal. I built it because I felt
|
||||
terminals deserve to be pretty. The .sfd font file contains a x3270
|
||||
bitmap font that was used for guidance.
|
||||
|
||||

|
||||
|
||||
Getting it
|
||||
----------
|
||||
|
||||
If you are running Debian or Ubuntu and you don't want to mess with
|
||||
building your font files, you can simply `apt-get install fonts-3270`
|
||||
(It's available from the Debian
|
||||
(https://packages.debian.org/sid/fonts/fonts-3270) and Ubuntu
|
||||
(http://packages.ubuntu.com/zesty/fonts-3270) package repos at
|
||||
https://packages.debian.org/sid/fonts/fonts-3270 and
|
||||
http://packages.ubuntu.com/xenial/fonts/fonts-3270, although the
|
||||
packaged version may not be the latest version, but it's good enough for
|
||||
most purposes. For those who don't have the luxury of a proper
|
||||
system-managed package, Adobe Type 1, TTF, OTF and WOFF versions are
|
||||
available for download on
|
||||
http://s3.amazonaws.com/3270font/3270_fonts_d250fd9.zip (although this
|
||||
URL may not always reflect the latest version).
|
||||
|
||||

|
||||
|
||||
The format
|
||||
----------
|
||||
|
||||
The "source" file is edited using FontForge. You'll need it if you want
|
||||
to generate fonts for your platform. On most civilized operating
|
||||
systems, you can simply `apt-get install fontforge`, `yum install
|
||||
fontforge` or even `port install fontforge`. On others, you may need to
|
||||
grab your copy from http://fontforge.org/. I encourage you to drop by
|
||||
and read the tutorials.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
If you are running Windows, you'll probably need something like
|
||||
Cygwin, but, in the end, the font works correctly (with some very
|
||||
minor hinting issues).
|
||||
|
||||

|
||||
|
||||
Generating usable font files
|
||||
----------------------------
|
||||
|
||||
The easiest way to generate the font files your computer can use is to
|
||||
run `make all` (if you are running Ubuntu or Debian, `make install` will
|
||||
install them too). Using `make help` will offer a handy list of options.
|
||||
|
||||
The script `generate_derived.pe` calls FontForge and generates
|
||||
PostScript, OTF, TTF and WOFF versions of the base font, as well as a
|
||||
slightly more condensed .sfd file with the base font narrowed to 488
|
||||
units, with no glyph rescaling (or cropping - we need to fix that) and
|
||||
its corresponding PostScript, TTF, OTF and WOFF versions.
|
||||
|
||||

|
||||
|
||||
Contributing
|
||||
------------
|
||||
|
||||
I fear GitHub's pull-request mechanism may not be very
|
||||
FontForge-friendly. If you want to contribute (there are a lot of
|
||||
missing glyphs, such as the APL set and most non-latin alphabets which
|
||||
most likely were never built into 3270 terminals), the best workflow
|
||||
would be to make add the encoding slots (if needed), add/make the
|
||||
changes, reencode it in "Unicode, Full", compact it and validate
|
||||
it. Check if the `git diff` command gives out something sensible (does
|
||||
not change things you didn't intend to) and make a pull request. If, in
|
||||
doubt, get in touch and we will figure out how to do it right.
|
||||
|
||||
Known problems
|
||||
--------------
|
||||
|
||||
Not all symbols in the 3270 charset have Unicode counterparts. When
|
||||
possible, they are duplicated in the Unicode space. The 3270-only
|
||||
symbols are at the end of the font, along with some glyphs useful for
|
||||
building others.
|
||||
|
||||
Please refer to http://x3270.bgp.nu/Charset.html for a complete map.
|
||||
@@ -1,94 +0,0 @@
|
||||
Copyright (c) 2013, Pablo Caro <me AT pcaro DOT es> - http://pcaro.es/
|
||||
with Reserved Font Name Hermit.
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
@@ -1,13 +0,0 @@
|
||||
monaco.ttf
|
||||
==========
|
||||
|
||||
The original monaco.ttf improved: add some special characters (which are from "DejaVu Sans Mono")
|
||||
|
||||
In my work environment, I need connect to Linux system from Windows system remotely using SecureCRT or Putty, and edit files using VIM tools. So I need one beautiful font in SecureCRT / Putty.
|
||||
|
||||
In windows system, there are some original fonts are beautiful, for example "Consolas", but they can't support some special characters, for example: ▸, ↪, ⌴. Because they are original fonts in my Windows, I don't want to modify them.
|
||||
|
||||
I get "Monaco" from web. It is tiny and beautiful. But it also can't support those special characters.
|
||||
|
||||
So I add the characters by myself and share it.
|
||||
|
||||