Skip to content

Instantly share code, notes, and snippets.

@SemanticDevice
Created April 30, 2020 19:13
Show Gist options
  • Save SemanticDevice/5ada98eae9b9735c1867514f0881b957 to your computer and use it in GitHub Desktop.
Save SemanticDevice/5ada98eae9b9735c1867514f0881b957 to your computer and use it in GitHub Desktop.
/**********************************************************************************************
*
* raylib 32x32 game/demo competition
*
* Competition consist in developing a videogame in a 32x32 pixels screen size.
*
* RULES:
*
* 1) Use only raylib (and included libraries), no external libraries allowed
* 2) The submission should consist of just one source file
* 3) Render your game/demo to a 32x32 pixels render texture,
* show what you could do with a 32x32 RGB LED matrix!
* 4) No external resources, you CAN only create them programmatically,
* 5) Game/demo can be 2D or 3D, choose wisely
* 5) Shaders (if used) should be included in the source as string (char *)
* and loaded with LoadShaderCode()
* 6) Code must compile and execute in PLATFORM_DESKTOP (Windows, Linux, macOS)
*
*
* LICENSE: zlib/libpng
*
* Copyright (c) 2020 <TODO: participant_name> (<TODO: participant_github_name>)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose, including commercial
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not claim that you
* wrote the original software. If you use this software in a product, an acknowledgment
* in the product documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
* as being the original software.
*
* 3. This notice may not be removed or altered from any source distribution.
*
**********************************************************************************************/
#include <stdbool.h>
#include "raylib.h"
#include "raymath.h"
#define max(a, b) ((a)>(b)? (a) : (b))
#define min(a, b) ((a)<(b)? (a) : (b))
const int windowWidth = 512; // NOTE: Game will be scaled x16
const int windowHeight = 512;
const int gameScreenWidth = 32;
const int gameScreenHeight = 32;
int main(void)
{
SetTraceLogLevel(LOG_DEBUG);
SetConfigFlags(FLAG_VSYNC_HINT);
InitWindow(windowWidth, windowHeight, "DOOM Fire Effect");
// Render texture initialization, used to hold the rendering
RenderTexture2D target = LoadRenderTexture(gameScreenWidth, gameScreenHeight);
SetTextureFilter(target.texture, FILTER_POINT); // Texture scale filter to use!
// ------------ YOUR CODE here -------------
// NOTE: You don't need to use 3D! (no extra points!)
Camera camera = { 0 };
camera.position = (Vector3){ 0.0f, 1.0f, 2.0f };
camera.target = (Vector3){ 0.0f, 0.0f, 0.0f };
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
camera.fovy = 45.0f;
camera.type = CAMERA_PERSPECTIVE;
// Generate torus mesh
Mesh mesh = GenMeshTorus(0.5f, 1.0f, 16, 32);
Model model = LoadModelFromMesh(mesh);
// Checked texture for the torus
Image imChecked = GenImageChecked(16, 16, 4, 4, RED, WHITE);
Texture texChecked = LoadTextureFromImage(imChecked);
UnloadImage(imChecked);
// Assign generated checked texture to model texture
model.materials[0].maps[MAP_DIFFUSE].texture = texChecked;
Vector3 angle = { 0 };
int frameCount = 0;
double nowSec = GetTime();
double prevUpdateSec = 0.0;
double dt = 0.0;
double cursorLastUpdateSec = 0.0;
bool cursorIsOn = false;
Color hmap[37] = {
{0x07,0x07,0x07,0xff},
{0x1f,0x07,0x07,0xff},
{0x2f,0x0f,0x07,0xff},
{0x47,0x0f,0x07,0xff},
{0x57,0x17,0x07,0xff},
{0x67,0x1f,0x07,0xff},
{0x77,0x1f,0x07,0xff},
{0x8f,0x27,0x07,0xff},
{0x9f,0x2f,0x07,0xff},
{0xaf,0x3f,0x07,0xff},
{0xbf,0x47,0x07,0xff},
{0xc7,0x47,0x07,0xff},
{0xdf,0x4f,0x07,0xff},
{0xdf,0x57,0x07,0xff},
{0xdf,0x57,0x07,0xff},
{0xd7,0x5f,0x07,0xff},
{0xd7,0x67,0x0f,0xff},
{0xcf,0x6f,0x0f,0xff},
{0xcf,0x77,0x0f,0xff},
{0xcf,0x7f,0x0f,0xff},
{0xcf,0x87,0x17,0xff},
{0xc7,0x87,0x17,0xff},
{0xc7,0x8f,0x17,0xff},
{0xc7,0x97,0x1f,0xff},
{0xbf,0x9f,0x1f,0xff},
{0xbf,0x9f,0x1f,0xff},
{0xbf,0xa7,0x27,0xff},
{0xbf,0xa7,0x27,0xff},
{0xbf,0xaf,0x2f,0xff},
{0xb7,0xaf,0x2f,0xff},
{0xb7,0xb7,0x2f,0xff},
{0xb7,0xb7,0x37,0xff},
{0xcf,0xcf,0x6f,0xff},
{0xdf,0xdf,0x9f,0xff},
{0xef,0xef,0xc7,0xff},
{0xff,0xff,0xff,0xff},
};
const unsigned int FIRE_WIDTH = 32;
const unsigned int FIRE_HEIGHT = 24;
int firePixels[FIRE_WIDTH][FIRE_HEIGHT];
double fireLastUpdateSec = 0.0;
const double FIRE_UPDATE_SEC = 0.040;
for (int x = 0; x < FIRE_WIDTH; x++) {
for (int y = 0; y < FIRE_HEIGHT - 1; y++) {
firePixels[x][y] = 0;
}
}
for (int x = 0; x < FIRE_WIDTH; x++) {
firePixels[x][FIRE_HEIGHT-1] = 36;
}
// ------------ end of YOUR CODE ------------------
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
frameCount++;
nowSec = GetTime();
dt = nowSec - prevUpdateSec;
prevUpdateSec = nowSec;
if (nowSec - cursorLastUpdateSec > 1.0)
{
cursorIsOn = !cursorIsOn;
cursorLastUpdateSec = nowSec;
}
if (nowSec - fireLastUpdateSec > FIRE_UPDATE_SEC) {
fireLastUpdateSec = nowSec;
for (int x = 0; x < FIRE_WIDTH; x++) {
for (int y = 0; y < FIRE_HEIGHT - 1; y++) {
unsigned int horizShiftIdx = x + GetRandomValue(0,2);
if (horizShiftIdx >= FIRE_WIDTH) {
horizShiftIdx -= FIRE_WIDTH;
}
firePixels[x][y] = firePixels[horizShiftIdx][y+1] - GetRandomValue(0,6);
if (firePixels[x][y] < 0) {
firePixels[x][y] = 0;
}
}
}
}
// Compute required framebuffer scaling
float scale = min((float)GetScreenWidth()/gameScreenWidth, (float)GetScreenHeight()/gameScreenHeight);
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(hmap[0]);
// Draw everything in the render texture, note this will not be rendered on screen, yet
BeginTextureMode(target);
ClearBackground(hmap[0]); // Clear render texture background color
// ------------ YOUR CODE here -------------
#ifdef SHELL_W_CURSOR
DrawTextEx(GetFontDefault(), ">", (Vector2){ 0, 0 }, GetFontDefault().baseSize, 1, (Color){ 0, 255, 255, 255 });
if(cursorIsOn)
{
DrawLineEx((Vector2){4,7}, (Vector2){8,7}, 1, (Color){ 0, 255, 255, 255 });
}
#endif // SHELL_W_CURSOR
for(int x = 0; x < FIRE_WIDTH; x++)
{
for(int y = 0; y < FIRE_HEIGHT; y++)
{
DrawPixel(x, y + 32 - FIRE_HEIGHT + 1, hmap[firePixels[x][y]]);
}
}
// ------------ end of YOUR CODE ------------------
EndTextureMode();
// Draw render texture to window, properly scaled
DrawTexturePro(target.texture, (Rectangle){ 0.0f, 0.0f, (float)target.texture.width, (float)-target.texture.height },
(Rectangle){ (GetScreenWidth() - ((float)gameScreenWidth*scale))*0.5, (GetScreenHeight() - ((float)gameScreenHeight*scale))*0.5,
(float)gameScreenWidth*scale, (float)gameScreenHeight*scale }, (Vector2){ 0, 0 }, 0.0f, WHITE);
// Draw the grid like "stencil" is drawn over the squares to make them look not at all like LEDs!
for (int x = 0; x < GetScreenWidth(); x += 16) DrawRectangle(x, 0, 4, GetScreenHeight(), BLACK);
for (int y = 0; y < GetScreenHeight(); y += 16) DrawRectangle(0, y, GetScreenWidth(), 4, BLACK);
EndDrawing();
//--------------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadRenderTexture(target); // Unload render texture
UnloadTexture(texChecked);
UnloadModel(model);
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment