~ndiddy/libremo

f7815919b314f2d13530b619835284ebdaac8d7f — Nathan Misner 2 years ago 06706d9
improved font management
12 files changed, 69 insertions(+), 54 deletions(-)

M font.cpp
M font.h
M main.cpp
M menu_text.cpp
A resources/arrow.png
D resources/hibiya24.fnt
D resources/hibiya24_0.png
R resources/{hibiya24.bmfc => hibiya32.bmfc}
A resources/hibiya32.fnt
A resources/hibiya32_0.png
M stage.cpp
M tutorial.cpp
M font.cpp => font.cpp +8 -31
@@ 17,10 17,7 @@
*  along with LibreMO.  If not, see <https://www.gnu.org/licenses/>.
*/

#include <array>
#include <fstream>
#include <map>
#include <memory>
#include <stdexcept>
#include <string>
#include <vector>


@@ 38,29 35,7 @@
// see http://www.angelcode.com/products/bmfont/doc/file_format.html#bin
// for format information

typedef struct {
    uint32_t ch;
    uint16_t x;
    uint16_t y;
    uint16_t width;
    uint16_t height;
    int16_t xOffset;
    int16_t yOffset;
    int16_t xAdvance;
} GLYPH;

uint16_t lineHeight;
uint16_t base;

// first and last printable ascii characters
#define ASCII_MIN (' ')
#define ASCII_MAX ('~')
static std::array<GLYPH, ASCII_MAX - ASCII_MIN> asciiGlyphs;
static std::map<uint32_t, GLYPH> otherGlyphs;

static std::unique_ptr<Surface> fontSurface;

void Font_Init(const std::string &filename) {
Font::Font(const std::string &filename) {
    // --- read in data from file ---
    std::string fullPath = Path_Graphics(filename);
    std::ifstream file(fullPath, std::ios::binary | std::ios::ate);


@@ 142,9 117,7 @@ void Font_Init(const std::string &filename) {
        // size of "character type" in binary file (i'm skipping loading from a couple fields)
        cursor += 20;
    }
}

Font::Font() {
    // create output texture
    dispSurface = SDL_CreateRGBSurfaceWithFormat(0, WINDOW_WIDTH, WINDOW_HEIGHT, 32, fontSurface->raw->format->format);
    if (dispSurface == NULL) {


@@ 234,7 207,11 @@ static void getGlyph(uint8_t *string, uint32_t *out, int *size) {
    }
}

void Font::display(float x, float y, int scale) {
void Font::showRest() {
    printTiming = FONT_TIMING_IMMEDIATE;
}

void Font::display(float x, float y) {
    if (message.empty()) {
        return;
    }


@@ 303,8 280,8 @@ void Font::display(float x, float y, int scale) {
    SDL_Rect drawRect = {
        .x = (int)x,
        .y = (int)y,
        .w = dispSurface->w * scale,
        .h = dispSurface->h * scale
        .w = dispSurface->w,
        .h = dispSurface->h
    };
   SDL_RenderCopy(gRenderer, dispTexture, NULL, &drawRect);
}
\ No newline at end of file

M font.h => font.h +33 -6
@@ 18,15 18,41 @@
*/

#pragma once
#include <array>
#include <map>
#include <memory>
#include <string>
#include <SDL.h>

#include "sdl_wrappers.h"

typedef struct {
	uint32_t ch;
	uint16_t x;
	uint16_t y;
	uint16_t width;
	uint16_t height;
	int16_t xOffset;
	int16_t yOffset;
	int16_t xAdvance;
} GLYPH;

// first and last printable ascii characters
#define ASCII_MIN (' ')
#define ASCII_MAX ('~')

// should be used as the timing parameter in the print method to print the entire
// message at once
#define FONT_TIMING_IMMEDIATE (-1)

class Font {
private:
	uint16_t lineHeight;
	uint16_t base;
	std::array<GLYPH, ASCII_MAX - ASCII_MIN> asciiGlyphs;
	std::map<uint32_t, GLYPH> otherGlyphs;
	std::unique_ptr<Surface> fontSurface;

	// how we display the fonts
	SDL_Surface *dispSurface;
	SDL_Texture *dispTexture;


@@ 46,7 72,8 @@ private:
	void copyToTexture();

public:
	Font();
	// filename: a BMFont .fnt file (binary)
	Font(const std::string &filename);
	~Font();

	// sets up printing a new message.


@@ 54,10 81,10 @@ public:
	// timing: frames between new character getting printed
	void print(const std::string &msg, int timing);

	// makes the rest of the message get displayed (note that you still have
	// to call display)
	void showRest();

	// should be run every frame
	void display(float x, float y, int scale);
	void display(float x, float y);
};

// must be run before creating any font objects.
// filename: a BMFont .fnt file (binary)
void Font_Init(const std::string &filename);
\ No newline at end of file

M main.cpp => main.cpp +1 -1
@@ 136,7 136,7 @@ int main(int argc, char **argv) {

	SDL_Event event;
	int quit = 0;
    int state = STATE_STAGE;
    int state = STATE_MENU;
    Stage_Init();
	
    try {

M menu_text.cpp => menu_text.cpp +8 -4
@@ 65,8 65,13 @@ static int cursor;
// forward declaration
static void switchMainMenu();

static void startGame() {
    font->showRest();
    Menu_StartGame();
}

MENU_ITEM startMenuItems[] = {
    { "INITIALIZE START", Menu_StartGame },
    { "INITIALIZE START", startGame },
    { "STAGE SELECT START", nullptr },
    { "LOADING START", nullptr },
};


@@ 130,8 135,7 @@ static void switchMainMenu() {

void Menu_Text_Init() {
    fontTexture = std::make_unique<Texture>(Sprite_Load("menufont.png", NULL));
    Font_Init("descfont.fnt");
    font = std::make_unique<Font>();
    font = std::make_unique<Font>("descfont.fnt");

    // ---font palette shifting highlight stuff---
    std::vector<uint32_t> originalColors;


@@ 250,7 254,7 @@ static void Menu_Text_PalCycle() {

void Menu_Text_Run() {
    Menu_Text_PalCycle();
    font->display(DESCRIPTION_X, DESCRIPTION_Y, 1);
    font->display(DESCRIPTION_X, DESCRIPTION_Y);

    if ((padDataE & PAD_UP) && (cursor > 0)) { cursor--; }
    if ((padDataE & PAD_DOWN) && (cursor < (currMenu->length - 1))) { cursor++; }

A resources/arrow.png => resources/arrow.png +0 -0
D resources/hibiya24.fnt => resources/hibiya24.fnt +0 -0
D resources/hibiya24_0.png => resources/hibiya24_0.png +0 -0
R resources/hibiya24.bmfc => resources/hibiya32.bmfc +4 -4
@@ 2,10 2,10 @@
fileVersion=1

# font settings
fontName=KH Dot Hibiya 24
fontFile=ttf/KH-Dot-Hibiya-24.ttf
fontName=KH Dot Hibiya 32
fontFile=../../../../Desktop/bmfont/ttf/KH-Dot-Hibiya-32.ttf
charSet=0
fontSize=24
fontSize=32
aa=1
scaleH=100
useSmoothing=1


@@ 35,7 35,7 @@ widthPaddingFactor=0.00

# output file
outWidth=256
outHeight=96
outHeight=192
outBitDepth=8
fontDescFormat=2
fourChnlPacked=0

A resources/hibiya32.fnt => resources/hibiya32.fnt +0 -0
A resources/hibiya32_0.png => resources/hibiya32_0.png +0 -0
M stage.cpp => stage.cpp +2 -2
@@ 233,8 233,8 @@ static int state;

void Stage_Init() {
    currentStage = 0;
    //state = STATE_CUTSCENE_INIT;
    state = STATE_GAME_INIT;
    state = STATE_CUTSCENE_INIT;
    //state = STATE_GAME_INIT;
}

void Stage_Run() {

M tutorial.cpp => tutorial.cpp +13 -6
@@ 143,7 143,7 @@ STAR midStars[NUM_STARS];
STAR farStars[NUM_STARS];

// text stuff
#define OPTIONS_X (264)
#define OPTIONS_X (256)
#define OPTIONS_Y (16)
static std::unique_ptr<Font> optionsFont;



@@ 151,6 151,9 @@ static std::unique_ptr<Font> optionsFont;
#define DESCRIPTION_Y (188)
static std::unique_ptr<Font> descriptionFont;

#define ARROW_X (OPTIONS_X - 16)
static std::unique_ptr<SpriteInfo> arrowSprite;

// draw the star bg
static void dispBG() {
	bgXScroll += BG_XSPEED;


@@ 393,10 396,12 @@ static void dispStars() {
void Tutorial_Init(int level, int numLevels, const std::string &text) {
	Global_SetLoRes();
	Chip_Init();
	Font_Init("descfont.fnt");
	optionsFont = std::make_unique<Font>();
	descriptionFont = std::make_unique<Font>();
	optionsFont = std::make_unique<Font>("hibiya32.fnt");
	descriptionFont = std::make_unique<Font>("descfont.fnt");
	uiTexture = std::make_unique<Texture>(Sprite_Load("tdoors.png", NULL));
	arrowSprite = std::make_unique<SpriteInfo>("arrow.png");
	arrowSprite->x = ARROW_X;
	arrowSprite->y = 16;

	bgSprites[0] = SpriteInfo("tbgstar0.png");
	bgSprites[1] = SpriteInfo("tbgstar1.png");


@@ 430,6 435,7 @@ int Tutorial_Run() {
	}
	if ((padDataE & PAD_ENTER) && Chip_Neutral()) {
		Chip_AnimOut();
		descriptionFont->showRest();
	}
	if (Chip_AnimOutDone() && !Fade_Active()) {
		Fade_Out();


@@ 468,9 474,10 @@ int Tutorial_Run() {
	dispWall();
	Chip_Display(230, 80);

	optionsFont->display(OPTIONS_X, OPTIONS_Y, 2);
	optionsFont->display(OPTIONS_X, OPTIONS_Y);
	arrowSprite->draw();
	if (Chip_AnimInDone()) {
		descriptionFont->display(DESCRIPTION_X, DESCRIPTION_Y, 1);
		descriptionFont->display(DESCRIPTION_X, DESCRIPTION_Y);
	}

	return 0;