Lerc 8 days ago

This has popped up because

Microui+fenster=Small GUI https://news.ycombinator.com/item?id=41477446

Was posted in the last day.

In that thread I suggested that API compatibility would be the way to go for more esoteric platforms, Since there's already comments here about BSD and Android targets.

All you need is

    struct fenster {
      const char *title; /* window title */
      const int width; /* window width */
      const int height; /* window height */
      uint32_t *buf; /* window pixels, 24-bit RGB, row by row, pixel by pixel */
      int keys[256]; /* keys are mostly ASCII, but arrows are 17..20 */
      int mod;       /* mod is 4 bits mask, ctrl=1, shift=2, alt=4, meta=8 */
      int x;         /* mouse X coordinate */
      int y;         /* mouse Y coordinate */
      int mouse;     /* 0 = no buttons pressed, 1 = left button pressed */
    };

    int fenster_open(struct fenster *f)
    int fenster_loop(struct fenster *f)
    void fenster_close(struct fenster *f) 
    void fenster_sleep(int ms)
    int64_t fenster_time() 
    fenster_pixel(f, x, y) 
    uint32_t px = fenster_pixel(f, x, y); 
A bit more for audio, but that's really it's own little API

As a mimimal API for doing interactive apps, it's hard to beat. I can see hobbyists who make their own operating systems taking advantage of this to get things working quickly.

felipefar 8 days ago

Nice work! It wouldn't be much work to support Android with this library and keep the single source file, since the addition of native_app_glue. It'd require just an AndroidManifest.xml, and the API communication can be done by calling the functions provided by the NDK or in the worst case by calling JNI.

immibis 8 days ago

You might want to use CLOCK_MONOTONIC on POSIX or changing the system time will screw up the refresh rate or freeze the window completely.

  • teo_zero 8 days ago

    The application can handle it changing

      if (ms > 0)
        fenster_sleep(ms);
    
    to

      if (ms > 0 && ms <= 1000/60)
        fenster_sleep(ms);
    • immibis 7 days ago

      Wouldn't you rather make it correct to begin with, rather than introducing hacks to work around incorrectness?

unwind 8 days ago

Very nice and very straight-forward. I really liked the part on getting "Doom" to run, impressive how easy such porting is now!

Any low-level C is kind of catnip for the old SO-powered part of my brain, but did not spend a lot of time and got a lot of confidence.i did find this bug:

    memset(f->buf, rgb, f->width*f->height*sizeoof(*f->buf));
This will not work to set a color in the general case (`rgb` is `uint32_t`) since `memset()` only uses the lower `CHAR_BIT` bits of the value, it is setting the memory byte by byte. For black or white it will work! :)
onetom 8 days ago

Would it work on NetBSD/OpenBSD/FreeBSD/GhostBSD too?

Because if it does, it would worth mentioning it in the readme.

In Plan 9, Rio, the window manager, does a similar thing; it exposes a framebuffer to the process running in a window, simply as the /dev/draw device file, iirc.

mrpippy 8 days ago

In the Mac/AppKit implementation it would be interesting to try using wantsUpdateLayer: and updateLayer: instead of drawRect. That should be more efficient.

password4321 8 days ago

TIL: Our goal here is to have a framebuffer for a single window that would run and look the same on Linux, Windows and macOS.

Basically re-implementing enough SDL from scratch to run Doom, nice!

igtztorrero 8 days ago

WASN + Fester, for Browser, it is possible?