clay/examples/playdate-project-example/main.c
2025-05-05 20:57:01 +03:00

102 lines
3 KiB
C

#include "pd_api.h"
#include "pd_api/pd_api_gfx.h"
#define CLAY_IMPLEMENTATION
#include "../../clay.h"
#include "../../renderers/playdate/clay_renderer_playdate.c"
#include "clay-video-demo-playdate.c"
static int update(void *userdata);
const char *fontPath = "/System/Fonts/Asheville-Sans-14-Bold.pft";
void HandleClayErrors(Clay_ErrorData errorData) {}
struct TextUserData {
LCDFont *font[1];
PlaydateAPI *pd;
};
static struct TextUserData textUserData = {.font = {NULL, NULL}, .pd = NULL};
static Clay_Dimensions PlayDate_MeasureText(Clay_StringSlice text, Clay_TextElementConfig *config, void *userData) {
struct TextUserData *textUserData = userData;
int width = textUserData->pd->graphics->getTextWidth(
textUserData->font[config->fontId],
text.chars,
Clay_Playdate_CountUtf8Codepoints(text.chars, text.length),
kUTF8Encoding,
0
);
int height = textUserData->pd->graphics->getFontHeight(textUserData->font[config->fontId]);
return (Clay_Dimensions){
.width = (float)width,
.height = (float)height,
};
}
#ifdef _WINDLL
__declspec(dllexport)
#endif
int eventHandler(PlaydateAPI* pd, PDSystemEvent event, uint32_t eventArg)
{
if (event == kEventInit) {
const char *err;
textUserData.font[0] = pd->graphics->loadFont(fontPath, &err);
if (textUserData.font[0] == NULL) {
pd->system->error("%s:%i Couldn't load font %s: %s", __FILE__, __LINE__, fontPath, err);
}
textUserData.pd = pd;
pd->system->setUpdateCallback(update, pd);
uint64_t totalMemorySize = Clay_MinMemorySize();
Clay_Arena clayMemory = Clay_CreateArenaWithCapacityAndMemory(totalMemorySize, pd->system->realloc(NULL, totalMemorySize));
Clay_Initialize(
clayMemory,
(Clay_Dimensions){(float)pd->display->getWidth(), (float)pd->display->getHeight()},
(Clay_ErrorHandler){HandleClayErrors}
);
Clay_SetMeasureTextFunction(PlayDate_MeasureText, &textUserData);
ClayVideoDemo_Initialize();
}
return 0;
}
int selectedDocumentIndex = 0;
#define WRAP_RANGE(x, N) ((((x) % (N)) + (N)) % (N))
static int update(void *userdata) {
PlaydateAPI *pd = userdata;
PDButtons pushedButtons;
pd->system->getButtonState(NULL, &pushedButtons, NULL);
if (pushedButtons & kButtonDown) {
selectedDocumentIndex = WRAP_RANGE(selectedDocumentIndex + 1, MAX_DOCUMENTS);
} else if (pushedButtons & kButtonUp) {
selectedDocumentIndex = WRAP_RANGE(selectedDocumentIndex - 1, MAX_DOCUMENTS);
}
pd->graphics->clear(kColorWhite);
// A bit hacky, setting the cursor on to the document view so it can be
// scrolled..
Clay_SetPointerState((Clay_Vector2){
.x = pd->display->getWidth() / 2.0f,
.y = pd->display->getHeight() / 2.0f
}, false);
float crankDelta = pd->system->getCrankChange();
Clay_UpdateScrollContainers(
false,
(Clay_Vector2){0, -crankDelta * 0.25f},
pd->system->getElapsedTime()
);
Clay_RenderCommandArray renderCommands = ClayVideoDemo_CreateLayout(selectedDocumentIndex);
Clay_Playdate_Render(pd, renderCommands, textUserData.font);
return 1;
}