You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

293 lines
5.5 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "memory/memory.h"
#include "video/gbuffer.h"
#include "screen.h"
void initscreen()
{
memset(&screens,0x00,sizeof(screens));
memset(&screencache,0x00,sizeof(screenstruct));
last_screen_type = 0;
}
void scrattrfill(int scr, unsigned short attr)
{
int qi, qj;
if ((scr >=0) && (scr < MAX_SCREENS))
{
if (screens[scr] != NULL)
{
for (qi = 0; qi<SCR_ROWS; qi++)
for (qj = 0; qj<SCR_COLS; qj++)
screens[scr]->attributes.rowcol[qi][qj] = attr;
}
}
}
void scrclr(int scr)
{
if ((scr >=0) && (scr < MAX_SCREENS))
{
if (screens[scr] != NULL)
{
memset(&screens[scr]->chars, 0x20, SCR_SIZE);
scrattrfill(scr, 0xbd);
screens[scr]->cx = 0;
screens[scr]->cy = 0;
screens[scr]->attr = 0xbd;
}
}
}
screenstruct *openscreen(int scr)
{
if ((scr >=0) && (scr < MAX_SCREENS))
{
if (screens[scr] == NULL)
{
screens[scr] = malloc(sizeof(screenstruct));
memset(screens[scr],0x00,sizeof(screenstruct));
memset(&screens[scr]->chars, 0x20, SCR_SIZE);
scrattrfill(scr, 0xbd);
screens[scr]->blink = 2;
screens[scr]->attr = 0xbd;
if (scr < 0x100)
screens[scr]->type = 0;
else
screens[scr]->type = 1;
}
return(screens[scr]);
}
else
return NULL;
}
void closescreen(int scr)
{
if ((scr >=0) && (scr < MAX_SCREENS))
{
if (screens[scr] != NULL)
{
free(screens[scr]);
screens[scr] = NULL;
}
}
}
void shutdownscreen()
{
int qi;
for (qi = 0; qi < MAX_SCREENS; qi++)
closescreen(qi);
}
void displayscreen(int scr)
{
int qi, qj;
unsigned char ch;
unsigned short attr;
int forceupdate = !(timer_tick % 20);
if ((scr <0) && (scr >= MAX_SCREENS))
return;
if (screens[scr] == NULL)
return;
if (last_screen_type != screens[scr]->type)
{
last_screen_type = screens[scr]->type;
forceupdate = 1;
}
for (qi = 0; qi < SCR_ROWS; qi++)
{
for (qj = 0; qj < SCR_COLS; qj++)
{
ch = screens[scr]->chars.rowcol[qi][qj];
attr = screens[scr]->attributes.rowcol[qi][qj];
if ((screens[scr]->cx == qj) && (screens[scr]->cy == qi))
{
switch(screens[scr]->blink)
{
case 0x01:
ch ^= 0x80;
break;
case 0x02:
if ( ((timer_tick >> 2) & 1) == 0 )
ch ^= 0x80;
break;
}
}
if ( (ch != screencache.chars.rowcol[qi][qj]) || (attr != screencache.attributes.rowcol[qi][qj]) || forceupdate)
{
if (screens[scr]->type == 1)
{
drawchar(qj + 1, qi + 2, ch, (attr & 0x0f) | ((attr >> 4) & 0xf0), ((attr >> 4) & 0x0f) | ((attr >> 8) & 0xf0), rom_charset);
}
else
{
drawchar(qj + 1, qi + 2, ch, 0x0d, 0x10, rom_charset);
}
screencache.chars.rowcol[qi][qj] = ch;
screencache.attributes.rowcol[qi][qj] = attr;
}
}
}
}
void scrxy(int scr, int x, int y)
{
if ((scr >=0) && (scr < MAX_SCREENS))
{
if (screens[scr] != NULL)
{
screens[scr]->cx = x;
screens[scr]->cy = y;
}
}
}
void scrattr(int scr, unsigned short attr)
{
if ((scr >=0) && (scr < MAX_SCREENS))
{
if (screens[scr] != NULL)
{
screens[scr]->attr = attr;
}
}
}
void scrblink(int scr, unsigned char blink)
{
if ((scr >=0) && (scr < MAX_SCREENS))
{
if (screens[scr] != NULL)
{
screens[scr]->blink = blink;
}
}
}
void scrtype(int scr, unsigned char type)
{
if ((scr >=0) && (scr < MAX_SCREENS))
{
if (screens[scr] != NULL)
{
screens[scr]->type = type;
}
}
}
void scrprintf(int scr, const char *fmt, ...)
{
unsigned char buf[1024];
unsigned char *ptr = buf;
va_list va;
int len;
va_start(va, fmt);
vsnprintf(buf, sizeof(buf), fmt, va);
va_end(va);
if ((scr <0) && (scr >= MAX_SCREENS))
return;
if (screens[scr] == NULL)
return;
while (*ptr)
{
if (*ptr>=0x20)
{
screens[scr]->attributes.rowcol[screens[scr]->cy][screens[scr]->cx] = screens[scr]->attr;
screens[scr]->chars.rowcol[screens[scr]->cy][screens[scr]->cx++] = *ptr;
}
else
{
if (*ptr == '\n')
{
screens[scr]->cy++;
screens[scr]->cx=0;
}
if (*ptr == '\t')
{
screens[scr]->cx = (screens[scr]->cx & 0xf8) + 8;
}
if (*ptr == 0x08)
{
if (screens[scr]->cx>0)
screens[scr]->chars.linear[screens[scr]->cy*SCR_COLS + (--screens[scr]->cx)]=0x20;
}
}
if (screens[scr]->cx>=SCR_COLS)
{
screens[scr]->cy++;
screens[scr]->cx = 0;
}
if (screens[scr]->cy>=SCR_ROWS)
{
memcpy(screens[scr]->chars.linear,screens[scr]->chars.linear + SCR_COLS,sizeof(screens[scr]->chars.linear)-SCR_COLS);
memset(screens[scr]->chars.linear + (SCR_ROWS-1)*SCR_COLS,0x20,SCR_COLS);
screens[scr]->cy=SCR_ROWS-1;
}
*ptr++;
}
}
void scrwindow(int scr, int x, int y, int sx, int sy, unsigned short attr, char *hdr)
{
int qi;
scrattr(scr, (attr >> 4) | (attr << 4));
for (qi=y; qi<y+sy; qi++)
{
scrxy(scr, x, qi);
scrprintf(scr,"%*s",sx,"");
}
scrxy(scr, x + (sx - strlen(hdr)) / 2, y);
scrprintf(scr,"%s",hdr);
scrattr(scr, attr);
for (qi=y+1; qi<y+sy-1; qi++)
{
scrxy(scr, x+1, qi);
scrprintf(scr,"%*s",sx-2,"");
}
}
void scrclone(int scr, int src)
{
if ((scr >=0) && (scr < MAX_SCREENS) && (src >=0) && (src < MAX_SCREENS))
{
if ((screens[scr] != NULL) && (screens[scr] != NULL))
{
memcpy(screens[scr],screens[src],sizeof(screenstruct));
}
}
}