Skip to content

Instantly share code, notes, and snippets.

@tschak909
Created June 23, 2021 03:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tschak909/36f59e03a8a3e871ac8d89d1d6c15347 to your computer and use it in GitHub Desktop.
Save tschak909/36f59e03a8a3e871ac8d89d1d6c15347 to your computer and use it in GitHub Desktop.
platoterm example doing tek4014 codes.
/**
* PLATOTerm64 - A PLATO Terminal for the Commodore 64
* Based on Steve Peltz's PAD
*
* Author: Thomas Cherryhomes <thom.cherryhomes at gmail dot com>
*
* screen.c - Display output functions
*/
#include <stdlib.h>
#include "screen.h"
#include "protocol.h"
#include "font.h"
unsigned char CharHigh=16;
unsigned char CharWide=8;
padPt TTYLoc;
/* SDL_Window *window;
SDL_Renderer *renderer;
SDL_Texture *texture;
extern SDL_Surface *surface; */
unsigned char fontm23[2048];
padRGB backgroundColor={0,0,0};
padRGB foregroundColor={255,255,255};
short max(short a, short b) { return ( a > b ) ? a : b; }
short min(short a, short b) { return ( a < b ) ? a : b; }
#define true 1
#define false 0
extern padBool FastText;
/**
* emit coordinates in Tek4014 format
*/
void tek_coord(int x, int y) /* package coordinates Tek style */
{
putchar((y / 32) + 32); /* high y */
putchar((y % 32) + 96); /* low y */
putchar((x / 32) + 32); /* high x */
putchar((x % 32) + 64); /* low x */
}
/**
* screen_init() - Set up the screen
*/
void screen_init(void)
{
screen_clear();
}
/**
* screen_main() - render/preserve screen
*/
void screen_main(void)
{
/* Not used for Tek */
}
/**
* screen_wait(void) - Sleep for approx 16.67ms
*/
void screen_wait(void)
{
}
/**
* screen_beep(void) - Beep the terminal
*/
void screen_beep(void)
{
putchar(0x07); /* BEL */
}
/**
* screen_clear - Clear the screen
*/
void screen_clear(void)
{
putchar(0x1B); /* ESC */
putchar(0x0C); /* FF */
}
/**
* screen_set_pen_mode(void) - Set pen mode
*/
void screen_set_pen_mode(void)
{
}
/**
* screen_block_draw(Coord1, Coord2) - Perform a block fill from Coord1 to Coord2
*/
void screen_block_draw(padPt* Coord1, padPt* Coord2)
{
/* SDL_Rect rect; */
/* short x1; */
/* short y1; */
/* short x2; */
/* short y2; */
/* x1=min(Coord1->x,Coord2->x); */
/* x2=max(Coord1->x,Coord2->x); */
/* y1=min((Coord1->y^0x1FF)&0x1FF,(Coord2->y^0x1FF)&0x1FF); */
/* y2=max((Coord1->y^0x1FF)&0x1FF,(Coord2->y^0x1FF)&0x1FF); */
/* if ((CurMode==ModeErase)||(CurMode==ModeInverse)) */
/* canvas_block_fill(x1,y1,x2,y2,SDL_MapRGB(surface->format,backgroundColor.red,backgroundColor.green,backgroundColor.blue)); */
/* else */
/* canvas_block_fill(x1,y1,x2,y2,SDL_MapRGB(surface->format,foregroundColor.red,foregroundColor.green,foregroundColor.blue)); */
}
/**
* screen_dot_draw(Coord) - Plot a mode 0 pixel
*/
void screen_dot_draw(padPt* Coord)
{
int x=Coord->x;
int y=Coord->y^0x1FF;
putchar(0x1C); /* FS */
tek_coord(x,y);
tek_coord(x,y);
putchar(0x1F); /* US */
}
/**
* screen_line_draw(Coord1, Coord2) - Draw a mode 1 line
*/
void screen_line_draw(padPt* Coord1, padPt* Coord2)
{
int x1 = Coord1->x;
int x2 = Coord2->x;
int y1 = Coord1->y^0x1FF;
int y2 = Coord2->y^0x1FF;
putchar(0x1d); /* GS */
tek_coord(x1,y1);
tek_coord(x2,y2);
putchar(0x1F); /* US */
}
/**
* screen_char_draw(Coord, ch, count) - Output buffer from ch* of length count as PLATO characters
*/
void screen_char_draw(padPt* Coord, unsigned char* ch, unsigned char count)
{
short offset; /* due to negative offsets */
unsigned short x; /* Current X and Y coordinates */
unsigned short y;
unsigned short* px; /* Pointers to X and Y coordinates used for actual plotting */
unsigned short* py;
unsigned char i; /* current character counter */
unsigned char a; /* current character byte */
unsigned char j,k; /* loop counters */
char b; /* current character row bit signed */
char width=8;
char height=16;
short deltaX=1;
short deltaY=1;
unsigned char *p;
unsigned char* curfont;
padRGB mainColor;
padRGB altColor;
if (CurMode==ModeRewrite)
{
altColor.red=backgroundColor.red;
altColor.green=backgroundColor.green;
altColor.blue=backgroundColor.blue;
}
else if (CurMode==ModeInverse)
{
altColor.red=foregroundColor.red;
altColor.green=foregroundColor.green;
altColor.blue=foregroundColor.blue;
}
if (CurMode==ModeErase || CurMode==ModeInverse)
{
mainColor.red=backgroundColor.red;
mainColor.green=backgroundColor.green;
mainColor.blue=backgroundColor.blue;
}
else
{
mainColor.red=foregroundColor.red;
mainColor.green=foregroundColor.green;
mainColor.blue=foregroundColor.blue;
}
switch(CurMem)
{
case M0:
curfont=font;
offset=-32;
break;
case M1:
curfont=font;
offset=64;
break;
case M2:
curfont=fontm23;
offset=-32;
break;
case M3:
curfont=fontm23;
offset=32;
break;
}
x=Coord->x;
if (ModeBold)
y=((Coord->y+30)^0x1FF)&0x1FF;
else
y=((Coord->y+15)^0x1FF)&0x1FF;
if (FastText==padF)
{
goto chardraw_with_fries;
}
/* the diet chardraw routine - fast text output. */
for (i=0;i<count;++i)
{
a=*ch;
++ch;
a+=offset;
p=&curfont[FONTPTR(a)];
for (j=0;j<16;++j)
{
b=*p;
for (k=0;k<8;++k)
{
if (b<0) /* check sign bit. */
{
padPt c;
c.x = x;
c.y = y;
screen_dot_draw(&c);
}
++x;
b<<=1;
}
++y;
x-=width;
++p;
}
x+=width;
y-=height;
}
return;
chardraw_with_fries:
if (Rotate)
{
deltaX=-abs(deltaX);
width=-abs(width);
px=&y;
py=&x;
}
else
{
px=&x;
py=&y;
}
if (ModeBold)
{
deltaX = deltaY = 2;
width<<=1;
height<<=1;
}
for (i=0;i<count;++i)
{
a=*ch;
++ch;
a+=offset;
p=&curfont[FONTPTR(a)];
for (j=0;j<16;++j)
{
b=*p;
if (Rotate)
{
px=&y;
py=&x;
}
else
{
px=&x;
py=&y;
}
for (k=0;k<8;++k)
{
if (b<0) /* check sign bit. */
{
padPt c;
if (ModeBold)
{
c.x = x+1;
c.y = y;
screen_dot_draw(&c);
c.x = x;
c.y = y+1;
screen_dot_draw(&c);
c.x++;
screen_dot_draw(&c);
/* canvas_set_pixel(*px+1,*py,SDL_MapRGB(surface->format,mainColor.red,mainColor.green,mainColor.blue)); */
/* canvas_set_pixel(*px,*py+1,SDL_MapRGB(surface->format,mainColor.red,mainColor.green,mainColor.blue)); */
/* canvas_set_pixel(*px+1,*py+1,SDL_MapRGB(surface->format,mainColor.red,mainColor.green,mainColor.blue)); */
}
c.x = x;
c.y = y;
screen_dot_draw(&c);
/* canvas_set_pixel(*px,*py,SDL_MapRGB(surface->format,mainColor.red,mainColor.green,mainColor.blue)); */
}
else
{
if (CurMode==ModeInverse || CurMode==ModeRewrite)
{
if (ModeBold)
{
/* canvas_set_pixel(*px+1,*py,SDL_MapRGB(surface->format,altColor.red,altColor.green,altColor.blue)); */
/* canvas_set_pixel(*px,*py+1,SDL_MapRGB(surface->format,altColor.red,altColor.green,altColor.blue)); */
/* canvas_set_pixel(*px+1,*py+1,SDL_MapRGB(surface->format,altColor.red,altColor.green,altColor.blue)); */
}
/* canvas_set_pixel(*px,*py,SDL_MapRGB(surface->format,altColor.red,altColor.green,altColor.blue)); */
}
}
x += deltaX;
b<<=1;
}
y+=deltaY;
x-=width;
++p;
}
Coord->x+=width;
x+=width;
y-=height;
}
return;
}
/**
* screen_tty_char - Called to plot chars when in tty mode
*/
void screen_tty_char(padByte theChar)
{
if ((theChar >= 0x20) && (theChar < 0x7F)) {
screen_char_draw(&TTYLoc, &theChar, 1);
TTYLoc.x += CharWide;
}
else if (theChar == 0x0b) /* Vertical Tab */
{
TTYLoc.y += CharHigh;
}
else if ((theChar == 0x08) && (TTYLoc.x > 7))/* backspace */
{
TTYLoc.x -= CharWide;
/* screen_block_draw(&scalex[TTYLoc.x],&scaley[TTYLoc.y],&scalex[TTYLoc.x+CharWide],&scaley[TTYLoc.y+CharHigh]); */
}
else if (theChar == 0x0A)/* line feed */
TTYLoc.y -= CharHigh;
else if (theChar == 0x0D)/* carriage return */
TTYLoc.x = 0;
if (TTYLoc.x + CharWide > 511) {/* wrap at right side */
TTYLoc.x = 0;
TTYLoc.y -= CharHigh;
}
if (TTYLoc.y < 0) {
screen_clear();
TTYLoc.y=495;
}
}
/**
* screen_foreground - Called to set foreground color.
*/
void screen_foreground(padRGB* theColor)
{
foregroundColor.red = theColor->red;
foregroundColor.green = theColor->green;
foregroundColor.blue = theColor->blue;
}
/**
* screen_background - Called to set foreground color.
*/
void screen_background(padRGB* theColor)
{
backgroundColor.red = theColor->red;
backgroundColor.green = theColor->green;
backgroundColor.blue = theColor->blue;
}
/**
* screen_paint_get_pixel - Get pixel at x,y
*/
unsigned char screen_paint_get_pixel(int x, int y)
{
return 0;
}
/**
* screen_paint - Called to paint at location.
*/
void screen_paint(padPt* Coord)
{
static unsigned short xStack[512];
static unsigned short yStack[512];
unsigned char stackentry = 1;
unsigned char spanAbove, spanBelow;
int x = Coord->x;
int y = (Coord->y^0x1FF)&0x1FF;
unsigned char oldColor;
unsigned char foregroundColorPixel;
return;
oldColor = screen_paint_get_pixel(x,y);
/* foregroundColorPixel = SDL_MapRGB(surface->format,foregroundColor.red,foregroundColor.green,foregroundColor.blue); */
if (oldColor == foregroundColorPixel)
return;
do
{
unsigned short startx;
while (x > 0 && screen_paint_get_pixel(x-1,y) == oldColor)
--x;
spanAbove = spanBelow = false;
startx=x;
while(screen_paint_get_pixel(x,y) == oldColor)
{
if (y < (511))
{
unsigned char belowColor = screen_paint_get_pixel(x, y+1);
if (!spanBelow && belowColor == oldColor)
{
xStack[stackentry] = x;
yStack[stackentry] = y+1;
++stackentry;
spanBelow = true;
}
else if (spanBelow && belowColor != oldColor)
spanBelow = false;
}
if (y > 0)
{
unsigned char aboveColor = screen_paint_get_pixel(x, y-1);
if (!spanAbove && aboveColor == oldColor)
{
xStack[stackentry] = x;
yStack[stackentry] = y-1;
++stackentry;
spanAbove = true;
}
else if (spanAbove && aboveColor != oldColor)
spanAbove = false;
}
++x;
}
/* canvas_line(startx,y,x-1,y,foregroundColorPixel); */
--stackentry;
x = xStack[stackentry];
y = yStack[stackentry];
}
while (stackentry);
}
/**
* screen_done()
* Close down TGI
*/
void screen_done(void)
{
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment