rsonx
rsonx

Reputation: 456

How to improve font quality in SDL ttf and dynamically display text and numbers

I am building a 6502 emulator, and I wish to represent the cpu and memory states visually.
I am using SDL2 for this purpose. I have to render text on the SDL window as the 6502 cpu or memory changes states.

i.e I wish to show the entire memory content, current instruction being executed, previous cpu state, current cpu state in form of texts and numbers.

Here is my attempt to render a text using a font already present in my linux system. Later I wish to render dynamic text and numbers instead of a static string.

#include<SDL2/SDL.h>
#include<SDL2/SDL_ttf.h>
#define SCREEN_HEIGHT 640
#define SCREEN_WIDTH 480
int quit=false;
SDL_Window *window;
SDL_Renderer *renderer;
int initializeDrawing(int argc,char** argv){
    if (SDL_Init(SDL_INIT_VIDEO) != 0){
        std::cout << "SDL_Init Error: " << SDL_GetError() << std::endl;
        return 1;
    }
    window = SDL_CreateWindow("6502 cpu display!", 100, 100, SCREEN_HEIGHT, SCREEN_WIDTH, SDL_WINDOW_SHOWN);
    if (window == nullptr){
        std::cout << "SDL_CreateWindow Error: " << SDL_GetError() << std::endl;
        SDL_Quit();
        return 1;
    }
    renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
    if (renderer == nullptr){
        SDL_DestroyWindow(window);
        std::cout << "SDL_CreateRenderer Error: " << SDL_GetError() << std::endl;
        SDL_Quit();
        return 1;
    }
    if (TTF_Init() != 0){
        SDL_Quit();
        return 1;
    }
    return 0;
}
void loop(){
    TTF_Font* Sans = TTF_OpenFont("./ttf/LH.ttf", 13);
    SDL_Color White = {255,255,255};
    SDL_Surface* surfaceMessage = TTF_RenderText_Solid(Sans, "0xABCEDFGHIJKLMNOPQRSTUVWXYZ", White);
    SDL_Texture* Message = SDL_CreateTextureFromSurface(renderer, surfaceMessage);

    SDL_Rect Message_rect;
    Message_rect.x = 0;
    Message_rect.y = 0;
    Message_rect.w = surfaceMessage->w;
    Message_rect.h = surfaceMessage->h;

    //loop
    SDL_Event e;
    while(!quit){
        SDL_PollEvent(&e);
        //If user closes the window
        if (e.type == SDL_QUIT){
            quit = true;
        }
        //First clear the renderer
        SDL_RenderClear(renderer);
        //Draw the texture
        SDL_RenderCopy(renderer, Message, NULL, &Message_rect);
        //Update the screen
        SDL_RenderPresent(renderer);
        //Take a quick break after all that hard work
    }
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
}

Here is the output

enter image description here

  1. I wish to make the text more smaller and smoother.
  2. I am looking for ideas on how to efficiently display numbers and text dynamically.

Upvotes: 2

Views: 4646

Answers (1)

user3684240
user3684240

Reputation: 1580

SDL2_ttf has several different text rendering modes.

You are using the mode Solid which the documentation describes as "Quick and Dirty":

There are three modes of rendering:

  • Solid: Quick and Dirty

    Create an 8-bit palettized surface and render the given text at fast quality with the given font and color. The pixel value of 0 is the colorkey, giving a transparent background when blitted. Pixel and colormap value 1 is set to the text foreground color. This allows you to change the color without having to render the text again. Palette index 0 is of course not drawn when blitted to another surface, since it is the colorkey, and thus transparent, though its actual color is 255 minus each of the RGB components of the foreground color. This is the fastest rendering speed of all the rendering modes. This results in no box around the text, but the text is not as smooth. The resulting surface should blit faster than the Blended one. Use this mode for FPS and other fast changing updating text displays.

  • Shaded: Slow and Nice, but with a Solid Box

    Create an 8-bit palettized surface and render the given text at high quality with the given font and colors. The 0 pixel value is background, while other pixels have varying degrees of the foreground color from the background color. This results in a box of the background color around the text in the foreground color. The text is antialiased. This will render slower than Solid, but in about the same time as Blended mode. The resulting surface should blit as fast as Solid, once it is made. Use this when you need nice text, and can live with a box.

  • Blended: Slow Slow Slow, but Ultra Nice over another image

    Create a 32-bit ARGB surface and render the given text at high quality, using alpha blending to dither the font with the given color. This results in a surface with alpha transparency, so you don't have a solid colored box around the text. The text is antialiased. This will render slower than Solid, but in about the same time as Shaded mode. The resulting surface will blit slower than if you had used Solid or Shaded. Use this when you want high quality, and the text isn't changing too fast.

If you want a higher quality rendering, you should try the *_Shaded or *_Blended functions.

Also note that you almost certainly want to use TTF_RenderUTF8 family of functions to make sure non-Latin characters are rendered correctly. (This may not be immediately relevant to your 6502 emulator, but it does not hurt and is good practice to do anyway.) More information: https://wiki.libsdl.org/SDL_ttf/TTF_RenderUTF8_Blended

Upvotes: 9

Related Questions