Hacker News new | past | comments | ask | show | jobs | submit login
The Story Behind Fenster (zserge.com)
72 points by hamdouni 56 days ago | hide | past | favorite | 10 comments



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.


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.


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.


The application can handle it changing

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

  if (ms > 0 && ms <= 1000/60)
    fenster_sleep(ms);


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


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! :)


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.


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


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!


WASN + Fester, for Browser, it is possible?




Consider applying for YC's W25 batch! Applications are open till Nov 12.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search:
  翻译: