Can't get drawText to display to the screen

I am developing on Visual Studio for Windows targeting the simulator (I learned my device was my Christmas present - but its on backorder :cry: ). I am messing around with the hello world example in C just trying to get the button I pressed to display to the screen.

I have a displayButton function that calls pd->graphics->drawText, but it doesn't seem to do anything! It appears like I am following the documentation, so what am I missing?

//
//  main.c
//  Extension
//
//  Created by Dave Hayden on 7/30/14.
//  Copyright (c) 2014 Panic, Inc. All rights reserved.
//

#include <stdio.h>
#include <stdlib.h>

#include "pd_api.h"

static int update(void* userdata);
static int displayButton(PDButtons button, int down, uint32_t when, void* userdata);
const char* fontpath = "/System/Fonts/Asheville-Sans-14-Bold.pft";
LCDFont* font = NULL;

#ifdef _WINDLL
__declspec(dllexport)
#endif
//pd is a pointer to a struct containing the system's runtime functions that handle music, display, files io, etc
int eventHandler(PlaydateAPI* pd, PDSystemEvent event, uint32_t arg)
{
	(void)arg; // arg is currently only used for event = kEventKeyPressed

	if ( event == kEventInit ) //kEventInit is the type event is set to on game startup. 
	{
		const char* err;
		font = pd->graphics->loadFont(fontpath, &err);
		
		if ( font == NULL )
			pd->system->error("%s:%i Couldn't load font %s: %s", __FILE__, __LINE__, fontpath, err);

		// Note: If you set an update callback in the kEventInit handler, the system assumes the game is pure C 
		// and doesn't run any Lua code in the game
		pd->system->setUpdateCallback(update, pd);
	}

	pd->system->setButtonCallback(displayButton, pd, 5);
	
	return 0;
}

static int displayButton(PDButtons button, int down, uint32_t when, void* userdata) {
	PlaydateAPI* pd = userdata;
	char btnStr[4] = { 0 };
	switch (button) {
	case kButtonB:
		strcpy(btnStr,"B");
		break;
	case kButtonA:
		strcpy(btnStr, "A");
		break;
	default:
		memset(&btnStr, 0, 2);
	}
	pd->system->logToConsole("Press: %d down? %d actual value of A: %d and B: %d ... Button pressed was %s", button, down,kButtonA, kButtonB, btnStr);

	pd->graphics->clear(kColorWhite);
	pd->graphics->setFont(font);
	pd->graphics->drawText(btnStr, strlen(btnStr), kASCIIEncoding, 0, 0);
	return 0;
}

#define TEXT_WIDTH 86
#define TEXT_HEIGHT 16

int x = (400-TEXT_WIDTH)/2;
int y = (240-TEXT_HEIGHT)/2;
int dx = 1;
int dy = 2;

static int update(void* userdata)
{
	PlaydateAPI* pd = userdata;
	
	pd->graphics->clear(kColorWhite);
	pd->graphics->setFont(font);
	/*pd->graphics->drawText("Hello World!", strlen("Hello World!"), kASCIIEncoding, x, y);

	x += dx;
	y += dy;
	
	if ( x < 0 || x > LCD_COLUMNS - TEXT_WIDTH )
		dx = -dx;
	
	if ( y < 0 || y > LCD_ROWS - TEXT_HEIGHT )
		dy = -dy;
        
	pd->system->drawFPS(0,0);*/

	return 1;
}

I appreciate any help I get!

Heya!
The button callback can fire multiple times per frame (once per button) BUT they're all called before your update function runs.
In your update function the first thing do is clear the screen with
pd->graphics->clear(kColorWhite);
Remove that!
You're already clearing inside your button callback so you will only see the last callback to come through that frame.

Personally, I like to ask for the button state at the start of each frame. eg.

PDButtons current;
PDButtons pushed;
PDButtons released;
sys->getButtonState( &current, &pushed, &released );

if ( pushed & kButtonA )
{
    //do something
}

Thank you! This makes more sense. I guess I can think of a button press as akin to an interrupt that gets handled before returning execution to the update function? I am more familiar with system programming than game design lol.

1 Like

Not quite an interrupt, and more of just order of operations.
from the docs:

The function is called for each button up/down event (possibly multiple events on the same button) that occurred during the previous update cycle

1 Like