commit 53952f5566cfa70d353a6b7957975cc7f7f32b86 Author: XANTRONIX Development Date: Sat May 7 16:11:34 2016 -0500 Initial implementation diff --git a/configure b/configure new file mode 100755 index 0000000..e02382c --- /dev/null +++ b/configure @@ -0,0 +1,95 @@ +#! /bin/sh + +OS=`uname -s` +PREFIX=/usr/local +DEBUG=0 + +create_linux_config_h() { + cat < src/config.h +#ifndef _CONFIG_H +#define _CONFIG_H +#include +#define CAMMY_INSTALL_PREFIX "$PREFIX" +#endif /* _CONFIG_H */ +EOF +} + +create_darwin_config_h() { + cat < src/config.h +#ifndef _CONFIG_H +#define _CONFIG_H +#include + +#ifdef __LITTLE_ENDIAN__ +#define __DO_SWAP_BYTES +#endif /* _DO_SWAP_BYTES */ +#define CAMMY_INSTALL_PREFIX "$PREFIX" +#endif /* _CONFIG_H */ +EOF +} + +create_common_build_mk() { + if [ "$DEBUG" = 1 ]; then + cat < mk/build.mk +PREFIX = $PREFIX + +CGFLAGS = -g -fno-inline +EOF + else + cat < mk/build.mk +PREFIX = $PREFIX + +CGFLAGS = +EOF + fi +} + +create_linux_build_mk() { + create_common_build_mk $@ + + cat <<'EOF' >> mk/build.mk +LLFLAGS = -shared -Wl,-soname=$(SONAME) + +SONAME_SHORT = lib$(LIBNAME).so +SONAME = $(SONAME_SHORT).$(VERSION_MAJOR) +SONAME_FULL = $(SONAME_SHORT).$(VERSION) +EOF +} + +create_darwin_build_mk() { + create_common_build_mk $@ + + cat <<'EOF' >> mk/build.mk +LLFLAGS = -dynamiclib -current_version $(VERSION) + +STATIC = lib$(LIBNAME).a + +SONAME_SHORT = $(LIBNAME).dylib +SONAME = lib$(LIBNAME).$(VERSION_MAJOR).dylib +SONAME_FULL = lib$(LIBNAME).$(VERSION).dylib +EOF +} + +for arg in $@; do + case $arg in + "--enable-debug") + DEBUG=1 + ;; + esac +done + +if [ ! -d "mk" ]; then + mkdir -m 0755 mk +fi + +case $OS in + Linux) + create_linux_config_h + create_linux_build_mk + ;; + + Darwin) + create_darwin_config_h + create_darwin_build_mk + ;; +esac diff --git a/include/cammy/sram.h b/include/cammy/sram.h new file mode 100644 index 0000000..0436cf8 --- /dev/null +++ b/include/cammy/sram.h @@ -0,0 +1,69 @@ +#ifndef _CAMMY_SRAM_H +#define _CAMMY_SRAM_H + +#include + +#define CAMMY_SRAM_SCRATCH_SIZE 4604 +#define CAMMY_SRAM_SCRATCH_2_SIZE 4 +#define CAMMY_SRAM_TILE_SIZE 16 +#define CAMMY_SRAM_PHOTO_SIZE 3584 +#define CAMMY_SRAM_THUMB_SIZE 256 + +#define CAMMY_SRAM_PHOTO_TILES_WIDTH 16 +#define CAMMY_SRAM_PHOTO_TILES_HEIGHT 14 + +#define CAMMY_SRAM_THUMB_TILES_WIDTH 4 +#define CAMMY_SRAM_THUMB_TILES_HEIGHT 4 + +#define CAMMY_SRAM_INFO_SIZE 256 + +#define CAMMY_SRAM_FRAME_COUNT 30 + +#pragma pack(1) +#pragma pack(push) + +typedef struct _cammy_sram_tile { + uint8_t data[CAMMY_SRAM_TILE_SIZE]; +} cammy_sram_tile; + +typedef struct _cammy_sram_thumb { + cammy_sram_tile rows[CAMMY_SRAM_THUMB_TILES_HEIGHT] + [CAMMY_SRAM_THUMB_TILES_WIDTH]; +} cammy_sram_thumb; + +typedef struct _cammy_sram_photo { + cammy_sram_tile rows[CAMMY_SRAM_PHOTO_TILES_HEIGHT] + [CAMMY_SRAM_PHOTO_TILES_WIDTH]; +} cammy_sram_photo; + +typedef struct _cammy_sram_frame { + cammy_sram_photo photo; + cammy_sram_thumb thumb; + uint8_t info[CAMMY_SRAM_INFO_SIZE]; +} cammy_sram_frame; + +typedef struct _cammy_sram_data { + uint8_t scratch[CAMMY_SRAM_SCRATCH_SIZE]; + cammy_sram_photo gameface; + uint8_t scratch_2[CAMMY_SRAM_SCRATCH_2_SIZE]; + + cammy_sram_frame frames[CAMMY_SRAM_FRAME_COUNT]; +} cammy_sram_data; + +typedef struct _cammy_sram { + int fd; + + cammy_sram_data *data; + + size_t size, + page_size, + mapped_size; +} cammy_sram; + +#pragma pack(pop) + +cammy_sram *cammy_sram_open(const char *file); + +void cammy_sram_close(cammy_sram *sram); + +#endif /* _CAMMY_SRAM_H */ diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..1bb0e59 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,32 @@ +include ../mk/build.mk + +INCLUDE_PATH = ../include +HEADER_SUBDIR = cammy + +CC = $(CROSS)cc +CFLAGS = $(CGFLAGS) -fPIC -Wall -O2 -I$(INCLUDE_PATH) +LDFLAGS = + +HEADERS = sram.h +OBJS = sram.o test.o + +PROGRAM = test + +AR = $(CROSS)ar +RANLIB = $(CROSS)ranlib + +RM = /bin/rm +LN = /bin/ln +RMDIR = /bin/rmdir +INSTALL = /usr/bin/install + +all: $(PROGRAM) + +$(PROGRAM): $(OBJS) + $(CC) $(LDFLAGS) $(OBJS) -o $(PROGRAM) + +$(OBJS): %.o: %.c $(HEADERS_BUILD) + $(CC) $(CFLAGS) -c $< + +clean: + $(RM) -f $(PROGRAM) $(OBJS) diff --git a/src/sram.c b/src/sram.c new file mode 100644 index 0000000..661d95b --- /dev/null +++ b/src/sram.c @@ -0,0 +1,63 @@ +#include +#include +#include +#include +#include +#include + +#include + +static inline size_t _mapped_size(size_t size, size_t page_size) { + return size + (page_size - (size % page_size)); +} + +cammy_sram *cammy_sram_open(const char *file) { + cammy_sram *sram; + struct stat st; + + if ((sram = malloc(sizeof(*sram))) == NULL) { + goto error_malloc_sram; + } + + if ((sram->fd = open(file, O_RDONLY)) < 0) { + goto error_open; + } + + if (fstat(sram->fd, &st) < 0) { + goto error_stat; + } + + if (st.st_size < sizeof(cammy_sram_data)) { + errno = EINVAL; + + goto error_invalid_file; + } + + sram->size = st.st_size; + sram->page_size = (size_t)sysconf(_SC_PAGESIZE); + sram->mapped_size = _mapped_size(st.st_size, sram->page_size); + + if ((sram->data = mmap(NULL, sram->mapped_size, + PROT_READ, MAP_PRIVATE, sram->fd, 0)) == NULL) { + goto error_mmap; + } + + return sram; + +error_mmap: +error_invalid_file: +error_stat: + close(sram->fd); + +error_open: + free(sram); + +error_malloc_sram: + return NULL; +} + +void cammy_sram_close(cammy_sram *sram) { + munmap(sram->data, sram->mapped_size); + close(sram->fd); + free(sram); +} diff --git a/src/test.c b/src/test.c new file mode 100644 index 0000000..bb97136 --- /dev/null +++ b/src/test.c @@ -0,0 +1,44 @@ +#include +#include +#include +#include +#include + +#include + +static void usage(int argc, char **argv, const char *message, ...) { + if (message) { + va_list args; + + va_start(args, message); + vfprintf(stderr, message, args); + va_end(args); + fprintf(stderr, "\n"); + } + + fprintf(stderr, "usage: %s file.sav\n", argv[0]); + + exit(1); +} + +int main(int argc, char **argv) { + cammy_sram *sram; + + if (argc != 2) { + usage(argc, argv, "No save file provided"); + } + + if ((sram = cammy_sram_open(argv[1])) == NULL) { + fprintf(stderr, "%s: %s: %s: %s\n", + argv[0], "cammy_sram_open()", argv[1], strerror(errno)); + + goto error_sram_open; + } + + cammy_sram_close(sram); + + return 0; + +error_sram_open: + return 1; +}