mario-kart-casio/src/platforms/gint.c

135 lines
3.4 KiB
C

#include "./gint.h"
#include <gint/keyboard.h>
#include <gint/gint.h>
#include <gint/drivers/r61524.h>
#include <gint/rtc.h>
#include <gint/display.h>
#include <gint/timer.h>
#include <gint/clock.h>
#include <stdbool.h>
#include "../main.h"
#include "gint/display-cg.h"
#include "gint/image.h"
#ifdef PROFILING_ENABLED
#include <libprof.h>
#endif
void platformInit() {
// clock_set_speed(CLOCK_SPEED_F5);
#ifdef PROFILING_ENABLED
prof_init();
#endif
}
static int callback_tick(volatile int *newFrameNeeded) {
*newFrameNeeded = 1;
return TIMER_CONTINUE;
}
void runMainLoop(void (*loop)(), int fps) {
static volatile int newFrameNeeded = false;
int t = timer_configure(TIMER_ANY, 1000000 / fps, GINT_CALL(callback_tick, &newFrameNeeded));
if (t >= 0) timer_start(t);
while (1) {
if (frameCapEnabled) {
while (!newFrameNeeded) sleep();
}
newFrameNeeded = 0;
loop();
}
}
void updateKeys() {
clearevents();
if (keydown(KEY_MENU)) {
gint_osmenu();
fillSky(0, LCD_HEIGHT_PX);
}
}
// Align to a multiple of 4, rounding down.
#define alignTo4Down(n) ((n) & ~3)
// Align to a multiple of 4, rounding up.
#define alignTo4Up(n) (((n) + 3) & ~3)
void displayUpdateBox(int x, int y, int w, int h) {
r61524_display_rect(gint_vram, x, x + w - 1, y, y + h - 1);
}
void displayUpdate(int minY, int maxY) {
minY = alignTo4Down(minY);
#ifdef PROFILING_ENABLED
#define method R61524_DMA_WAIT
#else
#define method R61524_DMA
#endif
r61524_display(gint_vram, minY, alignTo4Up(maxY - minY), method);
}
void drawText(int x, int y, const char *text) {
dtext_opt(x, y, C_BLACK, C_WHITE, DTEXT_LEFT, DTEXT_TOP, text, -1);
// displayUpdate(y, y + 12);
}
int getTimeMS(void) {
return rtc_ticks() * 1000 / 128;
}
int check_key(int key) {
if (key == -1) return 0;
return keydown(key);
}
struct image {
int xOffset;
int yOffset;
const bopti_image_t* data;
};
void draw(const struct image *img, int x, int y) {
dimage(x + img->xOffset, y + img->yOffset, img->data);
}
void draw_flipped(const struct image *img, int x, int y) {
// dimage(x + img->xOffset, y + img->yOffset, img->data);
dimage_p8_effect(x + img->xOffset, y + img->yOffset, img->data, IMAGE_HFLIP);
}
// void draw_loop_x(const struct image* data, int x, int y, int xOffset, int drawWidth);
void draw_partial(const struct image *img, int x, int y, int sx, int sy, int w, int h) {
dsubimage(x + img->xOffset + sx, y + img->yOffset + sy, img->data, sx, sy, w, h, 0);
}
void draw_partial_flipped(const struct image *img, int x, int y, int sx, int sy, int w, int h) {
dsubimage_p8_effect(x + img->xOffset + sx, y + img->yOffset + sy, img->data, sx, sy, w, h, IMAGE_HFLIP);
}
void draw_scaled(const struct image *img, int x, int y, float scaleX, float scaleY) {
// Create an image_linear_map
struct image_linear_map map;
image_scale(img->data, scaleX * (1 << 16), scaleY * (1 << 16), &map);
// If x is negative, cut the image off on the left.
const image_t* newData;
if (x < 0) {
// image_sub(const image_t *src, int x, int y, int w, int h, image_t *dst)
newData = image_sub(img->data, -x, 0, img->data->width + x, img->data->height);
} else {
newData = img->data;
}
// Use it to draw the image
// TODO: Free the created image or cache it
image_linear(newData, image_at(image_create_vram(), x, y), &map);
}
int get_width(const struct image* img) {
return img->data->width;
}
int get_height(const struct image* img) {
return img->data->height;
}