changeset 2438:bed4d3db8a3f

More flexible loading of Pico storyware assets
author Michael Pavone <pavone@retrodev.com>
date Sun, 11 Feb 2024 11:04:39 -0800
parents 79a8cccb6ac1
children a66916828c9b
files blastem.c config.h genesis.c render.h render_sdl.c system.c system.h
diffstat 7 files changed, 110 insertions(+), 57 deletions(-) [+]
line wrap: on
line diff
--- a/blastem.c	Sat Feb 10 17:46:30 2024 -0800
+++ b/blastem.c	Sun Feb 11 11:04:39 2024 -0800
@@ -173,7 +173,7 @@
 					}
 					dst->name = basename_no_extension(filename);
 					dst->size = out_size;
-					zip_close(z);
+					dst->zip = z;
 					return out_size;
 				}
 			}
@@ -187,6 +187,9 @@
 uint32_t load_media(char * filename, system_media *dst, system_type *stype)
 {
 	uint8_t header[10];
+	if (dst->zip) {
+		zip_close(dst->zip);
+	}
 	dst->orig_path = filename;
 	char *ext = path_extension(filename);
 	if (ext && !strcasecmp(ext, "zip")) {
--- a/config.h	Sat Feb 10 17:46:30 2024 -0800
+++ b/config.h	Sun Feb 11 11:04:39 2024 -0800
@@ -10,6 +10,7 @@
 
 tern_node *parse_config_file(char *config_path);
 tern_node *parse_bundled_config(char *config_name);
+tern_node *parse_config(char * config_data);
 tern_node *load_overrideable_config(char *name, char *bundled_name, uint8_t *used_config_dir);
 tern_node *load_config();
 char *serialize_config(tern_node *config, uint32_t *size_out);
--- a/genesis.c	Sat Feb 10 17:46:30 2024 -0800
+++ b/genesis.c	Sun Feb 11 11:04:39 2024 -0800
@@ -3155,44 +3155,67 @@
 	memset(gen->pico_story_pages, 0xFF, sizeof(gen->pico_story_pages));
 #ifndef IS_LIB
 	gen->pico_story_window = render_create_window("Pico Storybook & Pad", 640, 640, NULL);
-	const char *parts[] = {current_media()->dir, PATH_SEP, current_media()->name, ".manifest"};
-	char *manifest_path = alloc_concat_m(sizeof(parts)/sizeof(*parts), parts);
-	tern_node *manifest = parse_config_file(manifest_path);
-	if (!manifest) {
-		printf("Manifest not found at %s\n", manifest_path);
+	char *manifest_name = alloc_concat(current_media()->name, ".manifest");
+	char *manifest_str = load_media_subfile(current_media(), manifest_name, NULL);
+	tern_node *manifest = NULL;
+	if (manifest_str) {
+		manifest = parse_config(manifest_str);
+		if (!manifest) {
+			printf("Failed to parse manifest %s\n", manifest_name);
+		}
+	} else {
+		printf("Manifest file %s not found\n", manifest_name);
+	}
+	
+	tern_node *pages = tern_find_node(manifest, "pages");
+	if (!pages && manifest) {
+		printf("No pages key in %s\n", manifest_name);
 	}
-	if (manifest) {
-		tern_node *pages = tern_find_node(manifest, "pages");
+	char numkey[18];
+	for (int i = 0; i < 7; i++) {
+		uint8_t *img_data;
+		uint32_t img_size;
 		if (pages) {
-			char numkey[13];
-			for (int i = 0; i < 7; i++) {
-				sprintf(numkey, "%d", i);
-				char *page_path = tern_find_ptr(pages, numkey);
-				if (page_path) {
-					printf("page %d: %s\n", i, page_path);
-				} else {
+			sprintf(numkey, "%d", i);
+			char *page_path = tern_find_ptr(pages, numkey);
+			if (page_path) {
+				printf("page %d: %s\n", i, page_path);
+			} else {
+				continue;
+			}
+			img_data = load_media_subfile(current_media(), page_path, &img_size);
+			if (!img_data) {
+				printf("Failed to load image file for page %d from %s\n", i, page_path);
+				continue;
+			}
+		} else {
+			sprintf(numkey, "_%d.png", i);
+			char *img_path = alloc_concat(current_media()->name, numkey);
+			img_data = load_media_subfile(current_media(), img_path, &img_size);
+			if (!img_data) {
+				sprintf(numkey, "_%d.PNG", i);
+				char *img_path_loud = alloc_concat(current_media()->name, numkey);
+				img_data = load_media_subfile(current_media(), img_path_loud, &img_size);
+				if (!img_data) {
+					printf("Failed to load image file for page %d from %s or %s\n", i, img_path, img_path_loud);
+					free(img_path);
+					free(img_path_loud);
 					continue;
 				}
-				char *img_path;
-				if (is_absolute_path(current_media()->dir)) {
-					const char *img_parts[] = {current_media()->dir, PATH_SEP, page_path};
-					img_path = alloc_concat_m(sizeof(img_parts)/sizeof(*img_parts), img_parts);
-				} else {
-					const char *img_parts[] = {path_current_dir(), PATH_SEP, current_media()->dir, PATH_SEP, page_path};
-					img_path = alloc_concat_m(sizeof(img_parts)/sizeof(*img_parts), img_parts);
-				}
-				gen->pico_story_pages[i] = render_static_image(gen->pico_story_window, img_path);
-				if (gen->pico_story_pages[i] == 0xFF) {
-					printf("Failed to load page %d from %s\n", i, img_path);
-				}
-				free(img_path);
+				free(img_path_loud);
 			}
-		} else {
-			printf("No pages key in %s\n", manifest_path);
+			free(img_path);
 		}
-		tern_free(manifest);
+		
+		gen->pico_story_pages[i] = render_static_image(gen->pico_story_window, img_data, img_size);
+		if (gen->pico_story_pages[i] == 0xFF) {
+			printf("Failed to decode image for page %d\n", i);
+		}
+		free(img_data);
 	}
-	free(manifest_path);
+	
+	free(manifest_name);
+	tern_free(manifest);
 	pico_update_page(gen);
 #endif
 	return gen;
--- a/render.h	Sat Feb 10 17:46:30 2024 -0800
+++ b/render.h	Sun Feb 11 11:04:39 2024 -0800
@@ -151,7 +151,7 @@
 int render_ui_to_pixels_y(int ui);
 #ifndef IS_LIB
 uint8_t render_create_thread(render_thread *thread, const char *name, render_thread_fun fun, void *data);
-uint8_t render_static_image(uint8_t window, char *path);
+uint8_t render_static_image(uint8_t window, uint8_t *buffer, uint32_t size);
 void render_draw_image(uint8_t window, uint8_t image, int x, int y, int width, int height);
 void render_clear_window(uint8_t window, uint8_t r, uint8_t g, uint8_t b);
 void render_fill_rect(uint8_t window, uint8_t r, uint8_t g, uint8_t b, int x, int y, int width, int height);
--- a/render_sdl.c	Sat Feb 10 17:46:30 2024 -0800
+++ b/render_sdl.c	Sun Feb 11 11:04:39 2024 -0800
@@ -1530,33 +1530,11 @@
 
 SDL_Texture **static_images;
 uint8_t num_static;
-uint8_t render_static_image(uint8_t window, char *path)
+uint8_t render_static_image(uint8_t window, uint8_t *buffer, uint32_t size)
 {
-	uint32_t fsize;
-	uint8_t *buffer;
-	if (is_absolute_path(path)) {
-		FILE *f = fopen(path, "rb");
-		if (!f) {
-			return 0xFF;
-		}
-		fsize = file_size(f);
-		buffer = calloc(1, fsize);
-		if (fread(buffer, 1, fsize, f) != fsize) {
-			free(buffer);
-			fclose(f);
-			return 0xFF;
-		}
-		fclose(f);
-	} else {
-		buffer = (uint8_t *)read_bundled_file(path, &fsize);
-	}
-	if (!buffer) {
-		return 0xFF;
-	}
 	
 	uint32_t width, height;
-	uint32_t *pixels = load_png(buffer, fsize, &width, &height);
-	free(buffer);
+	uint32_t *pixels = load_png(buffer, size, &width, &height);
 	if (!pixels) {
 		return 0xFF;
 	}
--- a/system.c	Sat Feb 10 17:46:30 2024 -0800
+++ b/system.c	Sun Feb 11 11:04:39 2024 -0800
@@ -5,6 +5,8 @@
 #include "sms.h"
 #include "mediaplayer.h"
 #include "coleco.h"
+#include "paths.h"
+#include "util.h"
 
 uint8_t safe_cmp(char *str, long offset, uint8_t *buffer, long filesize)
 {
@@ -137,3 +139,46 @@
 	system->force_release = force_release;
 	system->request_exit(system);
 }
+
+void* load_media_subfile(const system_media *media, char *path, uint32_t *sizeout)
+{
+	char *to_free = NULL;
+	void *buffer = NULL;
+	uint32_t size = 0;
+	if (media->zip) {
+		uint32_t i;
+		for (i = 0; i < media->zip->num_entries; i++)
+		{
+			if (!strcasecmp(media->zip->entries[i].name, path)) {
+				break;
+			}
+		}
+		if (i < media->zip->num_entries) {
+			size_t zsize = media->zip->entries[i].size + 1;
+			buffer = zip_read(media->zip, i, &zsize);
+			size = zsize;
+			if (buffer) {
+				((uint8_t *)buffer)[size] = 0;
+			}
+			goto end;
+		}
+	}
+	if (!is_absolute_path(path)) {
+		to_free = path = path_append(media->dir, path);
+	}
+	FILE *f = fopen(path, "rb");
+	if (!f) {
+		goto end;
+	}
+	size = file_size(f);
+	buffer = calloc(1, size + 1);
+	size = fread(buffer, 1, size, f);
+	fclose(f);
+	
+end:
+	if (sizeout) {
+		*sizeout = size;
+	}
+	free(to_free);
+	return buffer;
+}
--- a/system.h	Sat Feb 10 17:46:30 2024 -0800
+++ b/system.h	Sun Feb 11 11:04:39 2024 -0800
@@ -4,6 +4,7 @@
 #include <stdint.h>
 #include <stdio.h>
 #include "flac.h"
+#include "zip.h"
 
 typedef struct system_header system_header;
 typedef struct system_media system_media;
@@ -138,6 +139,7 @@
 	system_media *chain;
 	track_info   *tracks;
 	uint8_t      *tmp_buffer;
+	zip_file     *zip;
 	seek_fun     seek;
 	read_fun     read;
 	read_fun     read_subcodes;
@@ -157,5 +159,6 @@
 system_header *alloc_config_system(system_type stype, system_media *media, uint32_t opts, uint8_t force_region);
 system_header *alloc_config_player(system_type stype, event_reader *reader);
 void system_request_exit(system_header *system, uint8_t force_release);
+void* load_media_subfile(const system_media *media, char *path, uint32_t *sizeout);
 
 #endif //SYSTEM_H_