1
0
mirror of https://gitlab.os-k.eu/os-k-team/kvisc.git synced 2023-08-25 14:05:46 +02:00
kvisc/vm/cn/console.c
2019-06-20 12:31:36 +02:00

180 lines
3.9 KiB
C

// The OS/K Team licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#include <cn/console.h>
#define SCREEN_WIDTH (1280)
#define SCREEN_HEIGHT (720)
SDL_Window *scr_win = NULL;
SDL_Renderer *scr_rend = NULL;
TTF_Font *scr_font = NULL;
SDL_Color scr_text_color = { 255, 255, 255, 0 };
char scr_lines[SCREEN_HEIGHT][SCREEN_WIDTH] = { 0 };
SDL_Texture *scr_texts[SCREEN_HEIGHT] = { 0 };
SDL_Rect *scr_rects[SCREEN_HEIGHT] = { 0 };
//----------------------------------------------------------------------------//
void console_init(ctx_t *ctx)
{
if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) < 0)
{
logerr("Couldn't initialize SDL: %s", SDL_GetError());
die(-1);
}
SDL_CreateWindowAndRenderer(SCREEN_WIDTH, SCREEN_HEIGHT, 0,
&scr_win, &scr_rend);
if (scr_win == NULL || scr_rend == NULL)
{
logerr("Couldn't create SDL screen window/renderer: %s", SDL_GetError());
die(-1);
}
TTF_Init();
// XXX I have to find a solution about this...
// including FreeMono.ttf directly in the project
// would force it into GPL...
scr_font = TTF_OpenFont
("/usr/share/fonts/truetype/freefont/FreeMono.ttf", 20);
if (scr_font == NULL)
{
logerr("Couldn't open the FreeMono font\n");
die(-1);
}
size_t y;
for (y = 0; y < SCREEN_HEIGHT; y++)
{
memset(scr_lines[y], ' ', SCREEN_WIDTH - 1);
scr_lines[y][SCREEN_WIDTH - 1] = 0;
}
}
//----------------------------------------------------------------------------//
void console_exit(ctx_t *ctx)
{
size_t y;
for (y = 0; y < SCREEN_HEIGHT; y++)
if (scr_texts[y] != NULL)
{
if (scr_rects[y])
free(scr_rects[y]);
SDL_DestroyTexture(scr_texts[y]);
}
if (scr_win)
SDL_DestroyWindow(scr_win);
TTF_Quit();
SDL_Quit();
}
//----------------------------------------------------------------------------//
void console_render(ctx_t *ctx)
{
size_t y;
SDL_SetRenderDrawColor(scr_rend, 20, 20, 20, 0);
SDL_RenderClear(scr_rend);
for (y = 0; y < SCREEN_HEIGHT; y++)
if (scr_texts[y] != NULL)
SDL_RenderCopy(scr_rend, scr_texts[y],
NULL, scr_rects[y]);
SDL_RenderPresent(scr_rend);
}
//----------------------------------------------------------------------------//
void console_putat(ctx_t *ctx, char ch, int x, int y)
{
SDL_Surface *surf;
// trace("putat: %c %d %d\n", ch, x, y);
if (y >= SCREEN_HEIGHT || x >= SCREEN_WIDTH)
{
logerr("console_putat: position out of range (%d,%d)", x, y);
return;
}
scr_lines[y][x] = ch;
surf = TTF_RenderText_Solid(scr_font, scr_lines[y], scr_text_color);
if (scr_texts[y])
{
if (scr_rects[y])
{
free(scr_rects[y]);
scr_rects[y] = NULL;
}
SDL_DestroyTexture(scr_texts[y]);
}
scr_texts[y] = SDL_CreateTextureFromSurface(scr_rend, surf);
scr_rects[y] = malloc(sizeof(SDL_Rect));
if (scr_rects[y] == NULL)
{
logerr("console_putat: not enough memory\n");
SDL_FreeSurface(surf);
die(-1);
}
scr_rects[y]->x = 0;
scr_rects[y]->y = y * surf->h;
scr_rects[y]->w = surf->w;
scr_rects[y]->h = surf->h;
SDL_FreeSurface(surf);
console_render(ctx);
}
#define CONSOLE_WIDTH 80
#define CONSOLE_HEIGHT 25
int csn_x = 0;
int csn_y = 0;
void console_putc(ctx_t *ctx, char ch)
{
if (ch < ' ' && ch != '\n')
ch = 127;
if (ch == '\n')
csn_x = CONSOLE_WIDTH;
else
{
console_putat(ctx, ch, csn_x, csn_y);
csn_x++;
}
if (csn_x == CONSOLE_WIDTH)
{
csn_x = 0;
csn_y++;
}
if (csn_y == CONSOLE_HEIGHT)
csn_y = 0;
}
//----------------------------------------------------------------------------//