Changeset bb4fd0c in buchla-emu for emu/ser.c


Ignore:
Timestamp:
07/23/2017 10:17:42 AM (7 years ago)
Author:
Thomas Lopatic <thomas@…>
Branches:
master
Children:
a23f3d9
Parents:
a1fd5d5
Message:

Started serial console.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • emu/ser.c

    ra1fd5d5 rbb4fd0c  
    2222#define ver3(...) _ver(ser_verbose, 2, __VA_ARGS__)
    2323
     24#define CON_W 80
     25#define CON_H 25
     26
     27#define CON_BGR 0x00000000
     28#define CON_CUR 0x00e87000
     29#define CON_FGR ((SDL_Color){ .r = 255, .b = 255, .g = 255, .a = 255 })
     30
     31#define CON_FONT "ttf/vera-sans-mono.ttf"
     32
    2433int32_t ser_verbose = 0;
    2534
     35static uint8_t mem[CON_H][CON_W + 1];
     36
     37static TTF_Font *fon;
     38static int32_t fon_w, fon_h;
     39
     40static int32_t sur_w, sur_h;
     41static SDL_Surface *sur;
     42
     43static int32_t cur_x = 0, cur_y = 0;
     44
     45static void update(void)
     46{
     47        if (SDL_FillRect(sur, NULL, CON_BGR) < 0) {
     48                fail("SDL_FillRect() failed: %s", SDL_GetError());
     49        }
     50
     51        if (SDL_FillRect(sur, &(SDL_Rect){
     52                .x = cur_x * fon_w,
     53                .y = cur_y * fon_h,
     54                .w = fon_w,
     55                .h = fon_h
     56        }, CON_CUR) < 0) {
     57                fail("SDL_FillRect() failed: %s", SDL_GetError());
     58        }
     59
     60        for (int32_t y = 0; y < CON_H; ++y) {
     61                SDL_Surface *lin = TTF_RenderText_Blended(fon, (char *)mem[y], CON_FGR);
     62
     63                if (lin == NULL) {
     64                        fail("TTF_RenderText_Blended() failed: %s", TTF_GetError());
     65                }
     66
     67                if (SDL_BlitSurface(lin, NULL, sur, &(SDL_Rect){
     68                        .x = 0,
     69                        .y = y * fon_h,
     70                        .w = CON_W * fon_w,
     71                        .h = fon_h
     72                })) {
     73                        fail("SDL_BlitSurface() failed: %s", SDL_GetError());
     74                }
     75
     76                SDL_FreeSurface(lin);
     77        }
     78
     79        SDL_Texture *tex = SDL_CreateTextureFromSurface(sdl_ren, sur);
     80
     81        if (tex == NULL) {
     82                fail("SDL_CreateTextureFromSurface() failed: %s", SDL_GetError());
     83        }
     84
     85        if (SDL_RenderCopy(sdl_ren, tex, NULL, NULL) < 0) {
     86                fail("SDL_RenderCopy() failed: %s", SDL_GetError());
     87        }
     88
     89        SDL_DestroyTexture(tex);
     90        SDL_RenderPresent(sdl_ren);
     91}
     92
     93static void scroll(void)
     94{
     95        memmove(mem, mem + 1, (CON_H - 1) * (CON_W + 1));
     96        memset(mem + (CON_H - 1), ' ', CON_W);
     97}
     98
     99static void forw(void)
     100{
     101        if (cur_x < CON_W - 1) {
     102                ++cur_x;
     103                return;
     104        }
     105
     106        if (cur_y == CON_H - 1) {
     107                cur_x = 0;
     108                scroll();
     109                return;
     110        }
     111
     112        cur_x = 0;
     113        ++cur_y;
     114}
     115
     116static void back(void)
     117{
     118        if (cur_x > 0) {
     119                --cur_x;
     120                return;
     121        }
     122
     123        if (cur_y == 0) {
     124                return;
     125        }
     126
     127        cur_x = CON_W - 1;
     128        --cur_y;
     129}
     130
     131static void down(void)
     132{
     133        if (cur_y < CON_H - 1) {
     134                ++cur_y;
     135                return;
     136        }
     137
     138        scroll();
     139}
     140
     141static void echo(uint8_t c)
     142{
     143        switch (c) {
     144        case '\r':
     145                cur_x = 0;
     146                break;
     147
     148        case '\n':
     149                down();
     150                break;
     151
     152        case '\b':
     153                back();
     154                break;
     155
     156        default:
     157                if (c < 32) {
     158                        echo('^');
     159                        echo((uint8_t)(c + '@'));
     160                        return;
     161                }
     162
     163                mem[cur_y][cur_x] = c;
     164                forw();
     165                break;
     166        }
     167
     168        update();
     169}
     170
     171void ser_key(SDL_KeyboardEvent *ev)
     172{
     173        switch (ev->keysym.sym) {
     174        case SDLK_BACKSPACE:
     175                echo('\b');
     176                break;
     177
     178        case SDLK_RETURN:
     179                echo('\r');
     180                echo('\n');
     181                break;
     182        }
     183}
     184
     185void ser_text(SDL_TextInputEvent *ev)
     186{
     187        for (int32_t i = 0; ev->text[i] != 0; ++i) {
     188                echo((uint8_t)ev->text[i]);
     189        }
     190}
     191
    26192void ser_init(void)
    27193{
    28194        ver("ser init");
     195
     196        SDL_RWops *ops = SDL_RWFromFile(CON_FONT, "rb");
     197
     198        if (ops == NULL) {
     199                fail("error while opening font file " CON_FONT ": %s", SDL_GetError());
     200        }
     201
     202        fon = TTF_OpenFontRW(ops, 1, 32);
     203
     204        if (fon == NULL) {
     205                fail("error while loading font file " CON_FONT ": %s", TTF_GetError());
     206        }
     207
     208        fon_h = TTF_FontLineSkip(fon);
     209
     210        if (TTF_GlyphMetrics(fon, 'X', NULL, NULL, NULL, NULL, &fon_w) < 0) {
     211                fail("error while measuring font width: %s", TTF_GetError());
     212        }
     213
     214        sur_w = CON_W * fon_w;
     215        sur_h = CON_H * fon_h;
     216
     217        sur = SDL_CreateRGBSurface(0, sur_w, sur_h, 32, 0, 0, 0, 0);
     218
     219        if (sur == NULL) {
     220                fail("SDL_CreateRGBSurface() failed: %s", SDL_GetError());
     221        }
     222
     223        for (int32_t y = 0; y < CON_H; ++y) {
     224                for (int32_t x = 0; x < CON_W; ++x) {
     225                        mem[y][x] = ' ';
     226                }
     227
     228                mem[y][CON_W] = 0;
     229        }
     230
     231        update();
    29232}
    30233
     
    32235{
    33236        ver("ser quit");
     237
     238        SDL_FreeSurface(sur);
     239        TTF_CloseFont(fon);
    34240}
    35241
Note: See TracChangeset for help on using the changeset viewer.