1
0
mirror of https://github.com/rricharz/Tek4010.git synced 2026-01-11 23:53:16 +00:00

larger windows with -full option

This commit is contained in:
¨Rene Richarz 2019-04-03 13:50:41 +02:00
parent 229ad1df4d
commit ab1fcd10d1
6 changed files with 131 additions and 49 deletions

View File

@ -40,13 +40,13 @@ virtual Ubuntu you can proceed.
Install the tek4010 emulator from this repo on a Raspberry Pi or Ubuntu. I propose using
sudo apt-get install git
git clone git://github.com/rricharz/Tek4010
sudo apt-get install git
git clone git://github.com/rricharz/Tek4010
cd Tek4010
This allows you to get updates later easily as follows:
cd Tek4010
cd Tek4010
git pull
The built tek4010 file is for a Raspberry Pi. If you are on Ubuntu, do the follwing to recompile
@ -219,7 +219,13 @@ tek4010 has the following options:
Emulate a baud rate. Without one of these arguments, the baud rate
is 19200 baud. The original Tektronix 4010 had a maximal baud rate
of 9600 baud. With the small baud rates you can emulate 1970s
style modem performance. Early modems had a baud rate of 300.
style modem performance. Early modems had a baud rate of 300.
-full in thos mode the tek4010 emulator creates the largest possible window
with 4x3 aspect ratio, and uses the full resolution of the 4014 with
enhanced graphics module installed, scaled down to the actual window
size. This mode is not recommended on the Raspberry Pi because of the
heavy workload on the GPU.
**Reporting problems**
@ -250,6 +256,11 @@ module. It would be easy to add the capability to support the 4K resolution of t
enhanced graphics module, but the current Raspberry Pi hardware cannot handle such a high
resolution.
If called with the -full option, the tek4010 emulator creates the largest possible window
with 4x3 aspect ratio, and uses the full resolution of the 4014 with enhanced graphics
module installed, scaled down to the actual window size. This mode is not recommended on
the Raspberry Pi because of the heavy workload on the GPU.
**Compiling the tek4010 project**
If you want to compile the project, you need to install "libgtk-3-dev":

51
main.c
View File

@ -33,6 +33,8 @@
*
*
*/
#define GDK_DISABLE_DEPRECATION_WARNINGS
#include <stdio.h>
#include <stdlib.h>
@ -46,6 +48,10 @@
extern FILE *putKeys;
static int global_firstcall;
extern int argFull;
int windowWidth;
int windowHeight;
int globalClearPersistent;
@ -81,21 +87,18 @@ static void on_quit_event()
static void do_drawing(cairo_t *cr, GtkWidget *widget)
{
int width = WINDOW_WIDTH; // we do not use actual window size here
int height = WINDOW_HEIGHT; // because surfaces does not change size
static cairo_surface_t *permanent_surface, *temporary_surface;
if (global_firstcall) {
permanent_surface = cairo_surface_create_similar(cairo_get_target(cr),
CAIRO_CONTENT_COLOR_ALPHA, width, height);
CAIRO_CONTENT_COLOR_ALPHA, windowWidth, windowHeight);
temporary_surface = cairo_surface_create_similar(cairo_get_target(cr),
CAIRO_CONTENT_COLOR_ALPHA, width, height);
CAIRO_CONTENT_COLOR_ALPHA, windowWidth, windowHeight);
}
cairo_t *permanent_cr = cairo_create(permanent_surface);
cairo_t *temporary_cr = cairo_create(temporary_surface);
tek4010_draw(permanent_cr, temporary_cr, width, height, global_firstcall);
tek4010_draw(permanent_cr, temporary_cr, global_firstcall);
global_firstcall = FALSE;
cairo_set_source_surface(cr, permanent_surface, 0, 0);
@ -151,6 +154,16 @@ int main (int argc, char *argv[])
{
GtkWidget *darea;
GtkWidget *window;
int askWindowWidth = A_WINDOW_WIDTH;
int askWindowHeight = A_WINDOW_HEIGHT;
tek4010_init(argc, argv);
if (argFull) {
askWindowWidth = 4096;
askWindowHeight = 3072;
}
gtk_init(&argc, &argv);
@ -168,6 +181,29 @@ int main (int argc, char *argv[])
g_signal_connect(G_OBJECT(window), "button-press-event", G_CALLBACK(clicked), NULL);
g_signal_connect(G_OBJECT(window), "key_press_event", G_CALLBACK(on_key_press), NULL);
GdkScreen *screen = gtk_window_get_screen(GTK_WINDOW(window));
int screenWidth = gdk_screen_get_width(screen);
int screenHeight = gdk_screen_get_height(screen);
printf("Screen dimensions: %d x %d\n", screenWidth, screenHeight);
if (argFull && (screenWidth<askWindowWidth+8) && (screenHeight<(askWindowHeight+72))) {
askWindowWidth = screenWidth - 8;
askWindowHeight = screenHeight - 72;
if (askWindowWidth > 4*askWindowHeight/3)
askWindowWidth = 4*askWindowHeight/3;
if (askWindowHeight > 3*askWindowWidth/4)
askWindowHeight = 3*askWindowWidth/4;
}
// DISPLAY DECORATED WINDOW
gtk_window_set_decorated(GTK_WINDOW(window), TRUE);
gtk_window_set_default_size(GTK_WINDOW(window),
askWindowWidth, askWindowHeight);
windowWidth = askWindowWidth;
windowHeight = askWindowHeight;
printf("Window dimensions: %d x %d\n", windowWidth, windowHeight);
if (TIME_INTERVAL > 0) {
// Add timer event
@ -176,14 +212,11 @@ int main (int argc, char *argv[])
g_timeout_add(TIME_INTERVAL, (GSourceFunc) on_timer_event, (gpointer) window);
}
gtk_window_set_default_size(GTK_WINDOW(window), WINDOW_WIDTH, WINDOW_HEIGHT);
gtk_window_set_title(GTK_WINDOW(window), WINDOW_NAME);
if (strlen(ICON_NAME) > 0) {
gtk_window_set_icon_from_file(GTK_WINDOW(window), ICON_NAME, NULL);
}
tek4010_init(argc, argv);
gtk_widget_show_all(window);

2
main.h
View File

@ -2,7 +2,7 @@
#include <cairo.h>
void tek4010_init(int argc, char* argv[]);
void tek4010_draw(cairo_t *cr, cairo_t *cr2, int width, int height, int first);
void tek4010_draw(cairo_t *cr, cairo_t *cr2, int first);
int tek4010_on_timer_event();
int tek4010_clicked(int button, int x, int y);
void tek4010_quit();

BIN
tek4010

Binary file not shown.

104
tek4010.c
View File

@ -48,11 +48,14 @@
extern void gtk_main_quit();
extern int globalClearPersistent;
extern int windowWidth;
extern int windowHeight;
int argNoexit = 0;
int argRaw = 0;
int argBaud = 19200;
int argTab1 = 0;
int argFull = 0;
int showCursor;
int isBrightSpot = 0;
@ -70,6 +73,7 @@ int count = 0;
static int x0,y0,x2,y2,xh,xl,yh,yl,xy4014;
static int plotPointMode = 0;
static int debugCount = 0;
static double efactor = 0.0;
static long refreshCount = 0;
static long charCount = 0;
@ -189,7 +193,7 @@ void tek4010_init(int argc, char* argv[])
exit(1);
}
// this stays here for compatability with early versions of tek4010
// this stays here for compatibility with early versions of tek4010
if (strcmp(argv[argc-1],"-noexit") == 0) {
argNoexit = 1;
argc--;
@ -214,6 +218,8 @@ void tek4010_init(int argc, char* argv[])
argBaud = 300;
else if (strcmp(argv[firstArg],"-tab1") == 0)
argTab1 = 1;
else if (strcmp(argv[firstArg],"-full") == 0)
argFull = 1;
else {
printf("tek4010: unknown argument %s\n", argv[firstArg]);
exit(1);
@ -257,8 +263,6 @@ void tek4010_init(int argc, char* argv[])
if (DEBUG) printf("character_interval = %0.1f msec\n",(double)characterInterval/10.0);
hDotsPerChar = WINDOW_WIDTH / 74;
vDotsPerChar = WINDOW_HEIGHT / 35;
globalClearPersistent = 1;
// create pipes for communication between parent and child
@ -407,7 +411,7 @@ void doCursor(cairo_t *cr2)
{
cairo_set_source_rgb(cr2, 0, 0.8, 0);
cairo_set_line_width (cr2, 1);
cairo_rectangle(cr2, x0, WINDOW_HEIGHT - y0 - vDotsPerChar + 8,
cairo_rectangle(cr2, x0, windowHeight - y0 - vDotsPerChar + 8,
hDotsPerChar - 3, vDotsPerChar - 3);
cairo_fill(cr2);
cairo_stroke (cr2);
@ -421,7 +425,7 @@ void clearPersistent(cairo_t *cr, cairo_t *cr2)
cairo_paint(cr);
globalClearPersistent = 0;
x0 = 0;
y0 = WINDOW_HEIGHT - vDotsPerChar;
y0 = windowHeight - vDotsPerChar;
leftmargin = 0;
cairo_set_source_rgb(cr, 0, 0.7, 0);
cairo_set_source_rgb(cr2, 0.8, 1, 0.8);
@ -440,20 +444,31 @@ void clearSecond(cairo_t *cr2)
}
void tek4010_draw(cairo_t *cr, cairo_t *cr2, int width, int height, int first)
void tek4010_draw(cairo_t *cr, cairo_t *cr2, int first)
// draw onto the main window using cairo
// width is the actual width of the main window
// height is the actual height of the main window
// cr is used for persistent drawing, cr2 for temporary drawing
{
{
int ch;
int todo;
char s[2];
refreshCount++;
long startPaintTime = mSeconds(); // start to meausure time for this draw operation
if (first) {
hDotsPerChar = windowWidth / 74;
vDotsPerChar = windowHeight / 35;
first = 0;
if (windowWidth == 1024) efactor = 0.0;
else efactor = windowWidth / 1024.0;
}
long startPaintTime = mSeconds(); // start to measure time for this draw operation
showCursor = 1;
isBrightSpot = 0;
@ -470,10 +485,17 @@ void tek4010_draw(cairo_t *cr, cairo_t *cr2, int width, int height, int first)
cairo_set_source_rgb(cr, 0, 0.7, 0);
cairo_select_font_face(cr, "Monospace", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_font_size(cr, 18);
cairo_select_font_face(cr2, "Monospace", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
cairo_set_font_size(cr2, 18);
if (efactor > 0.0) {
cairo_set_font_size(cr, (int)(efactor * 18));
cairo_set_font_size(cr2, (int)(efactor *18));
}
else {
cairo_set_font_size(cr, 18);
cairo_set_font_size(cr2, 18);
}
if (plotPointMode) todo = 5 * TODO; // more dots before refresh in plot point mode
else todo = TODO;
@ -486,8 +508,8 @@ void tek4010_draw(cairo_t *cr, cairo_t *cr2, int width, int height, int first)
cairo_set_line_width (cr2, vectorTable.linewidth);
cairo_set_source_rgb(cr2, vectorTable.intensity/2.0,
vectorTable.intensity, vectorTable.intensity/2.0);
cairo_move_to(cr2, vectorTable.x0, WINDOW_HEIGHT - vectorTable.y0);
cairo_line_to(cr2, vectorTable.x2, WINDOW_HEIGHT - vectorTable.y2);
cairo_move_to(cr2, vectorTable.x0, windowHeight - vectorTable.y0);
cairo_line_to(cr2, vectorTable.x2, windowHeight - vectorTable.y2);
cairo_stroke(cr2);
vectorTable.intensity = 0.0;
isBrightSpot = 1;
@ -540,9 +562,7 @@ void tek4010_draw(cairo_t *cr, cairo_t *cr2, int width, int height, int first)
}
if (tag != 0) {
////////////////////////
if ((mode == 1) && (tag != 1)) mode = 2;
if ((mode == 3) && (tag == 3)) {
@ -557,8 +577,6 @@ void tek4010_draw(cairo_t *cr, cairo_t *cr2, int width, int height, int first)
if ((mode == 2) && (tag != 3)) mode = 3;
if ((mode == 3) && (tag != 1)) mode = 4;
/////////////////////////
if ((mode == 5) && (tag != 1)) mode = 6;
if ((mode == 7) && (tag == 3)) {
@ -582,13 +600,25 @@ void tek4010_draw(cairo_t *cr, cairo_t *cr2, int width, int height, int first)
yh = 32 * (ch & 31); mode++;
if (DEBUG) printf("setting yh to %d\n", yh);
break;
case 2: yl = (ch & 31); y0 = yh + yl; mode++;
case 2: yl = (ch & 31);
if (efactor > 0.0) {
int yb = (xy4014 >> 2) & 3;
y0 = (int)(efactor * (double)(((yh+yl) << 2) + yb) / 4.0);
}
else y0 = yh + yl;
mode++;
if (DEBUG) printf("setting yl to %d\n", yl);
break;
case 3: if (tag == 1) xh = 32 * (ch & 31); mode++;
if (DEBUG) printf("setting xh to %d\n", xh);
break;
case 4: xl = (ch & 31); x0= xh + xl; mode++;
case 4: xl = (ch & 31);
if (efactor > 0.0) {
int xb = xy4014 & 3;
x0 = (int)(efactor * (double)(((xh+xl) << 2) + xb) / 4.0);
}
else x0 = xh + xl;
mode++;
if (DEBUG) printf("setting xl to %d\n", xl);
if (DEBUG) printf("******************************************** Moving to (%d,%d)\n",x0,y0);
break;
@ -609,22 +639,30 @@ void tek4010_draw(cairo_t *cr, cairo_t *cr2, int width, int height, int first)
break;
if (DEBUG) printf(">>>>>xh=%d\n",xh);
case 8: xl = (ch & 31);
x2 = xh + xl;
y2 = yh + yl;
if (efactor > 0.0) {
int xb = xy4014 & 3;
x2 = (int)(efactor * (double)(((xh+xl) << 2) + xb) / 4.0);
int yb = (xy4014 >> 2) & 3;
y2 = (int)(efactor * (double)(((yh+yl) << 2) + yb) / 4.0);
}
else {
x2 = xh + xl;
y2 = yh + yl;
}
if (DEBUG) printf(">>>>>xl=%d\n",xl);
if (plotPointMode>0.0) {
if (DEBUG) printf("********************************************** plotting point at %d,%d,todo =%d\n",
x2,y2,todo);
cairo_set_source_rgb(cr, 0, 1, 0);
cairo_move_to(cr, x2, WINDOW_HEIGHT - y2);
cairo_line_to(cr, x2+1, WINDOW_HEIGHT - y2);
cairo_move_to(cr, x2, windowHeight - y2);
cairo_line_to(cr, x2+1, windowHeight - y2);
cairo_stroke (cr);
cairo_set_source_rgb(cr, 0, 0.7, 0);
cairo_set_line_width (cr2, 3);
cairo_set_source_rgb(cr2, 0.5, 1, 0.5);
cairo_move_to(cr2, x2, WINDOW_HEIGHT - y2);
cairo_line_to(cr2, x2+1, WINDOW_HEIGHT - y2+1);
cairo_move_to(cr2, x2, windowHeight - y2);
cairo_line_to(cr2, x2+1, windowHeight - y2+1);
cairo_stroke (cr2);
isBrightSpot = 1;
mode = 50;
@ -634,14 +672,14 @@ void tek4010_draw(cairo_t *cr, cairo_t *cr2, int width, int height, int first)
else {
if (DEBUG) printf("tag=%d,**************************************** Drawing vector to (%d,%d)\n",tag,x2,y2);
cairo_move_to(cr, x0, WINDOW_HEIGHT - y0);
cairo_line_to(cr, x2, WINDOW_HEIGHT - y2);
cairo_move_to(cr, x0, windowHeight - y0);
cairo_line_to(cr, x2, windowHeight - y2);
cairo_stroke (cr);
cairo_set_line_width (cr2, 3);
cairo_set_source_rgb(cr2, 0.5, 1, 0.5);
cairo_move_to(cr2, x0, WINDOW_HEIGHT - y0);
cairo_line_to(cr2, x2, WINDOW_HEIGHT - y2);
cairo_move_to(cr2, x0, windowHeight - y0);
cairo_line_to(cr2, x2, windowHeight - y2);
cairo_stroke (cr2);
isBrightSpot = 1;
@ -728,9 +766,9 @@ void tek4010_draw(cairo_t *cr, cairo_t *cr2, int width, int height, int first)
case 10: // new line
y0 -= vDotsPerChar;
if (y0 < 4) {
y0 = WINDOW_HEIGHT - vDotsPerChar;
y0 = windowHeight - vDotsPerChar;
if (leftmargin) leftmargin = 0;
else leftmargin = WINDOW_WIDTH / 2;
else leftmargin = windowHeight / 2;
}
if (!argRaw) x0 = leftmargin;
break;
@ -762,10 +800,10 @@ void tek4010_draw(cairo_t *cr, cairo_t *cr2, int width, int height, int first)
if (y0 < 8) y0 = 8;
s[0] = ch;
s[1] = 0;
cairo_move_to(cr, x0, WINDOW_HEIGHT - y0 + 4);
cairo_move_to(cr, x0, windowHeight - y0 + 4);
cairo_show_text(cr, s);
cairo_set_source_rgb(cr2, 0.5, 1, 0.5);
cairo_move_to(cr2, x0, WINDOW_HEIGHT - y0 + 4);
cairo_move_to(cr2, x0, windowHeight - y0 + 4);
cairo_show_text(cr2, s);
x0 += hDotsPerChar;
isBrightSpot = 1;

View File

@ -1,6 +1,6 @@
#define WINDOW_WIDTH 1024 // proposed width of main window
#define WINDOW_HEIGHT 780 // proposed height of main window (as per Tektronix manual)
#define A_WINDOW_WIDTH 1024 // proposed width of main window
#define A_WINDOW_HEIGHT 780 // proposed height of main window
#define WINDOW_NAME "Tektronix 4010" // name of main window
#define ICON_NAME "" // path to icon for window