Skip to content

Instantly share code, notes, and snippets.

@possan
Created February 7, 2025 22:54
Show Gist options
  • Save possan/128b8a3384cad6d7e6667876bf83bb1c to your computer and use it in GitHub Desktop.
Save possan/128b8a3384cad6d7e6667876bf83bb1c to your computer and use it in GitHub Desktop.
Playbit rotozoom test
// build with
// cc -lplaybit -g -o /tmp/rotozoom rotozoom.c
#include <playbit/playbit.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
struct AppState
{
PBImageDisplayRef imageref;
uint8_t *buffer;
uint32_t frame;
int8_t dx, dy;
float pcx, pcy;
float pvx, pvy;
};
void eventhandler(PBEventSourceRef _Nonnull source,
/* input */ PBEventType eventType)
{
struct AppState *state = (struct AppState *)PBEventSourceGetUserDataPtr(source);
uint8_t buffer[320 * 240 * 4] = {
0,
};
int o = 0;
float t = state->frame * 0.1;
float a = 3.142f * sin(t / 23.0);
float s1 = cos(a);
float c1 = sin(a);
// s1 = 1;
// c1 = 0;
float sc = 2.0 + 1.0 * cos(t / 6.0);
for (int j = 0; j < 240; j++)
{
for (int k = 0; k < 320; k++)
{
float x1 = k - 160;
float y1 = j - 120;
x1 *= sc;
y1 *= sc;
float x2 = x1 * s1 + y1 * c1;
float y2 = x1 * c1 - y1 * s1;
// x2 = x1;
// y2 = y1;
// x2 += 40.0 * cos(t * 0.19);
// y2 += 40.0 * sin(t * 0.15);
x2 -= state->pcx;
y2 -= state->pcy;
int bx = ((int)(x2 * 1.0));
int by = ((int)(y2 * 1.0));
while (bx < 0)
bx += 256;
while (by < 0)
by += 256;
bx %= 256;
by %= 256;
int b = bx ^ by;
buffer[o + 0] = b;
buffer[o + 1] = b;
buffer[o + 2] = b;
buffer[o + 3] = 255;
o += 4;
}
}
PBImagePtr imageptr =
PBImageCreateFromBitmapBuffer(&buffer, 320 * 240 * 4, 320 * 4, 320, 240, 72, PBBitmapFormat_RGB8, PBColorSpaceID_SRGB);
PBImageDisplaySetImage(state->imageref, imageptr, PB_STR("Ken"));
PBImageRelease(imageptr);
state->frame++;
state->pvx += ((float)(state->dx * 5) - state->pvx) * 0.03;
state->pvy += ((float)(state->dy * 5) - state->pvy) * 0.03;
state->pcx += state->pvx * 1.0;
state->pcy += state->pvy * 1.0;
}
intptr_t customElement(PBElement *elm, PBMessage *message)
{
printf("custom element, msg type %d\n", message->type);
struct AppState *state = (struct AppState *)PBElementGetUserDataPtr(elm);
if (message->type == PBMsg_KEY_DOWN)
{
printf("key down: %d %d\n", message->keyboard.rawCode, message->keyboard.mappedCode);
if (message->keyboard.mappedCode == 80)
{
state->dx = -1;
}
if (message->keyboard.mappedCode == 81)
{
state->dy = 1;
}
if (message->keyboard.mappedCode == 82)
{
state->dy = -1;
}
if (message->keyboard.mappedCode == 79)
{
state->dx = 1;
}
}
else if (message->type == PBMsg_KEY_UP)
{
printf("key up: %d %d\n", message->keyboard.rawCode, message->keyboard.mappedCode);
if (message->keyboard.mappedCode == 80)
{
state->dx = 0;
}
if (message->keyboard.mappedCode == 81)
{
state->dy = 0;
}
if (message->keyboard.mappedCode == 82)
{
state->dy = 0;
}
if (message->keyboard.mappedCode == 79)
{
state->dx = 0;
}
}
}
intptr_t applicationMessage(PBMessage *message)
{
printf("ApplicationMessage, msg type %d\n", message->type);
if (message->type == PBMsg_APP_CREATE)
{
struct AppState *state = PBHeapAllocateZeroed(sizeof(struct AppState));
PBWindowCreationOptions options =
{PBWindowType_STANDARD, PB_STR("Roto zoomer"), 300, 300};
PBWindow *window = message->appCreate.window = PBWindowCreate(options);
PBElement *layoutColumn =
PBElementAdd((PBElement *)window, 0, PBElementMessageHandler_Make(NULL));
PBEventSourcePtr timer =
PBEventSourceCreateTimer(16);
PBEventSourceActivate(timer);
PBEventSourceSetHandler(timer, PBEventHandler_Make(eventhandler));
printf("window %X\n", window);
uint8_t buffer[2000] = {
0,
};
PBImagePtr imageptr =
PBImageCreateFromBitmapBuffer(&buffer, 8 * 8 * 3, 8 * 3, 8, 8, 72, PBBitmapFormat_RGB8, PBColorSpaceID_SRGB);
PBImageDisplayRef imageref =
PBImageDisplayAdd(layoutColumn, PBImageDisplay_FIT | PBElement_FILL, imageptr, PB_STR("jeff"));
PBImageRelease(imageptr);
state->imageref = imageref;
PBElement *e = PBElementCreate((PBElement *)window, PBElement_CUSTOM_PAINT, PBElementMessageHandler_Make(customElement));
PBElementFocus(e, 0);
PBElementSetUserDataPtr(e, state);
PBElementRelease(e);
PBEventSourceSetUserDataPtr(timer, state);
}
return 0;
}
int main()
{
return PBEventLoop(PBApplicationMessageHandler_Make(applicationMessage));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment