diff --git a/Makefile b/Makefile index e67e9891d9..2da091af2c 100644 --- a/Makefile +++ b/Makefile @@ -92,7 +92,7 @@ ifeq ($(HAVE_CG), 1) endif ifeq ($(HAVE_XML), 1) - OBJ += gfx/shader_glsl.o gfx/image.o sha256.o cheats.o + OBJ += gfx/shader_glsl.o gfx/image.o gfx/snes_state.o sha256.o cheats.o LIBS += $(XML_LIBS) DEFINES += $(XML_CFLAGS) endif diff --git a/Makefile.win32 b/Makefile.win32 index d294194b1c..143288d088 100644 --- a/Makefile.win32 +++ b/Makefile.win32 @@ -58,7 +58,7 @@ ifeq ($(HAVE_RSOUND), 1) endif ifeq ($(HAVE_XML), 1) - OBJ += gfx/shader_glsl.o gfx/image.o sha256.o cheats.o + OBJ += gfx/shader_glsl.o gfx/image.o gfx/snes_state.o sha256.o cheats.o DEFINES += $(XML_CFLAGS) -DHAVE_XML LIBS += -lxml2 endif diff --git a/Makefile.win64 b/Makefile.win64 index f28c51dd0c..161a9c5998 100644 --- a/Makefile.win64 +++ b/Makefile.win64 @@ -58,7 +58,7 @@ ifeq ($(HAVE_RSOUND), 1) endif ifeq ($(HAVE_XML), 1) - OBJ += gfx/shader_glsl.o gfx/image.o sha256.o cheats.o + OBJ += gfx/shader_glsl.o gfx/image.o gfx/snes_state.o sha256.o cheats.o DEFINES += $(XML_CFLAGS) -DHAVE_XML -DLIBXML_STATIC LIBS += -lxml2 -lz -lws2_32 endif diff --git a/gfx/snes_state.c b/gfx/snes_state.c new file mode 100644 index 0000000000..591d58e418 --- /dev/null +++ b/gfx/snes_state.c @@ -0,0 +1,142 @@ +/* SSNES - A Super Nintendo Entertainment System (SNES) Emulator frontend for libsnes. + * Copyright (C) 2010-2011 - Hans-Kristian Arntzen + * + * Some code herein may be based on code found in BSNES. + * + * SSNES is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * SSNES is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with SSNES. + * If not, see . + */ + +#include "snes_state.h" +#include +#include +#include "strl.h" + +struct snes_tracker_internal +{ + char id[64]; + + const uint8_t *ptr; + uint32_t addr; + + enum snes_tracker_type type; + + uint8_t prev[2]; + int frame_count; + uint8_t old_value; +}; + +struct snes_tracker +{ + struct snes_tracker_internal *info; + unsigned info_elem; +}; + +snes_tracker_t* snes_tracker_init(const struct snes_tracker_info *info) +{ + snes_tracker_t *tracker = calloc(1, sizeof(*tracker)); + if (!tracker) + return NULL; + + tracker->info = calloc(info->info_elem, sizeof(struct snes_tracker_internal)); + tracker->info_elem = info->info_elem; + + for (unsigned i = 0; i < info->info_elem; i++) + { + strlcpy(tracker->info[i].id, info->info[i].id, sizeof(tracker->info[i].id)); + tracker->info[i].addr = info->info[i].addr; + tracker->info[i].type = info->info[i].type; + + assert(info->wram && info->vram && info->cgram && + info->oam && info->apuram); + + switch (info->info[i].ram_type) + { + case SSNES_STATE_WRAM: + tracker->info[i].ptr = info->wram; + break; + case SSNES_STATE_APURAM: + tracker->info[i].ptr = info->apuram; + break; + case SSNES_STATE_OAM: + tracker->info[i].ptr = info->oam; + break; + case SSNES_STATE_CGRAM: + tracker->info[i].ptr = info->cgram; + break; + case SSNES_STATE_VRAM: + tracker->info[i].ptr = info->vram; + break; + + default: + tracker->info[i].ptr = NULL; + } + } + + + return tracker; +} + +void snes_tracker_free(snes_tracker_t *tracker) +{ + free(tracker->info); + free(tracker); +} + +static void update_element( + struct snes_tracker_uniform *uniform, + struct snes_tracker_internal *info, + unsigned frame_count) +{ + uniform->id = info->id; + + switch (info->type) + { + case SSNES_STATE_CAPTURE: + uniform->value = info->ptr[info->addr]; + break; + + case SSNES_STATE_TRANSITION: + if (info->old_value != info->ptr[info->addr]) + { + info->old_value = info->ptr[info->addr]; + info->frame_count = frame_count; + uniform->value = info->frame_count; + } + else + uniform->value = info->frame_count; + + break; + + case SSNES_STATE_CAPTURE_PREV: + if (info->prev[0] != info->ptr[info->addr]) + { + info->prev[1] = info->prev[0]; + info->prev[0] = info->ptr[info->addr]; + } + uniform->value = info->prev[1]; + break; + + default: + break; + } +} + +unsigned snes_get_uniform(snes_tracker_t *tracker, struct snes_tracker_uniform *uniforms, unsigned elem, unsigned frame_count) +{ + unsigned elems = tracker->info_elem < elem ? tracker->info_elem : elem; + + for (unsigned i = 0; i < elems; i++) + update_element(&uniforms[i], &tracker->info[i], frame_count); + + return elems; +} + diff --git a/gfx/snes_state.h b/gfx/snes_state.h new file mode 100644 index 0000000000..fbb6cb449d --- /dev/null +++ b/gfx/snes_state.h @@ -0,0 +1,72 @@ +/* SSNES - A Super Nintendo Entertainment System (SNES) Emulator frontend for libsnes. + * Copyright (C) 2010-2011 - Hans-Kristian Arntzen + * + * Some code herein may be based on code found in BSNES. + * + * SSNES is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * SSNES is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with SSNES. + * If not, see . + */ + +#ifndef __SSNES_SNES_STATE_H +#define __SSNES_SNES_STATE_H + +#include + +enum snes_tracker_type +{ + SSNES_STATE_CAPTURE, + SSNES_STATE_TRANSITION, + SSNES_STATE_CAPTURE_PREV +}; + +enum snes_ram_type +{ + SSNES_STATE_WRAM, + SSNES_STATE_APURAM, + SSNES_STATE_OAM, + SSNES_STATE_CGRAM, + SSNES_STATE_VRAM +}; + +struct snes_tracker_uniform_info +{ + const char *id; + uint32_t addr; + enum snes_tracker_type type; + enum snes_ram_type ram_type; +}; + +struct snes_tracker_info +{ + const uint8_t *wram; + const uint8_t *vram; + const uint8_t *cgram; + const uint8_t *oam; + const uint8_t *apuram; + + const struct snes_tracker_uniform_info *info; + unsigned info_elem; +}; + +struct snes_tracker_uniform +{ + const char *id; + int value; +}; + +typedef struct snes_tracker snes_tracker_t; + +snes_tracker_t* snes_tracker_init(const struct snes_tracker_info *info); +void snes_tracker_free(snes_tracker_t *tracker); + +unsigned snes_get_uniform(snes_tracker_t *tracker, struct snes_tracker_uniform *uniforms, unsigned elem, unsigned frame_count); + +#endif