Merge pull request #474 from raysan5/develop

Integrate develop branch (LAST INTEGRATION)
This commit is contained in:
Ray 2018-02-19 12:08:35 +01:00 committed by GitHub
commit f6231aa8b6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 281 additions and 123 deletions

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -29,7 +29,7 @@
#include <string.h>
#include <stdlib.h>
#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++;
if (title != NULL) 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;
}
}
// 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;
}

View File

@ -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};

26
project/Builder/README.md Normal file
View File

@ -0,0 +1,26 @@
# 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.
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.

View File

@ -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.

View File

@ -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)

View File

@ -0,0 +1,28 @@
# 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
# glfw3 and openal are not needed for raylib > 1.8.0
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)

View File

@ -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)

View File

@ -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)

View File

@ -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)
{

View File

@ -1374,12 +1374,17 @@ 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
// 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
@ -1389,13 +1394,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);

View File

@ -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!

View File

@ -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!

View File

@ -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!