@ -102,7 +102,8 @@ static void UnloadExamplesData(rlExampleInfo *exInfo);
/ / Get text lines ( by line - breaks ' \n ' )
/ / WARNING : It does not copy text data , just returns line pointers
static const char * * GetTextLines ( const char * text , int * count ) ;
static char * * LoadTextLines ( const char * text , int * count ) ;
static void UnloadTextLines ( char * * text ) ;
/ / raylib example line info parser
/ / Parses following line format : core / core_basic_window ; ⭐ ️ ☆ ☆ ☆ ; 1.0 ; 1.0 ; " Ray " / @ raysan5
@ -333,11 +334,96 @@ int main(int argc, char *argv[])
/ / Edit : raylib / examples / README . md - - > Add new example
/ / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/ / TODO : Use [ examples_list . txt ] to update / regen README . md
/ / Look for " | 01 | "
/ / NOTE : Using [ examples_list . txt ] to update / regen README . md
/ / Lines format : | 01 | [ core_basic_window ] ( core / core_basic_window . c ) | < img src = " core/core_basic_window.png " alt = " core_basic_window " width = " 80 " > | ⭐ ️ ☆ ☆ ☆ | 1.0 | 1.0 | [ Ray ] ( https : / / github . com / raysan5 ) |
char * mdText = LoadFileText ( TextFormat ( " %s/README.md " , exBasePath ) ) ;
char * mdTextUpdated = ( char * ) RL_CALLOC ( 2 * 1024 * 1024 , 1 ) ; / / Updated examples . js copy , 2 MB
int mdListStartIndex = TextFindIndex ( mdText , " | 01 | " ) ;
int mdIndex = 0 ;
memcpy ( mdTextUpdated , mdText , mdListStartIndex ) ;
/ / NOTE : We keep a global examples counter
for ( int i = 0 , catCount = 0 , gCount = 0 ; i < MAX_EXAMPLE_CATEGORIES ; i + + )
{
/ / Every category includes some introductory text , as it is quite short , just copying it here
/ / NOTE : " core " text already placed in the file
if ( i = = 1 ) / / " shapes "
{
mdIndex + = sprintf ( mdTextUpdated + mdListStartIndex + mdIndex , " \n ### category: shapes \n \n " ) ;
mdIndex + = sprintf ( mdTextUpdated + mdListStartIndex + mdIndex ,
" Examples using raylib shapes drawing functionality, provided by raylib [shapes](../src/rshapes.c) module. \n \n " ) ;
}
else if ( i = = 2 ) / / " textures "
{
mdIndex + = sprintf ( mdTextUpdated + mdListStartIndex + mdIndex , " \n ### category: textures \n \n " ) ;
mdIndex + = sprintf ( mdTextUpdated + mdListStartIndex + mdIndex ,
" Examples using raylib textures functionality, including image/textures loading/generation and drawing, provided by raylib [textures](../src/rtextures.c) module. \n \n " ) ;
}
else if ( i = = 3 ) / / " text "
{
mdIndex + = sprintf ( mdTextUpdated + mdListStartIndex + mdIndex , " \n ### category: text \n \n " ) ;
mdIndex + = sprintf ( mdTextUpdated + mdListStartIndex + mdIndex ,
" Examples using raylib text functionality, including sprite fonts loading/generation and text drawing, provided by raylib [text](../src/rtext.c) module. \n \n " ) ;
}
else if ( i = = 4 ) / / " models "
{
mdIndex + = sprintf ( mdTextUpdated + mdListStartIndex + mdIndex , " \n ### category: models \n \n " ) ;
mdIndex + = sprintf ( mdTextUpdated + mdListStartIndex + mdIndex ,
" Examples using raylib models functionality, including models loading/generation and drawing, provided by raylib [models](../src/rmodels.c) module. \n \n " ) ;
}
else if ( i = = 5 ) / / " shaders "
{
mdIndex + = sprintf ( mdTextUpdated + mdListStartIndex + mdIndex , " \n ### category: shaders \n \n " ) ;
mdIndex + = sprintf ( mdTextUpdated + mdListStartIndex + mdIndex ,
" Examples using raylib shaders functionality, including shaders loading, parameters configuration and drawing using them (model shaders and postprocessing shaders). This functionality is directly provided by raylib [rlgl](../src/rlgl.c) module. \n \n " ) ;
}
else if ( i = = 6 ) / / " audio "
{
mdIndex + = sprintf ( mdTextUpdated + mdListStartIndex + mdIndex , " \n ### category: audio \n \n " ) ;
mdIndex + = sprintf ( mdTextUpdated + mdListStartIndex + mdIndex ,
" Examples using raylib audio functionality, including sound/music loading and playing. This functionality is provided by raylib [raudio](../src/raudio.c) module. Note this module can be used standalone independently of raylib. \n \n " ) ;
}
else if ( i = = 7 ) / / " others "
{
mdIndex + = sprintf ( mdTextUpdated + mdListStartIndex + mdIndex , " \n ### category: others \n \n " ) ;
mdIndex + = sprintf ( mdTextUpdated + mdListStartIndex + mdIndex ,
" Examples showing raylib misc functionality that does not fit in other categories, like standalone modules usage or examples integrating external libraries. \n \n " ) ;
}
if ( i > 0 )
{
/ / Table header required
mdIndex + = sprintf ( mdTextUpdated + mdListStartIndex + mdIndex , " | ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer | \n " ) ;
mdIndex + = sprintf ( mdTextUpdated + mdListStartIndex + mdIndex , " |----|----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------| \n " ) ;
}
rlExampleInfo * exCatList = LoadExamplesData ( exCollectionListPath , exCategories [ i ] , false , & catCount ) ;
for ( int x = 0 ; x < catCount ; x + + )
{
char stars [ 16 ] = { 0 } ;
for ( int s = 0 ; s < 4 ; s + + )
{
if ( s < exCatList [ x ] . stars ) strcpy ( stars + 3 * s , " ⭐️ " ) ;
else strcpy ( stars + 3 * s , " ☆ " ) ;
}
mdIndex + = sprintf ( mdTextUpdated + mdListStartIndex + mdIndex ,
TextFormat ( " | %02i | [%s](%s/%s.c) | <img src= \" %s/%s.png \" alt= \" %s \" width= \" 80 \" > | %s | %.1f | %.1f | [%s](https://github.com/%s) | \n " ,
gCount + 1 , exCatList [ x ] . name , exCatList [ x ] . category , exCatList [ x ] . name , exCatList [ x ] . category , exCatList [ x ] . name , exCatList [ x ] . name ,
stars , exCatList [ x ] . verCreated , exCatList [ x ] . verUpdated , exCatList [ x ] . author , exCatList [ x ] . authorGitHub + 1 ) ) ;
gCount + + ;
}
UnloadExamplesData ( exCatList ) ;
}
/ / Save updated file
SaveFileText ( TextFormat ( " %s/README.md " , exBasePath ) , mdTextUpdated ) ;
UnloadFileText ( mdText ) ;
RL_FREE ( mdTextUpdated ) ;
/ / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/ / Create : raylib / projects / VS2022 / examples / < category > _example_name . vcxproj
@ -356,7 +442,7 @@ int main(int argc, char *argv[])
/ / Edit : raylib . com / common / examples . js - - > Add new example
/ / NOTE : Entries format : exampleEntry ( ' ⭐ ️ ☆ ☆ ☆ ' , ' core ' , ' basic_window ' ) ,
/ / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/*
char * jsText = LoadFileText ( TextFormat ( " %s/../common/examples.js " , exWebPath ) ) ;
char * jsTextUpdated = ( char * ) RL_CALLOC ( 2 * 1024 * 1024 , 1 ) ; / / Updated examples . js copy , 2 MB
@ -395,7 +481,6 @@ int main(int argc, char *argv[])
{
jsIndex + = sprintf ( jsTextUpdated + exListStartIndex + jsIndex ,
TextFormat ( " exampleEntry('%s', '%s', '%s'), \n " , stars , exCatList [ x ] . category , exCatList [ x ] . name + strlen ( exCatList [ x ] . category ) + 1 ) ) ;
}
}
@ -409,7 +494,7 @@ int main(int argc, char *argv[])
SaveFileText ( TextFormat ( " %s/../common/examples.js " , exWebPath ) , jsTextUpdated ) ;
UnloadFileText ( jsText ) ;
RL_FREE ( jsTextUpdated ) ;
*/
/ / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/ / Recompile example ( on raylib side )
@ -549,21 +634,21 @@ static rlExampleInfo *LoadExamplesData(const char *fileName, const char *categor
if ( text ! = NULL )
{
int lineCount = 0 ;
const char * * linePtr s = Get TextLines( text , & lineCount ) ;
const char * * lines = Load TextLines( text , & lineCount ) ;
for ( int i = 0 ; i < lineCount ; i + + )
{
/ / Basic validation for lines start categories
if ( ( linePtr s [ i ] [ 0 ] ! = ' # ' ) & &
( ( linePtr s [ i ] [ 0 ] = = ' c ' ) | | / / core
( linePtr s [ i ] [ 0 ] = = ' s ' ) | | / / shapes , shaders
( linePtr s [ i ] [ 0 ] = = ' t ' ) | | / / textures , text
( linePtr s [ i ] [ 0 ] = = ' m ' ) | | / / models
( linePtr s [ i ] [ 0 ] = = ' a ' ) | | / / audio
( linePtr s [ i ] [ 0 ] = = ' o ' ) ) ) / / others
if ( ( lines [ i ] [ 0 ] ! = ' # ' ) & &
( ( lines [ i ] [ 0 ] = = ' c ' ) | | / / core
( lines [ i ] [ 0 ] = = ' s ' ) | | / / shapes , shaders
( lines [ i ] [ 0 ] = = ' t ' ) | | / / textures , text
( lines [ i ] [ 0 ] = = ' m ' ) | | / / models
( lines [ i ] [ 0 ] = = ' a ' ) | | / / audio
( lines [ i ] [ 0 ] = = ' o ' ) ) ) / / others
{
rlExampleInfo info = { 0 } ;
int result = ParseExampleInfoLine ( linePtr s [ i ] , & info ) ;
int result = ParseExampleInfoLine ( lines [ i ] , & info ) ;
if ( result = = 1 ) / / Success on parsing
{
if ( strcmp ( category , " ALL " ) = = 0 )
@ -655,34 +740,37 @@ static int FileRemove(const char *fileName)
return result ;
}
/ / Get text lines ( by line - breaks ' \n ' )
/ / WARNING : It does not copy text data , just returns line pointers
static const char * * GetTextLines ( const char * text , int * count )
/ / Load text lines
static char * * LoadTextLines ( const char * text , int * count )
{
# define MAX_TEXT_LINE_PTRS 512
static const char * linePtrs [ MAX_TEXT_LINE_PTRS ] = { 0 } ;
for ( int i = 0 ; i < MAX_TEXT_LINE_PTRS ; i + + ) linePtrs [ i ] = NULL ; / / Init NULL pointers to substrings
# define MAX_TEXT_LINES 512
# define MAX_TEXT_LINE_LEN 256
char * * lines = ( char * * ) RL_CALLOC ( MAX_TEXT_LINES , sizeof ( char * ) ) ;
for ( int i = 0 ; i < MAX_TEXT_LINES ; i + + ) lines [ i ] = ( char * ) RL_CALLOC ( MAX_TEXT_LINE_LEN , 1 ) ;
int textSize = ( int ) strlen ( text ) ;
int k = 0 ;
linePtrs [ 0 ] = text ;
int len = 0 ;
* count = 1 ;
for ( int i = 0 , k = 0 ; ( i < textSize ) & & ( * count < MAX_TEXT_LINE_PTRS ) ; i + + )
for ( int i = 0 , len = 0 ; ( i < textSize ) & & ( k < MAX_TEXT_LINES ) ; i + + )
{
if ( text [ i ] = = ' \n ' )
{
k + + ;
linePtrs [ k ] = & text [ i + 1 ] ; / / WARNING : next value is valid ?
strncpy ( lines [ k ] , & text [ i - len ] , len ) ;
len = 0 ;
o">* count + = 1 ;
n">k + + ;
}
else len + + ;
}
return linePtrs ;
* count + = k ;
return lines ;
}
/ / Unload text lines
static void UnloadTextLines ( char * * lines )
{
for ( int i = 0 ; i < MAX_TEXT_LINES ; i + + ) RL_FREE ( lines [ i ] ) ;
RL_FREE ( lines ) ;
}
/ / raylib example line info parser
@ -692,7 +780,7 @@ static int ParseExampleInfoLine(const char *line, rlExampleInfo *entry)
# define MAX_EXAMPLE_INFO_LINE_LEN 512
char temp [ MAX_EXAMPLE_INFO_LINE_LEN ] = { 0 } ;
strncpy ( temp , line , MAX_EXAMPLE_INFO_LINE_LEN ) ; / / WARNING : Copy is needed because strtok ( ) modifies string , adds ' \0 '
strncpy ( temp , line , MAX_EXAMPLE_INFO_LINE_LEN ) ;
temp [ MAX_EXAMPLE_INFO_LINE_LEN - 1 ] = ' \0 ' ; / / Ensure null termination
int tokenCount = 0 ;
@ -721,10 +809,10 @@ static int ParseExampleInfoLine(const char *line, rlExampleInfo *entry)
entry - > verCreated = strtof ( tokens [ 3 ] , NULL ) ;
entry - > verUpdated = strtof ( tokens [ 4 ] , NULL ) ;
/ / Get author and github
t">char * quote1 = strchr ( tokens [ 5 ] , ' " ' ) ;
t">char * quote2 = quote1 ? strchr ( quote1 + 1 , ' " ' ) o">: NULL ;
k">if ( quote1 & & quote2 ) strcpy ( entry - > author , quote1 + 1 ) ;
/ / Get author and github
">if ( tokens [ 5 ] [ 0 ] = = ' " ' ) tokens [ 5 ] + = 1 ;
">if ( tokens [ 5 ] [ strlen ( tokens [ 5 ] ) - 1 ] = = ' " ' ) n">tokens [ 5 ] [ strlen ( tokens [ 5 ] ) - 1 ] = ' \0 ' ;
n">strcpy ( entry - > author , tokens [ 5 ] ) ;
strcpy ( entry - > authorGitHub , tokens [ 6 ] ) ;
return 1 ;