mirror of
https://github.com/rommapp/miyoo-mini-app.git
synced 2025-12-24 06:54:16 +00:00
get a working list
This commit is contained in:
+2
-1
@@ -1,3 +1,4 @@
|
||||
.DS_Store
|
||||
*.o
|
||||
romm
|
||||
App/RomM/romm
|
||||
config.txt
|
||||
|
||||
Binary file not shown.
@@ -1,5 +1,6 @@
|
||||
# template-repo
|
||||
A template repository for basing all new projects
|
||||
# miyoo-mini-app
|
||||
|
||||
Onion OS app to connect to a RomM server and fetch games
|
||||
|
||||
```sh
|
||||
sudo apt-get install libjson-c-dev libsdl2-dev libsdl2-ttf-dev
|
||||
|
||||
+8
-8
@@ -2,15 +2,15 @@
|
||||
#define ROMM_CLIENT_H
|
||||
|
||||
#include "rom.h"
|
||||
#include "platform.h"
|
||||
#include "menu_state.h"
|
||||
|
||||
// Structure for memory buffer
|
||||
struct MemoryStruct {
|
||||
char* memory;
|
||||
size_t size;
|
||||
};
|
||||
#include "SDL/SDL.h"
|
||||
#include "SDL/SDL_ttf.h"
|
||||
|
||||
// Memory handling callback
|
||||
static size_t WriteMemoryCallback(void* contents, size_t size, size_t nmemb, void* userp);
|
||||
int init_menu(MenuState* state);
|
||||
void cleanup_menu(MenuState* state);
|
||||
void render_platform_list(MenuState* state);
|
||||
void handle_input(MenuState* state, SDL_Event* event, bool* quit, bool* selected);
|
||||
int read_config(MenuState* state, const char* config_file);
|
||||
|
||||
#endif /* ROMM_CLIENT_H */
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
#include "SDL/SDL.h"
|
||||
#include "SDL/SDL_ttf.h"
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
typedef struct {
|
||||
int display_width;
|
||||
int display_height;
|
||||
SDL_Surface* screen;
|
||||
SDL_Surface* renderer;
|
||||
TTF_Font* font;
|
||||
RomMPlatform* platforms;
|
||||
int platform_count;
|
||||
int selected_index;
|
||||
int scroll_offset;
|
||||
int last_tick_count;
|
||||
int cur_tick_count;
|
||||
char* server_url;
|
||||
char* username;
|
||||
char* password;
|
||||
} MenuState;
|
||||
+4
-5
@@ -43,11 +43,10 @@ typedef struct RomMPlatform {
|
||||
// Function declarations for memory management
|
||||
void free_platform(RomMPlatform* platform);
|
||||
void free_firmware(RomMPlatformFirmware* firmware);
|
||||
|
||||
// Function declarations for operations
|
||||
const char* get_console_path(const char* platform_slug);
|
||||
int fetch_platform_list(const char* server_url, const char* username, const char* password, RomMPlatform** platform_list, int* platform_count);
|
||||
int fetch_rom_list(const char* server_url, const char* platform_slug, RomMRom** rom_list, int* rom_count);
|
||||
void free_platform_list(RomMPlatform* platforms, int count);
|
||||
|
||||
// Function declarations for operations
|
||||
char* generate_authorization_header(const char* username, const char* password);
|
||||
int fetch_platform_list(const char* server_url, const char* username, const char* password, RomMPlatform** platform_list, int* platform_count);
|
||||
|
||||
#endif // ROMM_PLATFORM_H
|
||||
|
||||
+112
-75
@@ -1,61 +1,52 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "platform.h"
|
||||
#include "menu_state.h"
|
||||
|
||||
#include "SDL/SDL.h"
|
||||
#include "SDL/SDL_ttf.h"
|
||||
|
||||
#define SCREEN_WIDTH 640
|
||||
#define SCREEN_HEIGHT 480
|
||||
#define ITEM_HEIGHT 40
|
||||
#define MAX_VISIBLE_ITEMS 10
|
||||
#define FRAME_RATE 60.0f
|
||||
|
||||
typedef struct {
|
||||
SDL_Surface* screen; // SDL1 uses Surface instead of Window+Renderer
|
||||
TTF_Font* font;
|
||||
RomMPlatform* platforms;
|
||||
int platform_count;
|
||||
int selected_index;
|
||||
int scroll_offset;
|
||||
int last_tick_count;
|
||||
int cur_tick_count;
|
||||
} MenuState;
|
||||
|
||||
void cleanup_menu(MenuState* state) {
|
||||
if (state->server_url) free(state->server_url);
|
||||
if (state->username) free(state->username);
|
||||
if (state->password) free(state->password);
|
||||
if (state->platforms) free_platform_list(state->platforms, state->platform_count);
|
||||
if (state->font) TTF_CloseFont(state->font);
|
||||
if (state->screen) SDL_FreeSurface(state->screen);
|
||||
if (state->renderer) SDL_FreeSurface(state->renderer);
|
||||
TTF_Quit();
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
int init_menu(MenuState* state) {
|
||||
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
|
||||
// Initialize state
|
||||
memset(state, 0, sizeof(MenuState));
|
||||
|
||||
// Initialize SDL with specific subsystems
|
||||
if (SDL_Init(SDL_INIT_VIDEO) < 0) { // Removed SDL_INIT_TIMER as it's not needed
|
||||
fprintf(stderr, "SDL could not initialize! SDL_Error: %s\n", SDL_GetError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Initialize TTF
|
||||
if (TTF_Init() < 0) {
|
||||
fprintf(stderr, "TTF could not initialize! TTF_Error: %s\n", TTF_GetError());
|
||||
SDL_Quit();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// SDL1 video mode initialization
|
||||
state->screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 16,
|
||||
SDL_HWSURFACE | SDL_DOUBLEBUF);
|
||||
|
||||
if (!state->screen) {
|
||||
fprintf(stderr, "Video mode could not be set! SDL_Error: %s\n", SDL_GetError());
|
||||
TTF_Quit();
|
||||
SDL_Quit();
|
||||
return -1;
|
||||
}
|
||||
// Get the current display width and height
|
||||
const SDL_VideoInfo *info = SDL_GetVideoInfo();
|
||||
state->display_width = info->current_w;
|
||||
state->display_height = info->current_h;
|
||||
|
||||
SDL_WM_SetCaption("ROMM", NULL); // Set window title in SDL1
|
||||
|
||||
// Load font
|
||||
state->font = TTF_OpenFont("./DejaVuSans.ttf", 16);
|
||||
// Load font - adjust path as needed for the Miyoo Mini
|
||||
state->font = TTF_OpenFont("/mnt/SDCARD/App/RomM/fonts/DejaVuSans.ttf", 16);
|
||||
if (!state->font) {
|
||||
fprintf(stderr, "Failed to load font! TTF_Error: %s\n", TTF_GetError());
|
||||
TTF_Quit();
|
||||
@@ -63,15 +54,44 @@ int init_menu(MenuState* state) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Set the video mode
|
||||
state->screen = SDL_SetVideoMode(state->display_width, state->display_height, 32, SDL_HWSURFACE);
|
||||
if (!state->screen) {
|
||||
fprintf(stderr, "Video mode could not be set! SDL_Error: %s\n", SDL_GetError());
|
||||
SDL_Quit();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Create a renderer surface
|
||||
state->renderer = SDL_CreateRGBSurface(SDL_HWSURFACE, state->display_width, state->display_height, 32, 0, 0, 0, 0);
|
||||
if (!state->renderer) {
|
||||
fprintf(stderr, "Renderer could not be created! SDL_Error: %s\n", SDL_GetError());
|
||||
SDL_Quit();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Clear the screen to black immediately after initialization
|
||||
SDL_FillRect(state->screen, NULL, SDL_MapRGB(state->screen->format, 0, 0, 0));
|
||||
SDL_Flip(state->screen);
|
||||
|
||||
state->selected_index = 0;
|
||||
state->scroll_offset = 0;
|
||||
state->last_tick_count = SDL_GetTicks();
|
||||
state->cur_tick_count = state->last_tick_count;
|
||||
|
||||
state->server_url = malloc(256);
|
||||
state->username = malloc(256);
|
||||
state->password = malloc(256);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void render_platform_list(MenuState* state) {
|
||||
// Fill background with black
|
||||
SDL_FillRect(state->screen, NULL, SDL_MapRGB(state->screen->format, 0, 0, 0));
|
||||
if (!state->renderer || !state->font) return; // Add safety check
|
||||
|
||||
// Clear screen with black using the surface's format
|
||||
Uint32 black = SDL_MapRGB(state->renderer->format, 0, 0, 0);
|
||||
SDL_FillRect(state->renderer, NULL, black);
|
||||
|
||||
SDL_Color text_color = {255, 255, 255, 0};
|
||||
SDL_Color selected_color = {255, 255, 0, 0};
|
||||
@@ -83,25 +103,27 @@ void render_platform_list(MenuState* state) {
|
||||
SDL_Color current_color = (actual_index == state->selected_index) ?
|
||||
selected_color : text_color;
|
||||
|
||||
SDL_Surface* text_surface = TTF_RenderText_Solid(state->font,
|
||||
state->platforms[actual_index].name,
|
||||
current_color);
|
||||
if (state->platforms && state->platforms[actual_index].name) { // Add safety check
|
||||
SDL_Surface* text_surface = TTF_RenderText_Solid(state->font,
|
||||
state->platforms[actual_index].name,
|
||||
current_color);
|
||||
|
||||
if (text_surface) {
|
||||
SDL_Rect dest_rect = {
|
||||
20, // x position
|
||||
i * ITEM_HEIGHT + 10, // y position
|
||||
text_surface->w, // width
|
||||
text_surface->h // height
|
||||
};
|
||||
if (text_surface) {
|
||||
SDL_Rect dest_rect = {
|
||||
20, // x position
|
||||
i * ITEM_HEIGHT + 10, // y position
|
||||
text_surface->w, // width
|
||||
text_surface->h // height
|
||||
};
|
||||
|
||||
// SDL1 uses SDL_BlitSurface instead of SDL_RenderCopy
|
||||
SDL_BlitSurface(text_surface, NULL, state->screen, &dest_rect);
|
||||
SDL_FreeSurface(text_surface);
|
||||
SDL_BlitSurface(text_surface, NULL, state->renderer, &dest_rect);
|
||||
SDL_FreeSurface(text_surface);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update the screen
|
||||
// Blit the renderer to the screen
|
||||
SDL_BlitSurface(state->renderer, NULL, state->screen, NULL);
|
||||
SDL_Flip(state->screen);
|
||||
}
|
||||
|
||||
@@ -131,7 +153,7 @@ void handle_input(MenuState* state, SDL_Event* event, bool* quit, bool* selected
|
||||
*selected = true;
|
||||
break;
|
||||
|
||||
case SDLK_ESCAPE: // Menu button
|
||||
case SDLK_RETURN: // Start button
|
||||
*quit = true;
|
||||
break;
|
||||
|
||||
@@ -141,19 +163,46 @@ void handle_input(MenuState* state, SDL_Event* event, bool* quit, bool* selected
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
MenuState state = {0};
|
||||
|
||||
if (init_menu(&state) < 0) {
|
||||
int read_config(MenuState* state, const char* filename) {
|
||||
FILE* file = fopen(filename, "r");
|
||||
if (!file) {
|
||||
fprintf(stderr, "Failed to open config file: %s\n", filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Define the server URL and the credentials for Basic Auth
|
||||
const char* server_url = "";
|
||||
const char* username = "";
|
||||
const char* password = "";
|
||||
char line[256];
|
||||
while (fgets(line, sizeof(line), file)) {
|
||||
// Remove trailing newline
|
||||
line[strcspn(line, "\n")] = 0;
|
||||
|
||||
if (fetch_platform_list(server_url, username, password, &state.platforms, &state.platform_count) < 0) {
|
||||
if (strncmp(line, "server_url=", 11) == 0) {
|
||||
snprintf(state->server_url, 256, "%s", line + 11);
|
||||
} else if (strncmp(line, "username=", 9) == 0) {
|
||||
snprintf(state->username, 256, "%s", line + 9);
|
||||
} else if (strncmp(line, "password=", 9) == 0) {
|
||||
snprintf(state->password, 256, "%s", line + 9);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main() {
|
||||
MenuState state = {0};
|
||||
|
||||
if (init_menu(&state) < 0) {
|
||||
fprintf(stderr, "Failed to initialize menu\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (read_config(&state, "/mnt/SDCARD/App/RomM/config.txt") < 0) {
|
||||
fprintf(stderr, "Failed to read configuration\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fetch_platform_list(state.server_url, state.username, state.password, &state.platforms, &state.platform_count) < 0) {
|
||||
fprintf(stderr, "Failed to fetch platform list\n");
|
||||
cleanup_menu(&state);
|
||||
return -1;
|
||||
}
|
||||
@@ -162,37 +211,25 @@ int main() {
|
||||
bool selected = false;
|
||||
SDL_Event event;
|
||||
|
||||
state.last_tick_count = SDL_GetTicks();
|
||||
state.cur_tick_count = state.last_tick_count;
|
||||
|
||||
float fps = 0.0f;
|
||||
int frame = state.cur_tick_count;
|
||||
int frameCount = 0;
|
||||
|
||||
while (!quit && !selected) {
|
||||
state.cur_tick_count = SDL_GetTicks();
|
||||
|
||||
while (SDL_PollEvent(&event)) {
|
||||
handle_input(&state, &event, &quit, &selected);
|
||||
}
|
||||
|
||||
if (state.cur_tick_count - state.last_tick_count < 1000 / FRAME_RATE) {
|
||||
continue;
|
||||
// Only render if enough time has passed
|
||||
if (state.cur_tick_count - state.last_tick_count >= (1000 / FRAME_RATE)) {
|
||||
render_platform_list(&state);
|
||||
state.last_tick_count = state.cur_tick_count;
|
||||
} else {
|
||||
SDL_Delay(1); // Give up some CPU time
|
||||
}
|
||||
|
||||
++frameCount;
|
||||
if (state.cur_tick_count - frame >= 1000) {
|
||||
fps = frameCount / ((state.cur_tick_count - frame) / 1000.f);
|
||||
frameCount = 0;
|
||||
frame = state.cur_tick_count;
|
||||
}
|
||||
|
||||
render_platform_list(&state);
|
||||
}
|
||||
|
||||
if (selected) {
|
||||
// User selected a platform - fetch its games
|
||||
if (selected && state.selected_index < state.platform_count) {
|
||||
RomMPlatform* selected_platform = &state.platforms[state.selected_index];
|
||||
printf("Selected platform: %s\n", selected_platform->name);
|
||||
// TODO: Implement fetch_rom_list and show games menu
|
||||
}
|
||||
|
||||
cleanup_menu(&state);
|
||||
|
||||
@@ -43,10 +43,6 @@ void free_platform_list(RomMPlatform* platforms, int count) {
|
||||
free(platforms);
|
||||
}
|
||||
|
||||
// Return the console path based on platform slug
|
||||
const char* get_console_path(const char* platform_slug) {
|
||||
return "miyoo-mini";
|
||||
}
|
||||
|
||||
// Function to generate the Basic Authorization header from username and password
|
||||
char* generate_authorization_header(const char* username, const char* password) {
|
||||
@@ -127,8 +123,6 @@ int fetch_platform_list(const char* server_host, const char* username, const cha
|
||||
struct json_object *parsed_json;
|
||||
parsed_json = json_tokener_parse(response_get_memory(resp));
|
||||
|
||||
fprintf(stderr, "Parsed JSON: %s\n", json_object_to_json_string(parsed_json));
|
||||
|
||||
if (parsed_json == NULL) {
|
||||
fprintf(stderr, "Failed to parse JSON response\n");
|
||||
response_free(resp);
|
||||
@@ -169,8 +163,3 @@ int fetch_platform_list(const char* server_host, const char* username, const cha
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Function to fetch the ROM list from the server
|
||||
int fetch_rom_list(const char* server_host, const char* platform_slug, RomMRom** rom_list, int* rom_count) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user