text/plain
•
4.46 KB
•
180 lines
#include <SDL.h>
#include <math.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include "../src/main.h"
#include "../src/moon.h"
#include "../src/lvgl_port.h"
#define SCREEN_SCALE 4
static uint32_t framebuffer[SCREEN_WIDTH * SCREEN_HEIGHT];
static float audio_phase = 0.0f;
// Audio callback - fill buf with your PCM data (signed 16-bit stereo)
static void audio_callback(void *userdata, uint8_t *buf, int len) {
(void)userdata;
int16_t *samples = (int16_t *)buf;
int num_samples = len / sizeof(int16_t) / 2; // stereo
// Simple 440Hz test tone
float freq = 440.0f;
float phase_inc = 2.0f * 3.14159f * freq / AUDIO_FREQ;
for (int i = 0; i < num_samples; i++) {
int16_t sample = (int16_t)(sinf(audio_phase) * 200);
samples[i * 2] = sample; // left
samples[i * 2 + 1] = sample; // right
audio_phase += phase_inc;
}
}
void blit_buf(const void *buf, int yStartArg, int yEndArg) {
blit_buf_rect(buf, 0, yStartArg, SCREEN_WIDTH, yEndArg);
}
void blit_buf_rect(const void *buf, int x, int yStartArg, int xEnd, int yEndArg) {
const int xStart = MIN(SCREEN_WIDTH, MAX(0, x));
const int xEndClamped = MIN(SCREEN_WIDTH, MAX(xStart, xEnd));
const int yStart = MIN(SCREEN_HEIGHT, MAX(0, yStartArg));
const int yEnd = MIN(SCREEN_HEIGHT, MAX(yStart, yEndArg));
const int width = xEndClamped - xStart;
const uint32_t *src = (const uint32_t *)buf;
for (int y = yStart; y < yEnd; y++) {
uint32_t *dst = &framebuffer[y * SCREEN_WIDTH + xStart];
memcpy(dst, src, width * 4);
src += width;
}
}
int main(int argc, char *argv[]) {
(void)argc;
(void)argv;
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) {
SDL_Log("SDL_Init failed: %s", SDL_GetError());
return 1;
}
SDL_Window *window = SDL_CreateWindow("Moon",
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
SCREEN_WIDTH * SCREEN_SCALE, SCREEN_HEIGHT * SCREEN_SCALE,
0);
if (!window) {
SDL_Log("SDL_CreateWindow failed: %s", SDL_GetError());
return 1;
}
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1,
SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (!renderer) {
SDL_Log("SDL_CreateRenderer failed: %s", SDL_GetError());
return 1;
}
SDL_Texture *texture = SDL_CreateTexture(renderer,
SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING,
SCREEN_WIDTH, SCREEN_HEIGHT);
if (!texture) {
SDL_Log("SDL_CreateTexture failed: %s", SDL_GetError());
return 1;
}
SDL_AudioSpec want = {
.freq = AUDIO_FREQ,
.format = AUDIO_S16SYS,
.channels = 2,
.samples = AUDIO_SAMPLES,
.callback = audio_callback,
};
SDL_AudioSpec have;
SDL_AudioDeviceID audio_dev = SDL_OpenAudioDevice(NULL, 0, &want, &have, 0);
if (!audio_dev) {
SDL_Log("SDL_OpenAudioDevice failed: %s", SDL_GetError());
return 1;
}
SDL_PauseAudioDevice(audio_dev, 0);
// Initialize LVGL display and input drivers
lvgl_port_init();
lvgl_port_indev_init();
bool running = true;
Uint32 last_tick = SDL_GetTicks();
setup();
while (running) {
SDL_Event event;
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
running = false;
} else if (event.type == SDL_KEYDOWN) {
switch (event.key.keysym.sym) {
case SDLK_ESCAPE:
running = false;
break;
case SDLK_UP:
case SDLK_LEFT:
button_state |= BUTTON_STATE_UP;
break;
case SDLK_DOWN:
case SDLK_RIGHT:
button_state |= BUTTON_STATE_DOWN;
break;
case SDLK_RETURN:
button_state |= BUTTON_STATE_OK;
break;
case SDLK_BACKSPACE:
button_state |= BUTTON_STATE_BACK;
break;
}
} else if (event.type == SDL_KEYUP) {
switch (event.key.keysym.sym) {
case SDLK_UP:
case SDLK_LEFT:
button_state &= ~BUTTON_STATE_UP;
break;
case SDLK_DOWN:
case SDLK_RIGHT:
button_state &= ~BUTTON_STATE_DOWN;
break;
case SDLK_RETURN:
button_state &= ~BUTTON_STATE_OK;
break;
case SDLK_BACKSPACE:
button_state &= ~BUTTON_STATE_BACK;
break;
}
}
}
// Update LVGL tick
Uint32 now = SDL_GetTicks();
Uint32 elapsed = now - last_tick;
last_tick = now;
lv_tick_inc(elapsed);
// Run application loop
loop();
// Handle LVGL tasks (includes rendering)
lv_timer_handler();
SDL_UpdateTexture(texture, NULL, framebuffer,
SCREEN_WIDTH * sizeof(uint32_t));
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent(renderer);
}
SDL_CloseAudioDevice(audio_dev);
SDL_DestroyTexture(texture);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}