Skip to content

Pure C cross-platform hot-reloading software-rendering window + api

License

Notifications You must be signed in to change notification settings

takeiteasy/fun-with-pixels

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

66 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Fun With Pixels

Warning

Work in progress, see TODO section. Everything works, but features need adding.

Fun With Pixels (fwp) is a cross-platform hot-reloading software-rendering enviroment for C, designed for quick experiments and testing. Edit your C code, rebuild and see the changes in real-time!

If you would like to try it out, see the setting up section. Also included is a utility library pb that can function independently from the fwp program. If you're interested in that, see the pb section.

Preview

Usage

 usage: fwp -p [path] [options]

 fun-with-pixels  Copyright (C) 2024  George Watson
 This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
 This is free software, and you are welcome to redistribute it
 under certain conditions; type `show c' for details.

  Options:
      -w/--width     Window width [default: 640]
      -h/--height    Window height [default: 480]
      -t/--title     Window title [default: "fwp"]
      -r/--resizable Enable resizable window
      -a/--top       Enable window always on top
      -p/--path      Path the dynamic library [required]
      -u/--usage     Display this message

Setting up

To achieve hot-reloading in C, all the code that is to be reloaded is built as a dynamic library. The symbols are loaded from the library and updated by the fwp executable; which remains running.

To make it easy, the user's code is put into a scene. Below is a barebones example of how to setup a scene. Look at the example and read the comments.

// Firstly include the fwp header, which contains everything we need
#include "fwp.h"
#include <stdlib.h> // malloc

// A fwpState should be defined in each scene. This structure can contain whatever variables and types you want, but it must be defined like this. Do not typedef the struct definition, as it is already typedef'd in fwp.h
struct fwpState {
    pbColor clearColor;
};

static fwpState* init(void) {
    // Called once when the program first starts
    // You must always create an instance of your fwpState definition
    // It must be allocated on the stack, not the heap
    // This object will be be used to keep track of things between reloads
    fwpState *state = malloc(sizeof(fwpState));
    state->clearColor = RGB(255, 0, 0);
    // Return your fwpState so fwp can keep track of it
    return state;
}

static void deinit(fwpState *state) {
    // Only called when the program is exiting
    if (state)
        free(state);
}

static void reload(fwpState *state) {
    // Called when the dynamic has been updated + reloaded
    // Here we change the `clearColor` field in our state to blue
    // If you rebuild the library, the screen will chang from red
    // to blue! Magic!
    state->clearColor = RGB(0, 0, 255);
}

static void unload(fwpState *state) {
    // Called when dynamic library has been unloaded
}

static int event(fwpState *state, pbEvent *e) {
    // Called on window event
    return 1;
}

static int tick(fwpState *state, pbImage *pbo, double delta) {
    // Called every frame, this is your update callback
    pbImageFill(pbo, state->clearColor);
    return 1;
}

// So fwp knows where your callbacks are a `scene` definition must be made
// The definition should be always be called scene. If the name changes fwp
// won't know where to look!
EXPORT const fwpScene scene = {
    .init = init,
    .deinit = deinit,
    .reload = reload,
    .unload = unload,
    .event = event,
    .tick = tick
};

Now you have your scene file, you will have to build it as a dynamic library. Make sure to link the necessary files. Below is an example of building on MacOS, please see the Makefile to see how to build on your platform.

clang -shared -fpic [scene file].c src/pb_cocoa.c src/rng.c -framework Cocoa -o scene.dylib

Now you have your dynamic library, you can run:

fwp -p scene.dylib

Provided you haven't changed the example, the window should appear and display a red background. If you now rebuild the scene with the same command as before, the screen will change to blue! That's about it really.

pb

If you're interested in using pb as a standalone library, it's very easy. It will be a similar process to before.

pb currently supports 4 different backends; Windows (Win32api), MacOS (Cocoa), *nix (X11) and WASM (Emscripten). Each backend has a different system library or dependency that you will need to link. Feel free to request or submit a pull request for other backends.

#include "pb.h"

int main(int argc, const char *argv[]) {
    // Initalize a new window titled "hello!"
    pbBegin(640, 480, "hello!", 0);
    // Create an image for the framebuffer
    pbImage *fb = pbImageNew(640, 480);
    // Loop while the window is open + poll events
    while (pbPoll()) {
        // Fill the image buffer red
        pbImageFill(fb, RGB(255, 0, 0));
        // Flush the image to the window's framebuffer
        pbFlush(fb);
    }
    // Clean up
    pbEnd();
    return 0;
}

And to build the executable:

clang -Ideps -Isrc [source file].c src/pb_cocoa.c -framework Cocoa -o [your executable]

TODO

  • Frame timing + limiting
  • Documentation + some examples
  • Image loading + saving (stb_image.h + stb_image_write.h + qoi.h)
  • ANSI escape parser for text rendering
  • GIF support (gif_load.h + msf_gif.h)
  • TTF loading + rendering (stb_truetype.h)

Dependencies

License

fun-with-pixels is a hot-reloadable software-rendering library

Copyright (C) 2024  George Watson

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

About

Pure C cross-platform hot-reloading software-rendering window + api

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published