diff --git a/game_english/data/Font/couriernew1.PNG b/game_english/data/Font/couriernew1.PNG new file mode 100644 index 00000000..1d1eae0c Binary files /dev/null and b/game_english/data/Font/couriernew1.PNG differ diff --git a/game_english/data/Font/couriernew1.dat b/game_english/data/Font/couriernew1.dat new file mode 100644 index 00000000..74837b87 Binary files /dev/null and b/game_english/data/Font/couriernew1.dat differ diff --git a/game_english/data/Font/couriernew2.PNG b/game_english/data/Font/couriernew2.PNG new file mode 100644 index 00000000..bbb059cb Binary files /dev/null and b/game_english/data/Font/couriernew2.PNG differ diff --git a/game_english/data/Font/couriernew2.dat b/game_english/data/Font/couriernew2.dat new file mode 100644 index 00000000..68ba6908 Binary files /dev/null and b/game_english/data/Font/couriernew2.dat differ diff --git a/game_japanese/data/Font/msgothic1.PNG b/game_japanese/data/Font/msgothic1.PNG new file mode 100644 index 00000000..04930541 Binary files /dev/null and b/game_japanese/data/Font/msgothic1.PNG differ diff --git a/game_japanese/data/Font/msgothic1.dat b/game_japanese/data/Font/msgothic1.dat new file mode 100644 index 00000000..6af06d40 Binary files /dev/null and b/game_japanese/data/Font/msgothic1.dat differ diff --git a/game_japanese/data/Font/msgothic2.PNG b/game_japanese/data/Font/msgothic2.PNG new file mode 100644 index 00000000..ae239df1 Binary files /dev/null and b/game_japanese/data/Font/msgothic2.PNG differ diff --git a/game_japanese/data/Font/msgothic2.dat b/game_japanese/data/Font/msgothic2.dat new file mode 100644 index 00000000..194fc0ba Binary files /dev/null and b/game_japanese/data/Font/msgothic2.dat differ diff --git a/src/Backends/Rendering.h b/src/Backends/Rendering.h index d142a066..bfe923c7 100644 --- a/src/Backends/Rendering.h +++ b/src/Backends/Rendering.h @@ -25,7 +25,7 @@ void RenderBackend_Blit(RenderBackend_Surface *source_surface, const RenderBacke void RenderBackend_ColourFill(RenderBackend_Surface *surface, const RenderBackend_Rect *rect, unsigned char red, unsigned char green, unsigned char blue); RenderBackend_GlyphAtlas* RenderBackend_CreateGlyphAtlas(size_t width, size_t height); void RenderBackend_DestroyGlyphAtlas(RenderBackend_GlyphAtlas *atlas); -void RenderBackend_UploadGlyph(RenderBackend_GlyphAtlas *atlas, size_t x, size_t y, const unsigned char *pixels, size_t width, size_t height); +void RenderBackend_UploadGlyph(RenderBackend_GlyphAtlas *atlas, size_t x, size_t y, const unsigned char *pixels, size_t width, size_t height, size_t pitch); void RenderBackend_PrepareToDrawGlyphs(RenderBackend_GlyphAtlas *atlas, RenderBackend_Surface *destination_surface, unsigned char red, unsigned char green, unsigned char blue); void RenderBackend_DrawGlyph(long x, long y, size_t glyph_x, size_t glyph_y, size_t glyph_width, size_t glyph_height); void RenderBackend_HandleRenderTargetLoss(void); diff --git a/src/Backends/Rendering/SDLTexture.cpp b/src/Backends/Rendering/SDLTexture.cpp index 5c7c1ad6..d85ab086 100644 --- a/src/Backends/Rendering/SDLTexture.cpp +++ b/src/Backends/Rendering/SDLTexture.cpp @@ -341,21 +341,25 @@ void RenderBackend_DestroyGlyphAtlas(RenderBackend_GlyphAtlas *atlas) free(atlas); } -void RenderBackend_UploadGlyph(RenderBackend_GlyphAtlas *atlas, size_t x, size_t y, const unsigned char *pixels, size_t width, size_t height) +void RenderBackend_UploadGlyph(RenderBackend_GlyphAtlas *atlas, size_t x, size_t y, const unsigned char *pixels, size_t width, size_t height, size_t pitch) { unsigned char *buffer = (unsigned char*)malloc(width * height * 4); if (buffer != NULL) { unsigned char *destination_pointer = buffer; - const unsigned char *source_pointer = pixels; - for (size_t i = 0; i < width * height; ++i) + for (size_t iy = 0; iy < height; ++iy) { - *destination_pointer++ = 0xFF; - *destination_pointer++ = 0xFF; - *destination_pointer++ = 0xFF; - *destination_pointer++ = *source_pointer++; + const unsigned char *source_pointer = &pixels[iy * pitch]; + + for (size_t ix = 0; ix < width; ++ix) + { + *destination_pointer++ = 0xFF; + *destination_pointer++ = 0xFF; + *destination_pointer++ = 0xFF; + *destination_pointer++ = *source_pointer++; + } } SDL_Rect rect; diff --git a/src/Bitmap.cpp b/src/Bitmap.cpp index 27b0ca9e..acabdec7 100644 --- a/src/Bitmap.cpp +++ b/src/Bitmap.cpp @@ -6,16 +6,17 @@ #define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_STATIC #define STBI_ONLY_BMP +#define STBI_ONLY_PNG #define STBI_NO_LINEAR #define STBI_NO_STDIO #include "../external/stb_image.h" #include "File.h" -unsigned char* DecodeBitmap(const unsigned char *in_buffer, size_t in_buffer_size, size_t *width, size_t *height) +unsigned char* DecodeBitmap(const unsigned char *in_buffer, size_t in_buffer_size, size_t *width, size_t *height, unsigned int bytes_per_pixel) { int int_width, int_height; - unsigned char *image_buffer = stbi_load_from_memory(in_buffer, in_buffer_size, &int_width, &int_height, NULL, 3); + unsigned char *image_buffer = stbi_load_from_memory(in_buffer, in_buffer_size, &int_width, &int_height, NULL, bytes_per_pixel); *width = int_width; *height = int_height; @@ -23,14 +24,14 @@ unsigned char* DecodeBitmap(const unsigned char *in_buffer, size_t in_buffer_siz return image_buffer; } -unsigned char* DecodeBitmapFromFile(const char *path, size_t *width, size_t *height) +unsigned char* DecodeBitmapFromFile(const char *path, size_t *width, size_t *height, unsigned int bytes_per_pixel) { size_t file_size; unsigned char *file_buffer = LoadFileToMemory(path, &file_size); if (file_buffer != NULL) { - unsigned char *image_buffer = DecodeBitmap(file_buffer, file_size, width, height); + unsigned char *image_buffer = DecodeBitmap(file_buffer, file_size, width, height, bytes_per_pixel); free(file_buffer); diff --git a/src/Bitmap.h b/src/Bitmap.h index 1734f8c7..c0544825 100644 --- a/src/Bitmap.h +++ b/src/Bitmap.h @@ -2,6 +2,6 @@ #include -unsigned char* DecodeBitmap(const unsigned char *in_buffer, size_t in_buffer_size, size_t *width, size_t *height); -unsigned char* DecodeBitmapFromFile(const char *path, size_t *width, size_t *height); +unsigned char* DecodeBitmap(const unsigned char *in_buffer, size_t in_buffer_size, size_t *width, size_t *height, unsigned int bytes_per_pixel); +unsigned char* DecodeBitmapFromFile(const char *path, size_t *width, size_t *height, unsigned int bytes_per_pixel); void FreeBitmap(unsigned char *buffer); diff --git a/src/Draw.cpp b/src/Draw.cpp index bc005c08..b3fb2b9a 100644 --- a/src/Draw.cpp +++ b/src/Draw.cpp @@ -212,7 +212,7 @@ BOOL MakeSurface_Resource(const char *name, SurfaceID surf_no) return FALSE; size_t width, height; - unsigned char *image_buffer = DecodeBitmap(data, size, &width, &height); + unsigned char *image_buffer = DecodeBitmap(data, size, &width, &height, 3); if (image_buffer == NULL) return FALSE; @@ -271,7 +271,7 @@ BOOL MakeSurface_File(const char *name, SurfaceID surf_no) } size_t width, height; - unsigned char *image_buffer = DecodeBitmapFromFile(path.c_str(), &width, &height); + unsigned char *image_buffer = DecodeBitmapFromFile(path.c_str(), &width, &height, 3); if (image_buffer == NULL) { @@ -318,7 +318,7 @@ BOOL ReloadBitmap_Resource(const char *name, SurfaceID surf_no) return FALSE; size_t width, height; - unsigned char *image_buffer = DecodeBitmap(data, size, &width, &height); + unsigned char *image_buffer = DecodeBitmap(data, size, &width, &height, 3); if (!ScaleAndUploadSurface(image_buffer, width, height, surf_no)) { @@ -356,7 +356,7 @@ BOOL ReloadBitmap_File(const char *name, SurfaceID surf_no) } size_t width, height; - unsigned char *image_buffer = DecodeBitmapFromFile(path.c_str(), &width, &height); + unsigned char *image_buffer = DecodeBitmapFromFile(path.c_str(), &width, &height, 3); if (image_buffer == NULL) { @@ -705,7 +705,11 @@ void InitTextObject(const char *name) #endif } - font = LoadFont(path.c_str(), width, height); +// font = LoadFont(path.c_str(), width, height); + + std::string bitmap_path = gDataPath + "/Font/couriernew2.PNG"; + std::string metadata_path = gDataPath + "/Font/couriernew2.dat"; + font = LoadBitmapFont(bitmap_path.c_str(), metadata_path.c_str()); } void PutText(int x, int y, const char *text, unsigned long color) diff --git a/src/Font.cpp b/src/Font.cpp index 7b54dc2a..55cb6078 100644 --- a/src/Font.cpp +++ b/src/Font.cpp @@ -9,6 +9,7 @@ #include FT_FREETYPE_H #include FT_BITMAP_H +#include "Bitmap.h" #include "File.h" #include "Backends/Rendering.h" @@ -45,9 +46,18 @@ typedef struct Glyph typedef struct Font { + unsigned char *image_buffer; + size_t image_buffer_width; + size_t image_buffer_height; + size_t glyph_slot_width; + size_t glyph_slot_height; + size_t total_local_glyphs; + Glyph *local_glyphs; +/* FT_Library library; FT_Face face; unsigned char *data; +*/ Glyph glyphs[TOTAL_GLYPH_SLOTS]; Glyph *glyph_list_head; RenderBackend_GlyphAtlas *atlas; @@ -989,6 +999,34 @@ static Glyph* GetGlyph(Font *font, unsigned long unicode_value) // Couldn't find glyph - overwrite the old at the end. // The one at the end hasn't been used in a while anyway. + for (size_t i = 0; i < font->total_local_glyphs; ++i) + { + if (font->local_glyphs[i].unicode_value == unicode_value) + { + glyph->unicode_value = font->local_glyphs[i].unicode_value; + glyph->width = font->local_glyphs[i].width; + glyph->height = font->local_glyphs[i].height; + glyph->x_offset = font->local_glyphs[i].x_offset; + glyph->y_offset = font->local_glyphs[i].y_offset; + glyph->x_advance = font->local_glyphs[i].x_advance; + + RenderBackend_UploadGlyph(font->atlas, glyph->x, glyph->y, &font->image_buffer[font->local_glyphs[i].y * font->image_buffer_width + font->local_glyphs[i].x], glyph->width, glyph->height, font->image_buffer_width); + + *glyph_pointer = glyph->next; + glyph->next = font->glyph_list_head; + font->glyph_list_head = glyph; + + return glyph; + } + } + + + + + + + +/* unsigned int glyph_index = FT_Get_Char_Index(font->face, unicode_value); #ifdef ENABLE_FONT_ANTIALIASING @@ -1053,10 +1091,12 @@ static Glyph* GetGlyph(Font *font, unsigned long unicode_value) FT_Bitmap_Done(font->library, &bitmap); } +*/ return NULL; } +/* Font* LoadFontFromData(const unsigned char *data, size_t data_size, size_t cell_width, size_t cell_height) { Font *font = (Font*)malloc(sizeof(Font)); @@ -1133,6 +1173,96 @@ Font* LoadFont(const char *font_filename, size_t cell_width, size_t cell_height) return font; } +*/ + +Font* LoadBitmapFont(const char *bitmap_path, const char *metadata_path) +{ + Font *font = NULL; + + size_t bitmap_width, bitmap_height; + unsigned char *image_buffer = DecodeBitmapFromFile(bitmap_path, &bitmap_width, &bitmap_height, 1); + + if (image_buffer != NULL) + { + size_t metadata_size; + unsigned char *metadata_buffer = LoadFileToMemory(metadata_path, &metadata_size); + + if (metadata_buffer != NULL) + { + font = (Font*)malloc(sizeof(Font)); + + if (font != NULL) + { + font->glyph_slot_width = (metadata_buffer[0] << 8) | metadata_buffer[1]; + font->glyph_slot_height = (metadata_buffer[2] << 8) | metadata_buffer[3]; + font->total_local_glyphs = (metadata_buffer[4] << 8) | metadata_buffer[5]; + + font->local_glyphs = (Glyph*)malloc(sizeof(Glyph) * font->total_local_glyphs); + + if (font->local_glyphs != NULL) + { + for (size_t i = 0; i < font->total_local_glyphs; ++i) + { + font->local_glyphs[i].unicode_value = (metadata_buffer[6 + i * 4 + 0] << 8) | metadata_buffer[6 + i * 4 + 1]; + + font->local_glyphs[i].x = (i % (bitmap_width / font->glyph_slot_width)) * font->glyph_slot_width; + font->local_glyphs[i].y = (i / (bitmap_width / font->glyph_slot_width)) * font->glyph_slot_height; + + font->local_glyphs[i].width = font->glyph_slot_width; + font->local_glyphs[i].height = font->glyph_slot_height; + + font->local_glyphs[i].x_offset = 0; + font->local_glyphs[i].y_offset = 0; + + font->local_glyphs[i].x_advance = (metadata_buffer[6 + i * 4 + 2] << 8) | metadata_buffer[6 + i * 4 + 3]; + + font->local_glyphs[i].next = NULL; + } + + size_t atlas_entry_width = font->glyph_slot_width; + size_t atlas_entry_height = font->glyph_slot_height; + + size_t atlas_columns = ceil(sqrt(atlas_entry_width * atlas_entry_height * TOTAL_GLYPH_SLOTS) / atlas_entry_width); + size_t atlas_rows = (TOTAL_GLYPH_SLOTS + (atlas_columns - 1)) / atlas_columns; + + font->atlas_row_length = atlas_columns; + + font->atlas = RenderBackend_CreateGlyphAtlas(atlas_columns * atlas_entry_width, atlas_rows * atlas_entry_height); + + if (font->atlas != NULL) + { + // Initialise the linked-list + for (size_t i = 0; i < TOTAL_GLYPH_SLOTS; ++i) + { + font->glyphs[i].next = (i == 0) ? NULL : &font->glyphs[i - 1]; + + font->glyphs[i].x = (i % font->atlas_row_length) * atlas_entry_width; + font->glyphs[i].y = (i / font->atlas_row_length) * atlas_entry_height; + } + + font->glyph_list_head = &font->glyphs[TOTAL_GLYPH_SLOTS - 1]; + + font->image_buffer = image_buffer; + font->image_buffer_width = bitmap_width; + font->image_buffer_height = bitmap_height; + + free(metadata_buffer); + + return font; + } + } + + free(font); + } + + free(metadata_buffer); + } + + FreeBitmap(image_buffer); + } + + return font; +} void DrawText(Font *font, RenderBackend_Surface *surface, int x, int y, unsigned long colour, const char *string) { @@ -1176,9 +1306,11 @@ void UnloadFont(Font *font) { RenderBackend_DestroyGlyphAtlas(font->atlas); - FT_Done_Face(font->face); - free(font->data); - FT_Done_FreeType(font->library); + FreeBitmap(font->image_buffer); + +// FT_Done_Face(font->face); +// free(font->data); +// FT_Done_FreeType(font->library); free(font); } } diff --git a/src/Font.h b/src/Font.h index 13ed1143..c1e14225 100644 --- a/src/Font.h +++ b/src/Font.h @@ -6,7 +6,8 @@ typedef struct Font Font; -Font* LoadFontFromData(const unsigned char *data, size_t data_size, size_t cell_width, size_t cell_height); -Font* LoadFont(const char *font_filename, size_t cell_width, size_t cell_height); +//Font* LoadFontFromData(const unsigned char *data, size_t data_size, size_t cell_width, size_t cell_height); +//Font* LoadFont(const char *font_filename, size_t cell_width, size_t cell_height); +Font* LoadBitmapFont(const char *bitmap_path, const char *metadata_path); void DrawText(Font *font, RenderBackend_Surface *surface, int x, int y, unsigned long colour, const char *string); void UnloadFont(Font *font); diff --git a/src/Main.cpp b/src/Main.cpp index 1d5f4712..b9839408 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -295,7 +295,7 @@ int main(int argc, char *argv[]) if (window_icon_resource_data != NULL) { size_t window_icon_width, window_icon_height; - unsigned char *window_icon_rgb_pixels = DecodeBitmap(window_icon_resource_data, window_icon_resource_size, &window_icon_width, &window_icon_height); + unsigned char *window_icon_rgb_pixels = DecodeBitmap(window_icon_resource_data, window_icon_resource_size, &window_icon_width, &window_icon_height, 3); if (window_icon_rgb_pixels != NULL) { @@ -312,7 +312,7 @@ int main(int argc, char *argv[]) if (cursor_resource_data != NULL) { size_t cursor_width, cursor_height; - unsigned char *cursor_rgb_pixels = DecodeBitmap(cursor_resource_data, cursor_resource_size, &cursor_width, &cursor_height); + unsigned char *cursor_rgb_pixels = DecodeBitmap(cursor_resource_data, cursor_resource_size, &cursor_width, &cursor_height, 3); if (cursor_rgb_pixels != NULL) {