From 051040af2d0829933f474e1accf8441b352bed13 Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Fri, 16 Feb 2018 05:43:13 +0100 Subject: CMake: Remove _RAYLIB suffix from -D{SHARED,STATIC}_RAYLIB They were named so for compatibility with make, but make doesn't use the anymore. I always forget whether it's SHARED_RAYLIB or RAYLIB_SHARED... For now, RAYLIB_SHARED and STATIC_RAYLIB may still be used, but print a deprecation warning. --- .travis.yml | 2 +- appveyor.yml | 2 +- src/CMakeLists.txt | 27 ++++++++++++++++++--------- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index e3a0e67d..19241346 100644 --- a/.travis.yml +++ b/.travis.yml @@ -45,7 +45,7 @@ before_install: script: - mkdir build - cd build - - cmake -DMACOS_FATLIB=ON -DSTATIC_RAYLIB=ON -DSHARED_RAYLIB=ON -DBUILD_EXAMPLES=ON -DBUILD_GAMES=ON -DUSE_EXTERNAL_GLFW=IF_POSSIBLE .. + - cmake -DMACOS_FATLIB=ON -DSTATIC=ON -DSHARED=ON -DBUILD_EXAMPLES=ON -DBUILD_GAMES=ON -DUSE_EXTERNAL_GLFW=IF_POSSIBLE .. - make VERBOSE=1 - make package diff --git a/appveyor.yml b/appveyor.yml index 4148e744..bec37da8 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -39,7 +39,7 @@ before_build: - cd build build_script: - - cmake -G %GENERATOR% -DSTATIC_RAYLIB=ON -DSHARED_RAYLIB=ON -DBUILD_EXAMPLES=%examples% -DBUILD_GAMES=%examples% .. + - cmake -G %GENERATOR% -DSTATIC=ON -DSHARED=ON -DBUILD_EXAMPLES=%examples% -DBUILD_GAMES=%examples% .. - cmake --build . --target install after_build: diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 40871455..6f759324 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -10,12 +10,21 @@ set(RAYLIB raylib) # Name of the generated library # Shared library is always PIC. Static library should be PIC too if linked into a shared library set(WITH_PIC OFF CACHE BOOL "Compile static library as position-independent code" OFF) # Build a static and/or shared raylib? -set(SHARED_RAYLIB OFF CACHE BOOL "Build raylib as a dynamic library") -set(STATIC_RAYLIB ON CACHE BOOL "Build raylib as a static library") +set(SHARED OFF CACHE BOOL "Build raylib as a dynamic library") +set(STATIC ON CACHE BOOL "Build raylib as a static library") set(MACOS_FATLIB ON CACHE BOOL "Build fat library for both i386 and x86_64 on macOS") -if(NOT (STATIC_RAYLIB OR SHARED_RAYLIB)) - message(FATAL_ERROR "Nothing to do if both -DSHARED_RAYLIB=OFF and -DSTATIC_RAYLIB=OFF...") +if(NOT (STATIC OR SHARED)) + message(FATAL_ERROR "Nothing to do if both -DSHARED=OFF and -DSTATIC=OFF...") +endif() + +if(DEFINED SHARED_RAYLIB) + set(SHARED ${SHARED_RAYLIB}) + message(DEPRECATION "-DSHARED_RAYLIB is deprecated. Please use -DSHARED instead.") +endif() +if(DEFINED STATIC_RAYLIB) + set(STATIC ${STATIC_RAYLIB}) + message(DEPRECATION "-DSTATIC_RAYLIB is deprecated. Please use -DSTATIC instead.") endif() # Platform @@ -85,7 +94,7 @@ endif() if(MACOS_FATLIB) if (CMAKE_OSX_ARCHITECTURES) - message(FATAL_ERROR "User supplied -DCMAKE_OSX_ARCHITECTURES overrides BUILD_MACOS_FATLIB=ON") + message(FATAL_ERROR "User supplied -DCMAKE_OSX_ARCHITECTURES overrides -DMACOS_FATLIB=ON") else() SET(CMAKE_OSX_ARCHITECTURES "x86_64;i386") endif() @@ -94,7 +103,7 @@ endif() # Which platform? if(${PLATFORM} MATCHES "PLATFORM_DESKTOP") - if(${SHARED_RAYLIB}) + if(${SHARED}) add_library(${RAYLIB}_shared SHARED ${sources}) target_compile_definitions(${RAYLIB}_shared @@ -127,9 +136,9 @@ if(${PLATFORM} MATCHES "PLATFORM_DESKTOP") PUBLIC_HEADER DESTINATION include ) endif() - endif(${SHARED_RAYLIB}) + endif(${SHARED}) - if(${STATIC_RAYLIB}) + if(${STATIC}) add_library(${RAYLIB} STATIC ${sources}) target_compile_definitions(${RAYLIB} @@ -147,7 +156,7 @@ if(${PLATFORM} MATCHES "PLATFORM_DESKTOP") ARCHIVE DESTINATION lib PUBLIC_HEADER DESTINATION include ) - endif(${STATIC_RAYLIB}) + endif(${STATIC}) configure_file(../raylib.pc.in raylib.pc @ONLY) install(FILES ${CMAKE_BINARY_DIR}/release/raylib.pc DESTINATION lib/pkgconfig) -- cgit v1.2.3 From 988f5b78329f31c3107ec258e8ac3eb1358dee3b Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Fri, 16 Feb 2018 11:20:21 +0100 Subject: Add Builder project template --- project/Builder/README.md | 20 ++++++++++++++++++++ project/Builder/meson.build | 27 +++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 project/Builder/README.md create mode 100644 project/Builder/meson.build diff --git a/project/Builder/README.md b/project/Builder/README.md new file mode 100644 index 00000000..f816ebe5 --- /dev/null +++ b/project/Builder/README.md @@ -0,0 +1,20 @@ +# Builder project template + +This is a project template to be used with [GNOME Builder](https://raw.githubusercontent.com/jubalh/raymario/master/meson.build). +We use the [meson](https://raw.githubusercontent.com/jubalh/raymario/master/meson.build) build system here. + +We can compile our project via the command line: +``` +meson build +cd build +ninja +ninja install +``` + +Or can simply click on the `meson.build` file to open it with Builder. +Alternatively you can open Builder first and click on the `open` button and the left top. + +We added comments to the file to give you an idea which values you should edit. +For a full overview of options please check the [meson manual](http://mesonbuild.com/Manual.html). + +In the provided file we assume that the build file is located at the root folder of your project, and that all your sources are in a `src` subfolder. diff --git a/project/Builder/meson.build b/project/Builder/meson.build new file mode 100644 index 00000000..4908736c --- /dev/null +++ b/project/Builder/meson.build @@ -0,0 +1,27 @@ +# This file should be in the main folder of your project + +# Replace 'projectname' with the name of your project +# Replace '1.0' with its version +project('projectname', 'c', version: '1.0', + meson_version: '>= 0.39.1') + +# We want a C Compiler to be present +cc = meson.get_compiler('c') + +# Find dependencies +glfw_dep = dependency('glfw3') +gl_dep = dependency('gl') +openal_dep = dependency('openal') +m_dep = cc.find_library('m', required : false) +raylib_dep = cc.find_library('raylib', required : false) + +# List your source files here +source_c = [ + 'src/main.c', +] + +# Build executable +projectname = executable('projectname', + source_c, + dependencies : [ raylib_dep, glfw_dep, gl_dep, openal_dep, m_dep ], + install : true) -- cgit v1.2.3 From 6ebc3fd29a6a05b2d56e893e753125a4c14cf184 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Fri, 16 Feb 2018 11:23:02 +0100 Subject: Add core_basic_window project example for Builder --- project/Builder/examples/README.md | 1 + project/Builder/examples/meson.build | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 project/Builder/examples/README.md create mode 100644 project/Builder/examples/meson.build diff --git a/project/Builder/examples/README.md b/project/Builder/examples/README.md new file mode 100644 index 00000000..cba3aef5 --- /dev/null +++ b/project/Builder/examples/README.md @@ -0,0 +1 @@ +Open `meson.build` with Builder or run `meson build; cd build; ninja; ./core_basic_window` on the commandline to launch the example. diff --git a/project/Builder/examples/meson.build b/project/Builder/examples/meson.build new file mode 100644 index 00000000..ab81ca6c --- /dev/null +++ b/project/Builder/examples/meson.build @@ -0,0 +1,27 @@ +# This file should be in the main folder of your project + +# Replace 'projectname' with the name of your project +# Replace '1.0' with its version +project('core_basic_window', 'c', version: '1.0', + meson_version: '>= 0.39.1') + +# We want a C Compiler to be present +cc = meson.get_compiler('c') + +# Find dependencies +glfw_dep = dependency('glfw3') +gl_dep = dependency('gl') +openal_dep = dependency('openal') +m_dep = cc.find_library('m', required : false) +raylib_dep = cc.find_library('raylib', required : false) + +# List your source files here +source_c = [ + '../../../examples/core/core_basic_window.c', +] + +# Build executable +core_basic_window = executable('core_basic_window', + source_c, + dependencies : [ raylib_dep, glfw_dep, gl_dep, openal_dep, m_dep ], + install : true) -- cgit v1.2.3 From e0a3a51b753ae20727bac9191da9b62f32c92d83 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Fri, 16 Feb 2018 11:25:12 +0100 Subject: Builder project: Add note about examples --- project/Builder/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/project/Builder/README.md b/project/Builder/README.md index f816ebe5..1696e0d2 100644 --- a/project/Builder/README.md +++ b/project/Builder/README.md @@ -18,3 +18,6 @@ We added comments to the file to give you an idea which values you should edit. For a full overview of options please check the [meson manual](http://mesonbuild.com/Manual.html). In the provided file we assume that the build file is located at the root folder of your project, and that all your sources are in a `src` subfolder. + +Check out the `examples` directory for a simple example on how to use this template. +You can also look at [raymario](https://github.com/jubalh/raymario) for a slightly more complex example which also installs resource files. -- cgit v1.2.3 From 883ed20e7c40009f116334fc2b7cf747942c68f2 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Fri, 16 Feb 2018 11:53:04 +0100 Subject: Add note about glfw3 and openAL --- project/Builder/README.md | 3 +++ project/Builder/meson.build | 1 + 2 files changed, 4 insertions(+) diff --git a/project/Builder/README.md b/project/Builder/README.md index 1696e0d2..556806ab 100644 --- a/project/Builder/README.md +++ b/project/Builder/README.md @@ -21,3 +21,6 @@ In the provided file we assume that the build file is located at the root folder Check out the `examples` directory for a simple example on how to use this template. You can also look at [raymario](https://github.com/jubalh/raymario) for a slightly more complex example which also installs resource files. + +# Notice +The files provided link against glfw3 and openAL because the latest stable version of raylib is version 1.8, which still needs this. For later versions these two dependencies are not necessary anymore. diff --git a/project/Builder/meson.build b/project/Builder/meson.build index 4908736c..41b37fdc 100644 --- a/project/Builder/meson.build +++ b/project/Builder/meson.build @@ -9,6 +9,7 @@ project('projectname', 'c', version: '1.0', cc = meson.get_compiler('c') # Find dependencies +# glfw3 and openal are not needed for raylib > 1.8.0 glfw_dep = dependency('glfw3') gl_dep = dependency('gl') openal_dep = dependency('openal') -- cgit v1.2.3 From 50fc4f7164fad37a7c4e542475ccb93d0f4b05ca Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sat, 17 Feb 2018 21:23:45 +0100 Subject: Reviewed transmission mission game Support string replacing to generate newspaper headline ISSUE: UTF8 characters not supported when drawing to Image --- .../resources/fonts/Lora-BoldItalic.ttf | Bin 232472 -> 0 bytes games/transmission/resources/fonts/fontTitle.ttf | Bin 125972 -> 0 bytes .../resources/fonts/mom_typewritter.ttf | Bin 0 -> 125972 bytes games/transmission/resources/missions.txt | 6 +- games/transmission/screens/screen_ending.c | 132 +++++++++++++-------- games/transmission/screens/screen_title.c | 2 +- 6 files changed, 88 insertions(+), 52 deletions(-) delete mode 100644 games/transmission/resources/fonts/Lora-BoldItalic.ttf delete mode 100644 games/transmission/resources/fonts/fontTitle.ttf create mode 100644 games/transmission/resources/fonts/mom_typewritter.ttf diff --git a/games/transmission/resources/fonts/Lora-BoldItalic.ttf b/games/transmission/resources/fonts/Lora-BoldItalic.ttf deleted file mode 100644 index 19b03226..00000000 Binary files a/games/transmission/resources/fonts/Lora-BoldItalic.ttf and /dev/null differ diff --git a/games/transmission/resources/fonts/fontTitle.ttf b/games/transmission/resources/fonts/fontTitle.ttf deleted file mode 100644 index 13f5dc7d..00000000 Binary files a/games/transmission/resources/fonts/fontTitle.ttf and /dev/null differ diff --git a/games/transmission/resources/fonts/mom_typewritter.ttf b/games/transmission/resources/fonts/mom_typewritter.ttf new file mode 100644 index 00000000..13f5dc7d Binary files /dev/null and b/games/transmission/resources/fonts/mom_typewritter.ttf differ diff --git a/games/transmission/resources/missions.txt b/games/transmission/resources/missions.txt index 346e54e4..63569608 100644 --- a/games/transmission/resources/missions.txt +++ b/games/transmission/resources/missions.txt @@ -1,4 +1,4 @@ -# Total missions +# Total missions # NOTE: Missions follow the order of this file t 4 # ----------------------------------------------------------------- @@ -10,7 +10,7 @@ k oviparo # # Message to be coded # NOTE: Sensible words must be noted using @ -m El @presidente es visto en un @hotel acompañado de su @amante . +m El @presidente es visto en un @hotel acompañado de su @amante. # # Solution to mission # NOTE: Provide the correct solution nums, according to above words @@ -26,7 +26,7 @@ k roedor # # Message to be coded # NOTE: Sensible words must be noted using @ -m Un @ovni ha sido detectado en el @cielo del @pais . Preparaos para el ataque de un @alien . +m Un @ovni ha sido detectado en el @cielo del @pais . Preparaos para el ataque de un @alien. # # NOTE: Provide the correct solution nums, according to above words # WARNING: Always provide 8 values, use -1 for not used ones diff --git a/games/transmission/screens/screen_ending.c b/games/transmission/screens/screen_ending.c index e1fd6156..d9ed4696 100644 --- a/games/transmission/screens/screen_ending.c +++ b/games/transmission/screens/screen_ending.c @@ -29,7 +29,7 @@ #include #include -#define MAX_TITLE_CHAR 128 +#define MAX_TITLE_CHAR 256 #define MAX_SUBTITLE_CHAR 256 //---------------------------------------------------------------------------------- @@ -66,7 +66,12 @@ static int state = 0; static Mission *missions = NULL; -static bool showResults = false; +static char headline[MAX_TITLE_CHAR] = "\0"; + +SpriteFont fontNews; + +// String (const char *) replacement function +static char *StringReplace(char *orig, char *rep, char *with); //---------------------------------------------------------------------------------- // Ending Screen Functions Definition @@ -84,60 +89,43 @@ void InitEndingScreen(void) texBackground = LoadTexture("resources/textures/ending_background.png"); texVignette = LoadTexture("resources/textures/message_vignette.png"); - fxNews = LoadSound("resources/audio/fx_batman.ogg"); - // TODO: Check game results! missions = LoadMissions("resources/missions.txt"); int wordsCount = missions[currentMission].wordsCount; - TraceLog(LOG_WARNING, "Words count %i", wordsCount); - - char title[MAX_TITLE_CHAR] = "\0"; - //char subtitle[MAX_SUBTITLE_CHAR] = "\0"; - - char *ptrTitle = title; - int len = 0; + + strcpy(headline, missions[currentMission].msg); // Base headline + int len = strlen(headline); + // Remove @ from headline + // TODO: Also remove additional spaces + for (int i = 0; i < len; i++) + { + if (headline[i] == '@') headline[i] = ' '; + } + for (int i = 0; i < wordsCount; i++) { - if (messageWords[i].id == missions[currentMission].sols[i]) + if (messageWords[i].id != missions[currentMission].sols[i]) { - len = strlen(messageWords[i].text); - strncpy(ptrTitle, messageWords[i].text, len); - ptrTitle += len; + // WARNING: It fails if the last sentence word has a '.' after space + char *title = StringReplace(headline, messageWords[i].text, codingWords[messageWords[i].id]); - // title[len] = ' '; - // len++; - // ptrTitle++; - } - else - { - TraceLog(LOG_WARNING, "Coding word: %s", codingWords[messageWords[i].id]); - len = strlen(codingWords[messageWords[i].id]); - TraceLog(LOG_WARNING, "Lenght: %i", len); - strncpy(ptrTitle, codingWords[messageWords[i].id], len); - ptrTitle += len; + strcpy(headline, title); // Base headline updated - // title[len] = ' '; - // len++; - // ptrTitle++; + free(title); } } - ptrTitle = '\0'; - - //TraceLog(LOG_WARNING, "Titular: %s", title); + TraceLog(LOG_WARNING, "Titular: %s", headline); // Generate newspaper with title and subtitle Image imNewspaper = LoadImage("resources/textures/ending_newspaper.png"); - SpriteFont fontNews = LoadSpriteFontEx("resources/fonts/Lora-Bold.ttf", 82, 250, 0); - ImageDrawTextEx(&imNewspaper, (Vector2){ 50, 220 }, fontNews, "FRACASO EN LA GGJ18!", fontNews.baseSize, 0, DARKGRAY); + fontNews = LoadSpriteFontEx("resources/fonts/Lora-Bold.ttf", 32, 250, 0); + ImageDrawTextEx(&imNewspaper, (Vector2){ 50, 220 }, fontNews, headline, fontNews.baseSize, 0, DARKGRAY); - // TODO: Draw subtitle message - //ImageDrawTextEx(&imNewspaper, (Vector2){ 50, 210 }, fontNews, "SUBE LA ESCALERA!", fontNews.baseSize, 0, DARKGRAY); - texNewspaper = LoadTextureFromImage(imNewspaper); - UnloadSpriteFont(fontNews); + //UnloadSpriteFont(fontNews); UnloadImage(imNewspaper); } @@ -167,8 +155,6 @@ void UpdateEndingScreen(void) if (currentMission >= totalMissions) finishScreen = 2; else finishScreen = 1; } - - if (IsKeyPressed(KEY_SPACE)) showResults = !showResults; } // Ending Screen Draw logic @@ -181,16 +167,15 @@ void DrawEndingScreen(void) (Vector2){ (float)texNewspaper.width*scale/2, (float)texNewspaper.height*scale/2 }, rotation, WHITE); DrawTextureEx(texVignette, (Vector2){ 0, 0 }, 0.0f, 2.0f, WHITE); + + // Draw debug information + DrawTextEx(fontNews, headline, (Vector2){ 10, 10 }, fontNews.baseSize, 0, RAYWHITE); - if (showResults) + for (int i = 0; i < missions[currentMission].wordsCount; i++) { - for (int i = 0; i < missions[currentMission].wordsCount; i++) - { - if (messageWords[i].id == missions[currentMission].sols[i]) DrawText(messageWords[i].text, 10, 10 + 30*i, 20, GREEN); - else DrawText(codingWords[messageWords[i].id], 10, 10 + 30*i, 20, RED); - } + DrawText(codingWords[messageWords[i].id], 10, 60 + 30*i, 20, (messageWords[i].id == missions[currentMission].sols[i]) ? GREEN : RED); } - + if (state == 1) DrawButton("continuar"); } @@ -209,4 +194,55 @@ void UnloadEndingScreen(void) int FinishEndingScreen(void) { return finishScreen; -} \ No newline at end of file +} + +// String (const char *) replacement function +// NOTE: Internally allocated memory must be freed by the user (if return != NULL) +// https://stackoverflow.com/questions/779875/what-is-the-function-to-replace-string-in-c +static char *StringReplace(char *orig, char *rep, char *with) +{ + char *result; // the return string + char *ins; // the next insert point + char *tmp; // varies + int len_rep; // length of rep (the string to remove) + int len_with; // length of with (the string to replace rep with) + int len_front; // distance between rep and end of last rep + int count; // number of replacements + + // Sanity checks and initialization + if (!orig || !rep) return NULL; + + len_rep = strlen(rep); + if (len_rep == 0) return NULL; // Empty rep causes infinite loop during count + + if (!with) with = ""; // Replace with nothing if not provided + len_with = strlen(with); + + // Count the number of replacements needed + ins = orig; + for (count = 0; tmp = strstr(ins, rep); ++count) + { + ins = tmp + len_rep; + } + + tmp = result = malloc(strlen(orig) + (len_with - len_rep)*count + 1); + + if (!result) return NULL; // Memory could not be allocated + + // First time through the loop, all the variable are set correctly from here on, + // tmp points to the end of the result string + // ins points to the next occurrence of rep in orig + // orig points to the remainder of orig after "end of rep" + while (count--) + { + ins = strstr(orig, rep); + len_front = ins - orig; + tmp = strncpy(tmp, orig, len_front) + len_front; + tmp = strcpy(tmp, with) + len_with; + orig += len_front + len_rep; // move to next "end of rep" + } + + strcpy(tmp, orig); + + return result; +} diff --git a/games/transmission/screens/screen_title.c b/games/transmission/screens/screen_title.c index dc062069..a5ad0a84 100644 --- a/games/transmission/screens/screen_title.c +++ b/games/transmission/screens/screen_title.c @@ -71,7 +71,7 @@ void InitTitleScreen(void) texBackground = LoadTexture("resources/textures/title_background.png"); fxTyping = LoadSound("resources/audio/fx_typing.ogg"); - fontTitle = LoadSpriteFontEx("resources/fonts/fontTitle.ttf", 96, 0, 0); + fontTitle = LoadSpriteFontEx("resources/fonts/mom_typewritter.ttf", 96, 0, 0); titleSize = 44; transmissionPosition = (Vector2){519, 221}; -- cgit v1.2.3 From 4492a70a4bfc32f699932eaaddc09d8225963f42 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sun, 18 Feb 2018 18:07:57 +0100 Subject: Support UTF8 basic characters on ImageTextEx() Supported UTF8 range equivalent to [128..255] (80h..FFh) Exposed and renamed text function GetGlyphIndex() Renamed spriteFont parameter name to simply font Small security check on transmission mission ending screen --- games/transmission/screens/screen_ending.c | 2 +- src/raylib.h | 7 ++- src/text.c | 95 +++++++++++++++--------------- src/textures.c | 40 +++++++++++-- 4 files changed, 86 insertions(+), 58 deletions(-) diff --git a/games/transmission/screens/screen_ending.c b/games/transmission/screens/screen_ending.c index d9ed4696..e6ab3518 100644 --- a/games/transmission/screens/screen_ending.c +++ b/games/transmission/screens/screen_ending.c @@ -113,7 +113,7 @@ void InitEndingScreen(void) strcpy(headline, title); // Base headline updated - free(title); + if (title != NULL) free(title); } } diff --git a/src/raylib.h b/src/raylib.h index fba973d0..782dd4e5 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -948,19 +948,20 @@ RLAPI void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle dest RLAPI SpriteFont GetDefaultFont(void); // Get the default SpriteFont RLAPI SpriteFont LoadSpriteFont(const char *fileName); // Load SpriteFont from file into GPU memory (VRAM) RLAPI SpriteFont LoadSpriteFontEx(const char *fileName, int fontSize, int charsCount, int *fontChars); // Load SpriteFont from file with extended parameters -RLAPI void UnloadSpriteFont(SpriteFont spriteFont); // Unload SpriteFont from GPU memory (VRAM) +RLAPI void UnloadSpriteFont(SpriteFont font); // Unload SpriteFont from GPU memory (VRAM) // Text drawing functions RLAPI void DrawFPS(int posX, int posY); // Shows current FPS RLAPI void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font) -RLAPI void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, // Draw text using SpriteFont and additional parameters +RLAPI void DrawTextEx(SpriteFont font, const char* text, Vector2 position, // Draw text using SpriteFont and additional parameters float fontSize, int spacing, Color tint); // Text misc. functions RLAPI int MeasureText(const char *text, int fontSize); // Measure string width for default font -RLAPI Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, int spacing); // Measure string size for SpriteFont +RLAPI Vector2 MeasureTextEx(SpriteFont font, const char *text, float fontSize, int spacing); // Measure string size for SpriteFont RLAPI const char *FormatText(const char *text, ...); // Formatting of text with variables to 'embed' RLAPI const char *SubText(const char *text, int position, int length); // Get a piece of a text string +RLAPI int GetGlyphIndex(SpriteFont font, int character); // Returns index position for a unicode character on sprite font //------------------------------------------------------------------------------------ // Basic 3d Shapes Drawing Functions (Module: models) diff --git a/src/text.c b/src/text.c index 227992e6..2a05773c 100644 --- a/src/text.c +++ b/src/text.c @@ -90,11 +90,9 @@ static SpriteFont defaultFont; // Default font provided by raylib //---------------------------------------------------------------------------------- // Module specific Functions Declaration //---------------------------------------------------------------------------------- -static int GetCharIndex(SpriteFont font, int letter); - static SpriteFont LoadImageFont(Image image, Color key, int firstChar); // Load a Image font file (XNA style) #if defined(SUPPORT_FILEFORMAT_FNT) -static SpriteFont LoadBMFont(const char *fileName); // Load a BMFont file (AngelCode font file) +static SpriteFont LoadBMFont(const char *fileName); // Load a BMFont file (AngelCode font file) #endif #if defined(SUPPORT_FILEFORMAT_TTF) static SpriteFont LoadTTF(const char *fileName, int fontSize, int charsCount, int *fontChars); // Load spritefont from TTF data @@ -345,13 +343,13 @@ SpriteFont LoadSpriteFontEx(const char *fileName, int fontSize, int charsCount, } // Unload SpriteFont from GPU memory (VRAM) -void UnloadSpriteFont(SpriteFont spriteFont) +void UnloadSpriteFont(SpriteFont font) { // NOTE: Make sure spriteFont is not default font (fallback) - if (spriteFont.texture.id != GetDefaultFont().texture.id) + if (font.texture.id != GetDefaultFont().texture.id) { - UnloadTexture(spriteFont.texture); - free(spriteFont.chars); + UnloadTexture(font.texture); + free(font.chars); TraceLog(LOG_DEBUG, "Unloaded sprite font data"); } @@ -377,7 +375,7 @@ void DrawText(const char *text, int posX, int posY, int fontSize, Color color) // Draw text using SpriteFont // NOTE: chars spacing is NOT proportional to fontSize -void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, float fontSize, int spacing, Color tint) +void DrawTextEx(SpriteFont font, const char *text, Vector2 position, float fontSize, int spacing, Color tint) { int length = strlen(text); int textOffsetX = 0; // Offset between characters @@ -387,7 +385,7 @@ void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, float unsigned char letter; // Current character int index; // Index position in sprite font - scaleFactor = fontSize/spriteFont.baseSize; + scaleFactor = fontSize/font.baseSize; // NOTE: Some ugly hacks are made to support Latin-1 Extended characters directly // written in C code files (codified by default as UTF-8) @@ -397,7 +395,7 @@ void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, float if ((unsigned char)text[i] == '\n') { // NOTE: Fixed line spacing of 1.5 lines - textOffsetY += (int)((spriteFont.baseSize + spriteFont.baseSize/2)*scaleFactor); + textOffsetY += (int)((font.baseSize + font.baseSize/2)*scaleFactor); textOffsetX = 0; } else @@ -406,29 +404,29 @@ void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, float { // Support UTF-8 encoded values from [0xc2 0x80] -> [0xc2 0xbf](¿) letter = (unsigned char)text[i + 1]; - index = GetCharIndex(spriteFont, (int)letter); + index = GetGlyphIndex(font, (int)letter); i++; } else if ((unsigned char)text[i] == 0xc3) // UTF-8 encoding identification HACK! { // Support UTF-8 encoded values from [0xc3 0x80](À) -> [0xc3 0xbf](ÿ) letter = (unsigned char)text[i + 1]; - index = GetCharIndex(spriteFont, (int)letter + 64); + index = GetGlyphIndex(font, (int)letter + 64); i++; } - else index = GetCharIndex(spriteFont, (unsigned char)text[i]); + else index = GetGlyphIndex(font, (unsigned char)text[i]); if ((unsigned char)text[i] != ' ') { - DrawTexturePro(spriteFont.texture, spriteFont.chars[index].rec, - (Rectangle){ position.x + textOffsetX + spriteFont.chars[index].offsetX*scaleFactor, - position.y + textOffsetY + spriteFont.chars[index].offsetY*scaleFactor, - spriteFont.chars[index].rec.width*scaleFactor, - spriteFont.chars[index].rec.height*scaleFactor }, (Vector2){ 0, 0 }, 0.0f, tint); + DrawTexturePro(font.texture, font.chars[index].rec, + (Rectangle){ position.x + textOffsetX + font.chars[index].offsetX*scaleFactor, + position.y + textOffsetY + font.chars[index].offsetY*scaleFactor, + font.chars[index].rec.width*scaleFactor, + font.chars[index].rec.height*scaleFactor }, (Vector2){ 0, 0 }, 0.0f, tint); } - if (spriteFont.chars[index].advanceX == 0) textOffsetX += (int)(spriteFont.chars[index].rec.width*scaleFactor + spacing); - else textOffsetX += (int)(spriteFont.chars[index].advanceX*scaleFactor + spacing); + if (font.chars[index].advanceX == 0) textOffsetX += (int)(font.chars[index].rec.width*scaleFactor + spacing); + else textOffsetX += (int)(font.chars[index].advanceX*scaleFactor + spacing); } } } @@ -490,7 +488,7 @@ int MeasureText(const char *text, int fontSize) } // Measure string size for SpriteFont -Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, int spacing) +Vector2 MeasureTextEx(SpriteFont font, const char *text, float fontSize, int spacing) { int len = strlen(text); int tempLen = 0; // Used to count longer text line num chars @@ -499,8 +497,8 @@ Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, i float textWidth = 0; float tempTextWidth = 0; // Used to count longer text line width - float textHeight = (float)spriteFont.baseSize; - float scaleFactor = fontSize/(float)spriteFont.baseSize; + float textHeight = (float)font.baseSize; + float scaleFactor = fontSize/(float)font.baseSize; for (int i = 0; i < len; i++) { @@ -508,17 +506,17 @@ Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, i if (text[i] != '\n') { - int index = GetCharIndex(spriteFont, (int)text[i]); + int index = GetGlyphIndex(font, (int)text[i]); - if (spriteFont.chars[index].advanceX != 0) textWidth += spriteFont.chars[index].advanceX; - else textWidth += (spriteFont.chars[index].rec.width + spriteFont.chars[index].offsetX); + if (font.chars[index].advanceX != 0) textWidth += font.chars[index].advanceX; + else textWidth += (font.chars[index].rec.width + font.chars[index].offsetX); } else { if (tempTextWidth < textWidth) tempTextWidth = textWidth; lenCounter = 0; textWidth = 0; - textHeight += ((float)spriteFont.baseSize*1.5f); // NOTE: Fixed line spacing of 1.5 lines + textHeight += ((float)font.baseSize*1.5f); // NOTE: Fixed line spacing of 1.5 lines } if (tempLen < lenCounter) tempLen = lenCounter; @@ -533,6 +531,28 @@ Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, i return vec; } +// Returns index position for a unicode character on spritefont +int GetGlyphIndex(SpriteFont font, int character) +{ +#define UNORDERED_CHARSET +#if defined(UNORDERED_CHARSET) + int index = 0; + + for (int i = 0; i < font.charsCount; i++) + { + if (font.chars[i].value == character) + { + index = i; + break; + } + } + + return index; +#else + return (character - 32); +#endif +} + // Shows current FPS on top-left corner // NOTE: Uses default font void DrawFPS(int posX, int posY) @@ -559,27 +579,6 @@ void DrawFPS(int posX, int posY) // Module specific Functions Definition //---------------------------------------------------------------------------------- -static int GetCharIndex(SpriteFont font, int letter) -{ -#define UNORDERED_CHARSET -#if defined(UNORDERED_CHARSET) - int index = 0; - - for (int i = 0; i < font.charsCount; i++) - { - if (font.chars[i].value == letter) - { - index = i; - break; - } - } - - return index; -#else - return (letter - 32); -#endif -} - // Load an Image font file (XNA style) static SpriteFont LoadImageFont(Image image, Color key, int firstChar) { diff --git a/src/textures.c b/src/textures.c index 2772e246..ba0bad54 100644 --- a/src/textures.c +++ b/src/textures.c @@ -1374,6 +1374,8 @@ Image ImageTextEx(SpriteFont font, const char *text, float fontSize, int spacing { int length = strlen(text); int posX = 0; + int index; // Index position in sprite font + unsigned char character; // Current character Vector2 imSize = MeasureTextEx(font, text, font.baseSize, spacing); @@ -1389,13 +1391,39 @@ Image ImageTextEx(SpriteFont font, const char *text, float fontSize, int spacing for (int i = 0; i < length; i++) { - CharInfo letter = font.chars[(int)text[i] - 32]; - - ImageDraw(&imText, imFont, letter.rec, (Rectangle){ posX + letter.offsetX, - letter.offsetY, letter.rec.width, letter.rec.height }); + if ((unsigned char)text[i] == '\n') + { + // TODO: Support line break + } + else + { + if ((unsigned char)text[i] == 0xc2) // UTF-8 encoding identification HACK! + { + // Support UTF-8 encoded values from [0xc2 0x80] -> [0xc2 0xbf](¿) + character = (unsigned char)text[i + 1]; + index = GetGlyphIndex(font, (int)character); + i++; + } + else if ((unsigned char)text[i] == 0xc3) // UTF-8 encoding identification HACK! + { + // Support UTF-8 encoded values from [0xc3 0x80](À) -> [0xc3 0xbf](ÿ) + character = (unsigned char)text[i + 1]; + index = GetGlyphIndex(font, (int)character + 64); + i++; + } + else index = GetGlyphIndex(font, (unsigned char)text[i]); - if (letter.advanceX == 0) posX += letter.rec.width + spacing; - else posX += letter.advanceX + spacing; + CharInfo letter = font.chars[index]; + + if ((unsigned char)text[i] != ' ') + { + ImageDraw(&imText, imFont, letter.rec, (Rectangle){ posX + letter.offsetX, + letter.offsetY, letter.rec.width, letter.rec.height }); + } + + if (letter.advanceX == 0) posX += letter.rec.width + spacing; + else posX += letter.advanceX + spacing; + } } UnloadImage(imFont); -- cgit v1.2.3 From 0958904eac63a82b427575439de1d96a62d4f5cf Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sun, 18 Feb 2018 19:29:13 +0100 Subject: Added comments to review function ImageTextEx() --- src/textures.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/textures.c b/src/textures.c index ba0bad54..a571718b 100644 --- a/src/textures.c +++ b/src/textures.c @@ -1375,13 +1375,16 @@ Image ImageTextEx(SpriteFont font, const char *text, float fontSize, int spacing int length = strlen(text); int posX = 0; int index; // Index position in sprite font - unsigned char character; // Current character + unsigned char character; // Current character + // TODO: ISSUE: Measured text size does not seem to be correct... issue on ImageDraw() Vector2 imSize = MeasureTextEx(font, text, font.baseSize, spacing); TraceLog(LOG_DEBUG, "Text Image size: %f, %f", imSize.x, imSize.y); // NOTE: glGetTexImage() not available in OpenGL ES + // TODO: This is horrible, retrieving font texture from GPU!!! + // Define ImageFont struct? or include Image spritefont in SpriteFont struct? Image imFont = GetTextureData(font.texture); ImageColorTint(&imFont, tint); // Apply color tint to font -- cgit v1.2.3 From 7e32a627e88035c21cd16daddca128a9b6024de9 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 19 Feb 2018 00:03:24 +0100 Subject: Corrected path backslash --- templates/advance_game/Makefile | 2 +- templates/simple_game/Makefile | 2 +- templates/standard_game/Makefile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/advance_game/Makefile b/templates/advance_game/Makefile index 0ebeb52e..60739253 100644 --- a/templates/advance_game/Makefile +++ b/templates/advance_game/Makefile @@ -26,7 +26,7 @@ # Define required raylib variables # WARNING: To compile to HTML5, code must be redesigned to use emscripten.h and emscripten_set_main_loop() PLATFORM ?= PLATFORM_DESKTOP -RAYLIB_PATH = ..\.. +RAYLIB_PATH = ../.. PROJECT_NAME ?= advance_game # Default path for raylib on Raspberry Pi, if installed in different path, update it! diff --git a/templates/simple_game/Makefile b/templates/simple_game/Makefile index 23cd0619..2c9c3568 100644 --- a/templates/simple_game/Makefile +++ b/templates/simple_game/Makefile @@ -26,7 +26,7 @@ # Define required raylib variables # WARNING: To compile to HTML5, code must be redesigned to use emscripten.h and emscripten_set_main_loop() PLATFORM ?= PLATFORM_DESKTOP -RAYLIB_PATH ?= ..\.. +RAYLIB_PATH ?= ../.. PROJECT_NAME ?= simple_game # Default path for raylib on Raspberry Pi, if installed in different path, update it! diff --git a/templates/standard_game/Makefile b/templates/standard_game/Makefile index b3e9c82a..d596a6dc 100644 --- a/templates/standard_game/Makefile +++ b/templates/standard_game/Makefile @@ -26,7 +26,7 @@ # Define required raylib variables # WARNING: To compile to HTML5, code must be redesigned to use emscripten.h and emscripten_set_main_loop() PLATFORM ?= PLATFORM_DESKTOP -RAYLIB_PATH = ..\.. +RAYLIB_PATH = ../.. PROJECT_NAME ?= standard_game # Default path for raylib on Raspberry Pi, if installed in different path, update it! -- cgit v1.2.3