EMILE/second/vga.c
Laurent Vivier 20e785f628 Define vga_set_palette() to define current display palette.
Signed-off-by: Laurent Vivier <Laurent@lvivier.info>
2008-09-17 14:53:27 +02:00

848 lines
18 KiB
C

/*
*
* (c) 2004-2007 Laurent Vivier <Laurent@lvivier.info>
*
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <macos/lowmem.h>
#include <macos/quickdraw.h>
#include <libmacos.h>
#include "misc.h"
#include "vga.h"
#include "keyboard.h"
#include "config.h"
static QDGlobals qd;
#define CHARSET_0 0
#define CHARSET_A 1
#define CHARSET_B 2
static unsigned char translation[][256] = {
/* VT100 Graphics to IBM CP-437 0 */
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x1a, 0x1b, 0x18, 0x19, 0x2f,
0xdb, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0xa0,
0x00, 0xb1, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xb1,
0xb0, 0x00, 0xd9, 0xbf, 0xda, 0xc0, 0xc5, 0x00,
0x00, 0xc4, 0x00, 0x00, 0xc3, 0xb4, 0xc1, 0xc2,
0xb3, 0xf3, 0xf2, 0xe3, 0x00, 0x9c, 0xb7, 0x7f,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0xa0, 0xa1, 0x9b, 0x9c, 0xa4, 0x9d, 0xa6, 0x15,
0xa8, 0xa9, 0xa6, 0xab, 0xaa, 0xad, 0xae, 0xaf,
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0x14, 0xb7,
0xb8, 0xb9, 0xa7, 0xaf, 0xac, 0xab, 0xbe, 0xa8,
0xc0, 0xc1, 0xc2, 0xc3, 0x8e, 0x8f, 0x92, 0x80,
0xc8, 0x90, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0xd0, 0xa5, 0xd2, 0xd3, 0xd4, 0xd5, 0x99, 0xd7,
0xd8, 0xd9, 0xda, 0xdb, 0x9a, 0xdd, 0xde, 0xdf,
0x85, 0xa0, 0x83, 0xe3, 0x84, 0x86, 0x91, 0x87,
0x8a, 0x82, 0x88, 0x89, 0x8d, 0xa1, 0x8c, 0x8b,
0xf0, 0xa4, 0x95, 0xa2, 0x93, 0xf5, 0x94, 0xf6,
0xf8, 0x97, 0xa3, 0x96, 0x81, 0xfd, 0xfe, 0x98,
},
/* UK ASCII to IBM CP-437 A */
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0x5f, 0xa1, 0x9b, 0x7d, 0xa4, 0x9d, 0xa6, 0x15,
0xa8, 0xa9, 0xa6, 0xab, 0xaa, 0xad, 0xae, 0xaf,
0x66, 0x67, 0xb2, 0xb3, 0xb4, 0xb5, 0x14, 0x7e,
0xb8, 0xb9, 0xa7, 0xaf, 0xac, 0xab, 0xbe, 0xa8,
0xc0, 0xc1, 0xc2, 0xc3, 0x8e, 0x8f, 0x92, 0x80,
0xc8, 0x90, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0xd0, 0xa5, 0xd2, 0xd3, 0xd4, 0xd5, 0x99, 0xd7,
0xd8, 0xd9, 0xda, 0xdb, 0x9a, 0xdd, 0xde, 0xdf,
0x85, 0xa0, 0x83, 0xe3, 0x84, 0x86, 0x91, 0x87,
0x8a, 0x82, 0x88, 0x89, 0x8d, 0xa1, 0x8c, 0x8b,
0xf0, 0xa4, 0x95, 0xa2, 0x93, 0xf5, 0x94, 0xf6,
0xf8, 0x97, 0xa3, 0x96, 0x81, 0xfd, 0xfe, 0x98,
},
/* US ASCII to IBM CP-437 B */
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
}
};
#define VT100_STACK_SIZE 16
typedef struct vga_handler {
unsigned int enabled;
unsigned char* video;
unsigned char* base;
unsigned long row_bytes; /* in bytes */
unsigned long depth; /* 4, 8, 16 or 32 */
unsigned long width; /* in pixels */
unsigned long height;
unsigned long siz_w, siz_h;
unsigned long pos_x, pos_y;
unsigned char mask;
/* vt100 emulation */
int escape_level;
char escape_stack[VT100_STACK_SIZE];
unsigned long saved_x, saved_y;
int charset;
} vga_handler_t ;
static unsigned char bits_depth2[16] = {
0x00, /* 0 : 0000 -> 00000000 */
0x03, /* 1 : 0001 -> 00000011 */
0x0c, /* 2 : 0010 -> 00001100 */
0x0f, /* 3 : 0011 -> 00001111 */
0x30, /* 4 : 0100 -> 00110000 */
0x33, /* 5 : 0101 -> 00110011 */
0x3c, /* 6 : 0110 -> 00111100 */
0x3f, /* 7 : 0111 -> 00111111 */
0xc0, /* 8 : 1000 -> 11000000 */
0xc3, /* 9 : 1001 -> 11000011 */
0xcc, /* 10 : 1010 -> 11001100 */
0xcf, /* 11 : 1011 -> 11001111 */
0xf0, /* 12 : 1100 -> 11110000 */
0xf3, /* 13 : 1101 -> 11110011 */
0xfc, /* 14 : 1110 -> 11111100 */
0xff /* 15 : 1111 -> 11111111 */
};
static unsigned char bits_depth4[4] = {
0x00, /* 0 : 00 -> 00000000 */
0x0f, /* 1 : 01 -> 00001111 */
0xf0, /* 2 : 10 -> 11110000 */
0xFF /* 3 : 11 -> 11111111 */
};
static unsigned char bits_depth8[2] = {
0x00, /* 0 : 0 -> 00000000 */
0xff /* 0 : 1 -> 11111111 */
};
static vga_handler_t vga =
{
.enabled = 0,
.video = 0,
.base = 0,
.row_bytes = 0,
.depth = 0,
.width = 0,
.height = 0,
.siz_w = 0,
.siz_h = 0,
.pos_x = 0,
.pos_y = 0,
.mask = 0,
};
static unsigned long cursor_save_x, cursor_save_y;
#define CURSOR_POS 0
#define CURSOR_HIGH 16
static int cursor_on = 0;
static int cursor_state = 0;
extern unsigned char* font_get(int c);
static void
draw_cursor(void)
{
int l,w;
unsigned char *base;
unsigned long x_base;
unsigned long y_base;
y_base = vga.row_bytes * vga.pos_y * 16;
x_base = vga.pos_x * vga.depth;
base = vga.base + y_base + x_base;
base += CURSOR_POS * vga.row_bytes;
for (l = 0 ; l < CURSOR_HIGH ; l++)
{
for (w = 0; w < vga.depth; w++)
base[w] ^= 0xFF;
base += vga.row_bytes;
}
}
static void vga_cursor(int state)
{
if (cursor_state != state)
{
draw_cursor();
cursor_state = state;
}
}
void vga_cursor_refresh(void)
{
if (!cursor_on)
return;
if (Ticks % 60 < 30)
vga_cursor(0);
else
vga_cursor(1);
}
static void vga_cursor_on(void)
{
cursor_on = 1;
vga_cursor_refresh();
}
static void vga_cursor_off(void)
{
cursor_on = 0;
vga_cursor(0);
}
void vga_cursor_save(void)
{
cursor_save_x = vga.pos_x;
cursor_save_y = vga.pos_y;
}
void vga_cursor_restore(void)
{
vga_cursor(0);
vga.pos_x = cursor_save_x;
vga.pos_y = cursor_save_y;
vga_cursor(1);
}
static void vga_set_video_mode(int m)
{
if (m) /* inverse */
vga.mask = 0x00;
else /* normal */
vga.mask = 0xFF;
}
static void
draw_byte_1(unsigned char *glyph, unsigned char *base)
{
int l;
for (l = 0 ; l < 16; l++)
{
*base = vga.mask ^ (*glyph++);
base += vga.row_bytes;
}
}
static void
draw_byte_2(unsigned char *glyph, unsigned char *base)
{
int l;
int bits;
for (l = 0 ; l < 16; l++)
{
bits = vga.mask ^ (*glyph++);
base[1] = bits_depth2[bits & 0x0F];
bits = bits >> 4;
base[0] = bits_depth2[bits & 0x0F];
base += vga.row_bytes;
}
}
static void
draw_byte_4(unsigned char *glyph, unsigned char *base)
{
int l;
int bits;
for (l = 0 ; l < 16; l++)
{
bits = vga.mask ^ (*glyph++);
base[3] = bits_depth4[bits & 0x03];
bits = bits >> 2;
base[2] = bits_depth4[bits & 0x03];
bits = bits >> 2;
base[1] = bits_depth4[bits & 0x03];
bits = bits >> 2;
base[0] = bits_depth4[bits & 0x03];
base += vga.row_bytes;
}
}
static void
draw_byte_8(unsigned char *glyph, unsigned char *base)
{
int l;
int bits;
for (l = 0 ; l < 16; l++)
{
bits = vga.mask ^ (*glyph++);
base[7] = bits_depth8[bits & 0x01];
bits = bits >> 1;
base[6] = bits_depth8[bits & 0x01];
bits = bits >> 1;
base[5] = bits_depth8[bits & 0x01];
bits = bits >> 1;
base[4] = bits_depth8[bits & 0x01];
bits = bits >> 1;
base[3] = bits_depth8[bits & 0x01];
bits = bits >> 1;
base[2] = bits_depth8[bits & 0x01];
bits = bits >> 1;
base[1] = bits_depth8[bits & 0x01];
bits = bits >> 1;
base[0] = bits_depth8[bits & 0x01];
base += vga.row_bytes;
}
}
static void
draw_byte_16(unsigned char *glyph, unsigned char *base)
{
int l;
int bits;
for (l = 0 ; l < 16; l++)
{
bits = *glyph++;
base[15] = base[14] = bits_depth8[bits & 0x01];
bits = bits >> 1;
base[13] = base[12] = bits_depth8[bits & 0x01];
bits = bits >> 1;
base[11] = base[10] = bits_depth8[bits & 0x01];
bits = bits >> 1;
base[9] = base[8] = bits_depth8[bits & 0x01];
bits = bits >> 1;
base[7] = base[6] = bits_depth8[bits & 0x01];
bits = bits >> 1;
base[5] = base[4] = bits_depth8[bits & 0x01];
bits = bits >> 1;
base[3] = base[2] = bits_depth8[bits & 0x01];
bits = bits >> 1;
base[1] = base[0] = bits_depth8[bits & 0x01];
base += vga.row_bytes;
}
}
static void
draw_byte_24(unsigned char *glyph, unsigned char *base)
{
int l;
int bits;
for (l = 0 ; l < 16; l++)
{
bits = *glyph++;
base[23] = base[22] = base[21] = bits_depth8[bits & 0x01];
bits = bits >> 1;
base[20] = base[19] = base[18] = bits_depth8[bits & 0x01];
bits = bits >> 1;
base[17] = base[16] = base[15] = bits_depth8[bits & 0x01];
bits = bits >> 1;
base[14] = base[13] = base[12] = bits_depth8[bits & 0x01];
bits = bits >> 1;
base[11] = base[10] = base[9] = bits_depth8[bits & 0x01];
bits = bits >> 1;
base[8] = base[7] = base[6] = bits_depth8[bits & 0x01];
bits = bits >> 1;
base[5] = base[4] = base[3] = bits_depth8[bits & 0x01];
bits = bits >> 1;
base[2] = base[1] = base[0] = bits_depth8[bits & 0x01];
base += vga.row_bytes;
}
}
static void
draw_byte(unsigned char c, unsigned long locX, unsigned long locY)
{
unsigned char *base;
unsigned char *glyph;
unsigned long x_base;
unsigned long y_base;
glyph = font_get(c);
y_base = vga.row_bytes * locY * 16;
x_base = locX * vga.depth;
base = vga.base + y_base + x_base;
switch(vga.depth)
{
case 1:
draw_byte_1(glyph, base);
break;
case 2:
draw_byte_2(glyph, base);
break;
case 4:
draw_byte_4(glyph, base);
break;
case 8:
draw_byte_8(glyph, base);
break;
case 16:
draw_byte_16(glyph, base);
break;
case 24:
draw_byte_24(glyph, base);
break;
}
}
static void
vga_scroll()
{
unsigned long j;
unsigned long i;
unsigned long *src;
unsigned long *dst;
unsigned long bg32;
/* move up the screen */
src = (unsigned long *)(vga.base + (vga.row_bytes << 4));
dst = (unsigned long *)vga.base;
for (j = 0; j < vga.siz_h - 1; j++)
for (i = 0; i < (vga.row_bytes<<2); i++)
*dst++ = *src++;
/* clear last line */
if (vga.depth <= 8)
bg32 = 0xffffffff;
else
bg32 = 0x00000000;
for (j = 0; j < (vga.row_bytes << 2); j++)
*dst++ = bg32;
}
static void vga_clear();
int
vga_init(char *mode)
{
GDHandle hdl;
volatile PixMapPtr pm;
InitGraf(&qd.thePort);
hdl = LMGetMainDevice();
if ( (hdl == (GDHandle)0xAAAAAAAA) || (hdl == NULL) ||
((**hdl).gdPMap == NULL) || ((*(**hdl).gdPMap)->baseAddr == NULL) )
{
vga.base = qd.screenBits.baseAddr;
vga.row_bytes = qd.screenBits.rowBytes;
vga.width = qd.screenBits.bounds.right -
qd.screenBits.bounds.left;
vga.height = qd.screenBits.bounds.bottom -
qd.screenBits.bounds.top;
vga.depth = 1;
} else {
pm = *(**hdl).gdPMap;
vga.video = (unsigned char *)pm->baseAddr;
vga.row_bytes = pm->rowBytes & 0x3fff;
vga.width = pm->bounds.right - pm->bounds.left;
vga.height = pm->bounds.bottom - pm->bounds.top;
vga.depth = pm->pixelSize;
if (vga.depth == 15)
vga.depth = 16;
}
vga.base = vga.video + pm->bounds.top * vga.row_bytes + pm->bounds.left * (vga.depth >> 3);
vga.pos_x = 0;
vga.pos_y = 0;
vga.siz_w = vga.width / 8;
vga.siz_h = vga.height / 16;
vga.mask = 0xFF;
vga.escape_level= 0;
vga.charset = CHARSET_B;
vga_cursor(0);
if (strcmp(mode, "none") != 0)
{
vga.enabled = 1;
vga_clear();
}
return 0;
}
static void
vga_clear()
{
int i,j;
unsigned long row;
unsigned char bg;
unsigned long bg32;
unsigned long *base;
unsigned char *next;
if (vga.depth <= 8)
{
bg = 0xff;
bg32 = 0xffffffff;
}
else
{
bg = 0x00;
bg32 = 0x00000000;
}
for (j = 0, row = 0; j < vga.height; j++)
{
base = (unsigned long*)(vga.base + row);
row += vga.row_bytes;
for (i = 0; i < (vga.row_bytes >> 2); i++)
*base++ = bg32;
next = (unsigned char*)base;
for (i = i << 2 ; i < vga.row_bytes; i++)
*next++ = bg;
}
vga.pos_x = 0;
vga.pos_y = 0;
vga_cursor_refresh();
}
void
vga_put(char c)
{
int tmp_x, tmp_y;
char *end;
if (!vga.enabled)
return;
vga_cursor(0);
/* VT100 EMULATION */
if (vga.escape_level)
{
vga.escape_stack[vga.escape_level - 1] = c;
vga.escape_stack[vga.escape_level] = 0;
vga.escape_level++;
switch(vga.escape_stack[0])
{
case '7': /* cursor save */
vga.saved_x = vga.pos_x;
vga.saved_y = vga.pos_y;
goto exit_escape;
case '8': /* cursor restore */
vga.pos_x = vga.saved_x;
vga.pos_y = vga.saved_y;
goto exit_escape;
case '(': /* character set selection */
if (vga.escape_level <= 2)
goto exit;
if (vga.escape_stack[1] == '0')
vga.charset = CHARSET_0;
else if (vga.escape_stack[1] == 'A')
vga.charset = CHARSET_A;
else if (vga.escape_stack[1] == 'B')
vga.charset = CHARSET_B;
goto exit_escape;
case '[':
if (vga.escape_level <= 2)
goto exit;
/* Control Sequence Introducer (CSI) ends
* with a letter
*/
switch(c)
{
case 'J': /* clear screen */
if (strcmp("[2J", vga.escape_stack) == 0)
{
vga_clear();
goto exit_escape;
}
break;
case 'l': /* hide cursor */
if (strcmp("[?25l", vga.escape_stack) == 0)
{
vga_cursor_off();
goto exit_escape;
}
break;
case 'h': /* show cursor */
if (strcmp("[?25h", vga.escape_stack) == 0)
{
vga_cursor_on();
goto exit_escape;
}
break;
case 'H': /* set cursor position */
tmp_y = strtol(vga.escape_stack + 1, &end, 10);
if (tmp_y > vga.siz_h)
tmp_y = vga.siz_h;
else if (tmp_y < 1)
tmp_y = 1;
if (*end == ';')
{
tmp_x = strtol(end + 1, &end, 10);
if (tmp_x > vga.siz_w)
tmp_x = vga.siz_w;
else if (tmp_x < 1)
tmp_x = 1;
if (*end == 'H')
{
vga.pos_x = tmp_x - 1;
vga.pos_y = tmp_y - 1;
goto exit_escape;
}
}
break;
case 'm': /* set video mode */
if (strcmp("[7m", vga.escape_stack) == 0)
{
/* inverse */
vga_set_video_mode(1);
goto exit_escape;
}
else if (strcmp("[27m", vga.escape_stack) == 0)
{
/* normal */
vga_set_video_mode(0);
goto exit_escape;
}
break;
case 'n': /* get cursor position */
if(strcmp("[6n", vga.escape_stack) == 0)
{
char buf[16];
sprintf(buf, "\033[%ld;%ldR", vga.pos_y + 1, vga.pos_x + 1);
keyboard_inject(buf);
goto exit_escape;
}
break;
default:
goto exit;
}
}
}
vga.escape_level = 0;
switch(c) {
case '\r':
vga.pos_x = 0;
break;
case '\n':
vga.pos_x = 0;
vga.pos_y++;
break;
case '\b':
if (vga.pos_x > 0)
vga.pos_x--;
else if (vga.pos_y > 0)
{
vga.pos_y--;
vga.pos_x = vga.siz_w - 1;
}
break;
case '\033': /* ESCAPE */
vga.escape_level = 1;
break;
default:
draw_byte(translation[vga.charset][(unsigned char)c],
vga.pos_x++, vga.pos_y);
if (vga.pos_x >= vga.siz_w) {
vga.pos_x = 0;
vga.pos_y++;
}
}
while (vga.pos_y >= vga.siz_h) {
vga_scroll();
vga.pos_y--;
}
exit:
vga_cursor_refresh();
return;
exit_escape:
vga.escape_level = 0;
vga_cursor_refresh();
}
unsigned long vga_get_videobase()
{
return (unsigned long)vga.base;
}
unsigned long vga_get_row_bytes()
{
return vga.row_bytes;
}
unsigned long vga_get_depth()
{
return vga.depth;
}
unsigned long vga_get_width()
{
return vga.width;
}
unsigned long vga_get_height()
{
return vga.height;
}
unsigned long vga_get_video()
{
return (unsigned long)vga.video;
}
int vga_is_available(void)
{
return vga.enabled;
}
void vga_set_palette(RGBColor *palette)
{
GDHandle hdl = LMGetMainDevice();
short depth, gdID;
ColorSpec colors[256];
int i;
if (hdl == NULL || (*hdl)->gdType != clutType)
return;
depth = (*(*hdl)->gdPMap)->pixelSize;
if (depth < 1 || depth > 8)
return;
gdID = (*hdl)->gdID & 0xff;
for (i = 0; i < (1 << depth); i++)
{
colors[i].value = gdID;
colors[i].rgb.red = palette[i].red;
colors[i].rgb.green = palette[i].green;
colors[i].rgb.blue = palette[i].blue;
}
SetEntries(0, (1 << depth) - 1, colors);
}