Raylib Hacking: cUstom Logs!
Make custom logs for Raylib
Go to
for personalized 1 on 1 tutoring in programming in bug bounty!
Hello, raylib enthusiasts! Today, I'm excited to share a custom logging example that I created. This example showcases how to implement a custom logging mechanism in raylib, providing a more tailored and informative logging experience.
I've been deeply immersed in working with raylib for my upcoming game project, a roguelike titled "project.rpg." This game is a labor of love, with art beautifully crafted by Krishna Palacio, and it's early in development but already showing a lot of promise. I chose raylib for its simplicity and power, which has allowed me to focus on bringing my creative vision to life without getting bogged down by complex frameworks. The game features a help menu accessible with a simple "?" shortcut, and it's designed to be played in short, intense sessions, perfect for a quick escape into a fantasy world. You can expect updates regularly as I continue to refine and expand the game, so stay tuned!
/********************************************************************************************* raylib example - Custom logging** Copyright (c) 2025 Michael Steven Bell Jr. (@darkmage666)*********************************************************************************************/#include "raylib.h"#include <stdio.h> // Required for: fopen(), fclose(), fputc(), fwrite(), printf(), fprintf(), funopen()#include <time.h> // Required for: time_t, tm, time(), localtime(), strftime()// Custom logging functionvoid CustomLog(int msgType, const char *text, va_list args){ char timeStr[64] = { 0 }; time_t now = time(NULL); struct tm *tm_info = localtime(&now); strftime(timeStr, sizeof(timeStr), "%Y-%m-%d %H:%M:%S", tm_info); printf("[%s] ", timeStr); switch (msgType) { case LOG_INFO: printf("[INFO] : "); break; case LOG_ERROR: printf("[ERROR]: "); break; case LOG_WARNING: printf("[WARN] : "); break; case LOG_DEBUG: printf("[DEBUG]: "); break; default: break; } vprintf(text, args); printf("\n");}int main(void){ const int screenWidth = 800; const int screenHeight = 450; SetTraceLogCallback(CustomLog); InitWindow(screenWidth, screenHeight, "custom logging"); SetTargetFPS(60); // Set our game to run at 60 frames-per-second while (!WindowShouldClose()) { BeginDrawing(); ClearBackground(RAYWHITE); DrawText("Check out the console output to see the custom logger in action!", 60, 200, 20, LIGHTGRAY); EndDrawing(); } CloseWindow(); return 0;}```Let's break down the code step by step and understand what's happening under the hood.
First, let's examine the header files that I included at the beginning of the code:
```c
#include "raylib.h"
#include <time.h>
#include <stdio.h>
```
raylib.h: This is the main header file for raylib, which provides all the necessary functions and definitions to work with the library.
stdio.h: I included this standard input-output header file to use functions like printf for outputting log messages to the console.
time.h: This header file is included to work with time and date functions, which are essential for timestamping our log messages.
```c
void CustomLog(int msgType, const char *text, va_list args)
{
char timeStr[64] = { 0 };
time_t now = time(NULL);
struct tm *tm_info = localtime(&now);
strftime(timeStr, sizeof(timeStr), "%Y-%m-%d %H:%M:%S", tm_info);
printf("[%s] ", timeStr);
switch (msgType)
{
case LOG_INFO: printf("[INFO] : "); break;
case LOG_ERROR: printf("[ERROR]: "); break;
case LOG_WARNING: printf("[WARN] : "); break;
case LOG_DEBUG: printf("[DEBUG]: "); break;
default: break;
}
vprintf(text, args);
printf("\n");
}
```
I started by generating a timestamp using the current local time. The time() function gets the current calendar time, and localtime() converts it to a tm structure representing the local time. Then, I used the strftime() function to format this time into a human-readable string, which I printed to the console.
Next, I handled the message type by using a switch statement on the msgType parameter. Depending on the value of msgType, I printed a corresponding tag (e.g., [INFO], [ERROR]) to the console. This helps categorize the log messages and makes it easier to identify the severity or type of each log entry.
Finally, I used the vprintf() function to print the formatted message passed as text and args. This allows for variable arguments to be handled correctly. I ended the function by printing a newline character to ensure each log message appears on a new line.
Now, let's look at the main function, where the magic happens. I started the initialization phase by defining the screen width and height as constants, setting the resolution of the window. Then, I set my custom logger by calling SetTraceLogCallback with my CustomLog function. This tells raylib to use my custom logger for all log messages.
I initialized the window with the specified dimensions and title using the InitWindow function. To ensure smooth performance, I set the target frames per second for the game loop using SetTargetFPS.
The main game loop is where the application's logic and rendering occur. The loop continues to run until the window close button is pressed or the ESC key is detected.
```c
while (!WindowShouldClose())
{
// Update
// TODO: Update your variables here
// Draw
BeginDrawing();
ClearBackground(RAYWHITE);
DrawText("Check out the console output to see the custom logger in action!", 60, 200, 20, LIGHTGRAY);
EndDrawing();
}
```
In the update phase, you would typically update your game variables, handle input, and perform any necessary calculations. For now, it's a placeholder for future updates.
In the draw phase, I bracketed the drawing code with BeginDrawing and EndDrawing functions to ensure that all rendering commands are executed between these calls. I set the background color to RAYWHITE using ClearBackground and rendered a message on the screen using DrawText. This message instructs the user to check the console for log output.
My custom logging example for raylib provides a clear and informative way to implement tailored logging in your raylib applications. By following this example, you can gain a deeper understanding of how to work with raylib's logging mechanisms and create more informative and debug-friendly applications. Happy coding!
