2019-06-19 21:41:22 +02:00
|
|
|
// The OS/K Team licenses this file to you under the MIT license.
|
|
|
|
// See the LICENSE file in the project root for more information.
|
|
|
|
|
2019-06-20 17:44:48 +02:00
|
|
|
#include <pc/console.h>
|
2019-06-19 21:41:22 +02:00
|
|
|
|
2019-08-03 17:41:44 +02:00
|
|
|
// FIXME XXX
|
|
|
|
|
|
|
|
//#define _LARGE_SCREEN
|
|
|
|
|
2019-06-23 12:40:18 +02:00
|
|
|
#ifndef _LARGE_SCREEN
|
2019-08-03 17:41:44 +02:00
|
|
|
# define _MULT 1
|
2019-06-23 12:40:18 +02:00
|
|
|
#else
|
2019-08-03 17:41:44 +02:00
|
|
|
# define _MULT 2
|
2019-06-23 12:40:18 +02:00
|
|
|
#endif
|
2019-06-20 13:58:27 +02:00
|
|
|
|
2019-08-03 17:41:44 +02:00
|
|
|
#define CONSOLE_WIDTH (80)
|
|
|
|
#define CONSOLE_HEIGHT (25)
|
|
|
|
#define CONSOLE_FONT_SIZE (16 * _MULT)
|
|
|
|
#define SCREEN_WIDTH (9 * CONSOLE_WIDTH * _MULT)
|
|
|
|
#define SCREEN_HEIGHT (16 * CONSOLE_HEIGHT * _MULT)
|
|
|
|
|
|
|
|
#define _SURF_H CONSOLE_FONT_SIZE
|
2019-06-19 23:16:30 +02:00
|
|
|
|
|
|
|
SDL_Window *scr_win = NULL;
|
|
|
|
SDL_Renderer *scr_rend = NULL;
|
|
|
|
|
|
|
|
TTF_Font *scr_font = NULL;
|
|
|
|
SDL_Color scr_text_color = { 255, 255, 255, 0 };
|
|
|
|
|
2019-06-20 13:58:27 +02:00
|
|
|
char scr_lines[CONSOLE_HEIGHT][CONSOLE_WIDTH+1] = { 0 };
|
|
|
|
SDL_Texture *scr_texts[CONSOLE_HEIGHT] = { 0 };
|
|
|
|
SDL_Rect *scr_rects[CONSOLE_HEIGHT] = { 0 };
|
2019-06-19 23:16:30 +02:00
|
|
|
|
2019-07-10 22:37:59 +02:00
|
|
|
int csn_x = 0;
|
|
|
|
int csn_y = 0;
|
|
|
|
|
2019-06-19 23:16:30 +02:00
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
|
2019-06-19 21:41:22 +02:00
|
|
|
void console_init(ctx_t *ctx)
|
|
|
|
{
|
2019-06-19 23:16:30 +02:00
|
|
|
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);
|
|
|
|
|
2019-06-20 18:13:06 +02:00
|
|
|
SDL_SetRenderDrawColor(scr_rend, 20, 20, 20, 0);
|
|
|
|
|
2019-06-19 23:16:30 +02:00
|
|
|
if (scr_win == NULL || scr_rend == NULL)
|
|
|
|
{
|
|
|
|
logerr("Couldn't create SDL screen window/renderer: %s", SDL_GetError());
|
|
|
|
die(-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
TTF_Init();
|
|
|
|
|
|
|
|
scr_font = TTF_OpenFont
|
2019-06-26 21:27:22 +02:00
|
|
|
("fs/csfont.ttf", CONSOLE_FONT_SIZE);
|
2019-06-19 23:16:30 +02:00
|
|
|
|
|
|
|
if (scr_font == NULL)
|
|
|
|
{
|
|
|
|
logerr("Couldn't open the FreeMono font\n");
|
|
|
|
die(-1);
|
|
|
|
}
|
2019-06-20 12:31:36 +02:00
|
|
|
|
|
|
|
size_t y;
|
2019-06-20 13:58:27 +02:00
|
|
|
for (y = 0; y < CONSOLE_HEIGHT; y++)
|
2019-06-20 12:31:36 +02:00
|
|
|
{
|
2019-06-20 13:58:27 +02:00
|
|
|
memset(scr_lines[y], ' ', CONSOLE_WIDTH);
|
|
|
|
scr_lines[y][CONSOLE_WIDTH] = 0;
|
2019-06-20 12:31:36 +02:00
|
|
|
}
|
2019-06-20 18:13:06 +02:00
|
|
|
|
|
|
|
SDL_RenderClear(scr_rend);
|
|
|
|
SDL_RenderPresent(scr_rend);
|
2019-06-19 23:16:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
|
|
|
|
void console_exit(ctx_t *ctx)
|
|
|
|
{
|
2019-06-20 12:31:36 +02:00
|
|
|
size_t y;
|
2019-06-19 23:16:30 +02:00
|
|
|
|
2019-06-20 13:58:27 +02:00
|
|
|
for (y = 0; y < CONSOLE_HEIGHT; y++)
|
2019-06-20 12:31:36 +02:00
|
|
|
if (scr_texts[y] != NULL)
|
|
|
|
{
|
|
|
|
if (scr_rects[y])
|
|
|
|
free(scr_rects[y]);
|
2019-06-19 23:16:30 +02:00
|
|
|
|
2019-06-20 12:31:36 +02:00
|
|
|
SDL_DestroyTexture(scr_texts[y]);
|
|
|
|
}
|
2019-06-19 23:16:30 +02:00
|
|
|
|
2019-06-21 19:38:31 +02:00
|
|
|
if (scr_rend)
|
|
|
|
SDL_DestroyRenderer(scr_rend);
|
|
|
|
|
2019-06-19 23:16:30 +02:00
|
|
|
if (scr_win)
|
|
|
|
SDL_DestroyWindow(scr_win);
|
|
|
|
|
|
|
|
TTF_Quit();
|
|
|
|
SDL_Quit();
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
|
|
|
|
void console_render(ctx_t *ctx)
|
|
|
|
{
|
2019-06-20 12:31:36 +02:00
|
|
|
size_t y;
|
2019-06-19 23:16:30 +02:00
|
|
|
|
|
|
|
SDL_RenderClear(scr_rend);
|
|
|
|
|
2019-06-20 13:58:27 +02:00
|
|
|
for (y = 0; y < CONSOLE_HEIGHT; y++)
|
2019-06-20 17:44:48 +02:00
|
|
|
if (scr_texts[y] != NULL && scr_rects[y] != NULL)
|
2019-06-20 12:31:36 +02:00
|
|
|
SDL_RenderCopy(scr_rend, scr_texts[y],
|
|
|
|
NULL, scr_rects[y]);
|
2019-06-19 23:16:30 +02:00
|
|
|
|
|
|
|
SDL_RenderPresent(scr_rend);
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
|
2019-06-21 19:38:31 +02:00
|
|
|
void console_update(ctx_t *ctx)
|
|
|
|
{
|
|
|
|
SDL_Event evt;
|
|
|
|
|
|
|
|
if (__builtin_expect(SDL_PollEvent(&evt) == 1, 0))
|
|
|
|
{
|
|
|
|
switch (evt.type)
|
|
|
|
{
|
|
|
|
case SDL_QUIT:
|
|
|
|
die(0);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SDL_KEYDOWN:
|
|
|
|
console_handle_input(ctx, evt.key.keysym.sym);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
|
2019-07-10 22:37:59 +02:00
|
|
|
void console_clear(ctx_t *ctx)
|
|
|
|
{
|
|
|
|
csn_y = CONSOLE_HEIGHT - 1;
|
|
|
|
|
|
|
|
for (int i = 0; i < CONSOLE_HEIGHT; i++)
|
|
|
|
console_putc(ctx, '\n');
|
|
|
|
|
|
|
|
csn_x = csn_y = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
|
2019-06-19 23:16:30 +02:00
|
|
|
void console_putat(ctx_t *ctx, char ch, int x, int y)
|
|
|
|
{
|
|
|
|
SDL_Surface *surf;
|
|
|
|
|
2019-06-20 17:44:48 +02:00
|
|
|
//trace("putat: %c %d %d\n", ch, x, y);
|
2019-06-19 23:16:30 +02:00
|
|
|
|
2019-06-20 13:58:27 +02:00
|
|
|
if (y >= CONSOLE_HEIGHT || x >= CONSOLE_WIDTH)
|
2019-06-20 12:31:36 +02:00
|
|
|
{
|
|
|
|
logerr("console_putat: position out of range (%d,%d)", x, y);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
scr_lines[y][x] = ch;
|
2019-06-19 23:16:30 +02:00
|
|
|
|
2019-06-20 12:31:36 +02:00
|
|
|
surf = TTF_RenderText_Solid(scr_font, scr_lines[y], scr_text_color);
|
2019-06-19 23:16:30 +02:00
|
|
|
|
2019-06-20 12:58:24 +02:00
|
|
|
if (!surf)
|
|
|
|
{
|
2019-06-20 18:13:06 +02:00
|
|
|
logerr("console_putat: couldn't render TTF font: "
|
|
|
|
"(%d,%d) '%c'\nError: '%s'\n", x, y, ch, SDL_GetError());
|
2019-06-20 12:58:24 +02:00
|
|
|
die(-1);
|
|
|
|
}
|
|
|
|
|
2019-06-20 12:31:36 +02:00
|
|
|
if (scr_texts[y])
|
2019-06-19 23:16:30 +02:00
|
|
|
{
|
2019-06-20 12:31:36 +02:00
|
|
|
if (scr_rects[y])
|
2019-06-19 23:16:30 +02:00
|
|
|
{
|
2019-06-20 12:31:36 +02:00
|
|
|
free(scr_rects[y]);
|
|
|
|
scr_rects[y] = NULL;
|
2019-06-19 23:16:30 +02:00
|
|
|
}
|
|
|
|
|
2019-06-20 12:31:36 +02:00
|
|
|
SDL_DestroyTexture(scr_texts[y]);
|
2019-06-19 23:16:30 +02:00
|
|
|
}
|
|
|
|
|
2019-06-20 12:31:36 +02:00
|
|
|
scr_texts[y] = SDL_CreateTextureFromSurface(scr_rend, surf);
|
|
|
|
scr_rects[y] = malloc(sizeof(SDL_Rect));
|
2019-06-19 23:16:30 +02:00
|
|
|
|
2019-06-20 12:58:24 +02:00
|
|
|
if (scr_texts[y] == NULL)
|
|
|
|
{
|
2019-06-20 13:58:27 +02:00
|
|
|
logerr("console_putat: couldn't create texture from surface: "
|
|
|
|
"(%d,%d) '%c'\nError: '%s'\n", x, y, ch, SDL_GetError());
|
2019-06-20 12:58:24 +02:00
|
|
|
SDL_FreeSurface(surf);
|
|
|
|
die(-1);
|
|
|
|
}
|
|
|
|
|
2019-06-20 12:31:36 +02:00
|
|
|
if (scr_rects[y] == NULL)
|
2019-06-19 23:16:30 +02:00
|
|
|
{
|
|
|
|
logerr("console_putat: not enough memory\n");
|
|
|
|
SDL_FreeSurface(surf);
|
2019-06-20 12:58:24 +02:00
|
|
|
SDL_DestroyTexture(scr_texts[y]);
|
2019-06-19 23:16:30 +02:00
|
|
|
die(-1);
|
|
|
|
}
|
|
|
|
|
2019-06-20 12:31:36 +02:00
|
|
|
scr_rects[y]->x = 0;
|
|
|
|
scr_rects[y]->y = y * surf->h;
|
|
|
|
scr_rects[y]->w = surf->w;
|
|
|
|
scr_rects[y]->h = surf->h;
|
2019-06-19 23:16:30 +02:00
|
|
|
|
|
|
|
SDL_FreeSurface(surf);
|
|
|
|
|
|
|
|
console_render(ctx);
|
|
|
|
}
|
|
|
|
|
2019-07-10 22:37:59 +02:00
|
|
|
//----------------------------------------------------------------------------//
|
2019-06-19 23:16:30 +02:00
|
|
|
|
|
|
|
void console_putc(ctx_t *ctx, char ch)
|
|
|
|
{
|
2019-06-20 17:44:48 +02:00
|
|
|
size_t y;
|
|
|
|
|
2019-06-21 19:38:31 +02:00
|
|
|
switch (ch)
|
2019-06-19 21:41:22 +02:00
|
|
|
{
|
2019-06-21 19:38:31 +02:00
|
|
|
case '\n':
|
|
|
|
csn_x = CONSOLE_WIDTH;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case '\r':
|
|
|
|
csn_x = 0;
|
|
|
|
return;
|
|
|
|
|
|
|
|
case '\b':
|
|
|
|
if (csn_x == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
csn_x--;
|
|
|
|
console_putat(ctx, ' ', csn_x, csn_y);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
console_putat(ctx, ch, csn_x, csn_y);
|
|
|
|
csn_x++;
|
|
|
|
break;
|
2019-06-19 21:41:22 +02:00
|
|
|
}
|
|
|
|
|
2019-06-19 23:16:30 +02:00
|
|
|
if (csn_x == CONSOLE_WIDTH)
|
|
|
|
{
|
|
|
|
csn_x = 0;
|
|
|
|
csn_y++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (csn_y == CONSOLE_HEIGHT)
|
2019-06-20 17:44:48 +02:00
|
|
|
{
|
|
|
|
csn_y--;
|
|
|
|
memmove(scr_lines, &scr_lines[1],
|
|
|
|
(CONSOLE_HEIGHT - 1) * CONSOLE_WIDTH);
|
|
|
|
|
|
|
|
memset(&scr_lines[CONSOLE_HEIGHT-1], ' ', CONSOLE_WIDTH);
|
|
|
|
scr_lines[CONSOLE_HEIGHT-1][CONSOLE_WIDTH] = 0;
|
|
|
|
|
|
|
|
if (scr_texts[0] != NULL)
|
|
|
|
{
|
|
|
|
SDL_DestroyTexture(scr_texts[0]);
|
|
|
|
scr_texts[0] = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
memmove(scr_texts, &scr_texts[1],
|
|
|
|
(CONSOLE_HEIGHT - 1) * sizeof(SDL_Texture *));
|
|
|
|
|
|
|
|
scr_texts[CONSOLE_HEIGHT-1] = NULL;
|
|
|
|
|
|
|
|
if (scr_rects[0] != NULL)
|
|
|
|
{
|
|
|
|
free(scr_rects[0]);
|
|
|
|
scr_rects[0] = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
memmove(scr_rects, &scr_rects[1],
|
|
|
|
(CONSOLE_HEIGHT - 1) * sizeof(SDL_Rect *));
|
|
|
|
|
|
|
|
scr_rects[CONSOLE_HEIGHT-1] = NULL;
|
|
|
|
|
|
|
|
for (y = 0; y < CONSOLE_HEIGHT-1; y++)
|
|
|
|
if (scr_rects[y] != NULL)
|
|
|
|
{
|
2019-08-03 17:41:44 +02:00
|
|
|
scr_rects[y]->y -= _SURF_H; // surf->h
|
2019-06-20 17:44:48 +02:00
|
|
|
}
|
2019-06-21 22:19:55 +02:00
|
|
|
|
|
|
|
console_render(ctx);
|
2019-06-20 17:44:48 +02:00
|
|
|
}
|
2019-06-19 21:41:22 +02:00
|
|
|
}
|
|
|
|
|
2019-06-19 23:16:30 +02:00
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
|