fixed audio/video synchronization, preliminary GX gui implementation

This commit is contained in:
ekeeke31 2009-02-22 19:57:41 +00:00
parent 7cd6346927
commit 6f65ac3f15
35 changed files with 1149 additions and 10542 deletions

View File

@ -18,15 +18,15 @@ include $(DEVKITPPC)/gamecube_rules
TARGET := genplus_cube TARGET := genplus_cube
BUILD := build_cube BUILD := build_cube
SOURCES := source source/m68k source/z80 source/sound source/sound/SRC source/ntsc \ SOURCES := source source/m68k source/z80 source/sound source/sound/SRC source/ntsc \
source/cart_hw source/cart_hw/svp source/ngc source/ngc/gui source/ngc/fileio source/cart_hw source/cart_hw/svp source/ngc source/ngc/gui source/ngc/fileio source/ngc/png
INCLUDES := source source/m68k source/z80 source/sound source/sound/SRC source/ntsc \ INCLUDES := source source/m68k source/z80 source/sound source/sound/SRC source/ntsc \
source/cart_hw source/cart_hw/svp source/ngc source/ngc/gui source/ngc/fileio source/cart_hw source/cart_hw/svp source/ngc source/ngc/gui source/ngc/fileio source/ngc/png
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# options for code generation # options for code generation
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
CFLAGS = -O3 -fomit-frame-pointer -Wall $(MACHDEP) $(INCLUDE) -DWORDS_BIGENDIAN -DNGC="1" -DHW_DOL CFLAGS = -O3 -fomit-frame-pointer -Wall -Wno-strict-aliasing $(MACHDEP) $(INCLUDE) -DWORDS_BIGENDIAN -DNGC="1" -DHW_DOL
CXXFLAGS = $(CFLAGS) CXXFLAGS = $(CFLAGS)
LDFLAGS = $(MACHDEP) -Wl,-Map,$(notdir $@).map LDFLAGS = $(MACHDEP) -Wl,-Map,$(notdir $@).map
@ -34,7 +34,7 @@ LDFLAGS = $(MACHDEP) -Wl,-Map,$(notdir $@).map
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project # any extra libraries we wish to link with the project
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
LIBS := -lfat -logc -lm -lz LIBS := -lpng -lfat -logc -lm -lz
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing # list of directories containing libraries, this must be the top level containing

View File

@ -17,10 +17,10 @@ include $(DEVKITPPC)/wii_rules
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
TARGET := genplus_wii TARGET := genplus_wii
BUILD := build_wii BUILD := build_wii
SOURCES := source source/m68k source/z80 source/sound source/sound/SRC source/ntsc \ SOURCES := source source/m68k source/z80 source/sound source/sound/SRC source/ntsc source/cart_hw source/cart_hw/svp \
source/cart_hw source/cart_hw/svp source/ngc source/ngc/gui source/ngc/fileio source/ngc source/ngc/gui source/ngc/fileio source/ngc/png
INCLUDES := source source/m68k source/z80 source/sound source/sound/SRC source/ntsc \ INCLUDES := source source/m68k source/z80 source/sound source/sound/SRC source/ntsc source/cart_hw source/cart_hw/svp \
source/cart_hw source/cart_hw/svp source/ngc source/ngc/gui source/ngc/fileio source/ngc source/ngc/gui source/ngc/fileio source/ngc/png
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# options for code generation # options for code generation
@ -34,7 +34,7 @@ LDFLAGS = $(MACHDEP) -Wl,-Map,$(notdir $@).map
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project # any extra libraries we wish to link with the project
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
LIBS := -ldi -lfat -lwiiuse -lbte -logc -lm -lz LIBS := -lpng -ldi -lfat -lwiiuse -lbte -logc -lm -lz
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing # list of directories containing libraries, this must be the top level containing

View File

@ -185,8 +185,6 @@ void gen_busreq_w (uint32 state)
{ {
uint32 z80_cycles_to_run; uint32 z80_cycles_to_run;
input_raz (); /* from Gens */
if (state) if (state)
{ {
/* Bus Request */ /* Bus Request */

View File

@ -23,9 +23,9 @@
#include "shared.h" #include "shared.h"
#ifdef HW_RVL #ifdef HW_RVL
#define CONFIG_VERSION "GENPLUS 1.3.0W" #define CONFIG_VERSION "GENPLUS 1.3.1W"
#else #else
#define CONFIG_VERSION "GENPLUS 1.3.0G" #define CONFIG_VERSION "GENPLUS 1.3.1G"
#endif #endif
void config_save() void config_save()
@ -78,8 +78,8 @@ void set_config_defaults(void)
strncpy(config.version,CONFIG_VERSION,15); strncpy(config.version,CONFIG_VERSION,15);
/* sound options */ /* sound options */
config.psg_preamp = 1.5; config.psg_preamp = 150;
config.fm_preamp = 1.0; config.fm_preamp = 100;
config.boost = 1; config.boost = 1;
config.hq_fm = 1; config.hq_fm = 1;
config.filter = 1; config.filter = 1;

View File

@ -50,7 +50,7 @@ static void ShowFiles (int offset, int selection)
int i, j; int i, j;
char text[MAXJOLIET+2]; char text[MAXJOLIET+2];
ClearScreen (); ClearScreen ((GXColor)BLACK);
j = 0; j = 0;
for (i = offset; i < (offset + PAGESIZE) && (i < maxfiles); i++) for (i = offset; i < (offset + PAGESIZE) && (i < maxfiles); i++)

View File

@ -1,877 +0,0 @@
/*******************************************************************
* Image File : /public/dkpro.bmp
* Width : 218
* Height : 65
*
* This header contains a compressed Zip image.
* Use zlib1.2.3 uncompress function to restore.
*******************************************************************/
#define dkpro_RAW 28340
#define dkpro_COMPRESSED 6887
#define dkpro_WIDTH 218
#define dkpro_HEIGHT 65
unsigned char dkpro[6887] = {
0x78, 0xda, 0xed, 0x9c, 0x67, 0x70, 0x54, 0x57, 0x96, 0xc7, 0xf9, 0xb8,
0xb5, 0x55, 0xbb, 0x55,
0x53, 0xb5, 0xb5, 0xb3, 0x9e, 0x31, 0xc6, 0x98, 0x20, 0x31, 0xf6, 0x38,
0x7b, 0xc6, 0x33, 0x0e,
0xe3, 0x34, 0x60, 0x03, 0x36, 0xc9, 0x80, 0x49, 0xb6, 0x41, 0x42, 0x59,
0x42, 0x39, 0x20, 0x75,
0xbf, 0xd3, 0x92, 0x90, 0x84, 0x32, 0x41, 0x02, 0x11, 0xd4, 0x48, 0xe4,
0x60, 0x72, 0x0e, 0x22,
0x98, 0x8c, 0x8d, 0x04, 0x26, 0x83, 0x31, 0xe0, 0xec, 0x71, 0x06, 0xe7,
0xa0, 0xfd, 0xdd, 0xdb,
0xdd, 0xaf, 0x5f, 0xb7, 0xba, 0x07, 0x30, 0xc6, 0xf6, 0x87, 0xd6, 0xbf,
0x1e, 0xb4, 0x6e, 0x38,
0xf7, 0xe4, 0x7b, 0xee, 0x7b, 0x4f, 0xdd, 0x4e, 0xda, 0x5d, 0x1d, 0xaa,
0xc3, 0x52, 0xba, 0x38,
0x3b, 0x46, 0x75, 0x70, 0xb6, 0x8f, 0xbd, 0xb1, 0xfe, 0xc6, 0xf8, 0x3f,
0x3a, 0x6f, 0x8c, 0x6f,
0xef, 0xbc, 0x29, 0xb6, 0xa3, 0xb3, 0x53, 0x74, 0x57, 0x67, 0xb7, 0x88,
0x76, 0x12, 0xc2, 0x6f,
0x06, 0x55, 0xe1, 0xd8, 0xea, 0xe6, 0xa8, 0x3f, 0x38, 0xc3, 0x62, 0xfa,
0xd5, 0x94, 0xc4, 0x2f,
0x28, 0xdd, 0x91, 0x71, 0x74, 0xdc, 0xf9, 0xdc, 0x0b, 0x85, 0xa7, 0x72,
0x0f, 0x8c, 0x5f, 0x95,
0x59, 0x37, 0x29, 0x32, 0xf1, 0xfe, 0xfa, 0x3f, 0xc4, 0xb4, 0x77, 0x76,
0x8a, 0x09, 0x9b, 0x15,
0xb2, 0xdd, 0xaf, 0x6f, 0xaf, 0xb0, 0x94, 0x9b, 0x89, 0xa3, 0xbe, 0x93,
0x9d, 0x09, 0xef, 0x39,
0x5a, 0xed, 0xad, 0x12, 0x0c, 0x3f, 0xca, 0x8e, 0xca, 0x84, 0x94, 0xdb,
0x9d, 0xed, 0xa3, 0xba,
0x84, 0xec, 0xf6, 0x6b, 0xda, 0x2b, 0xf5, 0x26, 0x67, 0x58, 0x74, 0xe5,
0xf8, 0x7f, 0x65, 0x6a,
0xab, 0x18, 0xdf, 0x49, 0x50, 0x18, 0x3f, 0xb8, 0x6c, 0x37, 0x6e, 0x5d,
0xee, 0xd3, 0x33, 0x6e,
0x88, 0xeb, 0xec, 0xec, 0x16, 0x19, 0xd2, 0xe0, 0x2f, 0x9f, 0x0f, 0x3b,
0xd4, 0xdf, 0x1b, 0x35,
0xaf, 0xa8, 0x75, 0x6c, 0x2b, 0xf6, 0xf8, 0xc6, 0xf8, 0x46, 0x3c, 0xf8,
0x9e, 0x98, 0xf2, 0x46,
0xd7, 0x0f, 0xf2, 0xad, 0x78, 0xfb, 0xbe, 0x33, 0x68, 0xcd, 0x3f, 0x69,
0x1b, 0x36, 0xfd, 0xa6,
0xd8, 0x2e, 0xd5, 0xed, 0x52, 0x43, 0x9a, 0xfc, 0x85, 0x50, 0xdd, 0x2d,
0xa5, 0xb3, 0xb3, 0x43,
0x74, 0x69, 0x49, 0x6b, 0x76, 0xab, 0xf1, 0xb5, 0x7c, 0xa5, 0xa1, 0x6c,
0xe5, 0xb2, 0xd3, 0x27,
0x72, 0x52, 0xf6, 0xcb, 0x36, 0x69, 0x92, 0x5d, 0x72, 0x48, 0xde, 0x96,
0x1f, 0xdc, 0xd6, 0xfb,
0x56, 0xdc, 0x63, 0x0d, 0x6c, 0x5a, 0xb0, 0x3b, 0xef, 0xfe, 0xfa, 0x9b,
0xa2, 0xc3, 0xab, 0xda,
0xa5, 0x84, 0x34, 0x7a, 0xfd, 0xd1, 0xcd, 0xd9, 0x61, 0x74, 0x8f, 0xca,
0x8f, 0x53, 0x5b, 0x8d,
0xaf, 0xe4, 0x4b, 0x8d, 0x6f, 0xb0, 0xc9, 0xb7, 0x72, 0x5c, 0xe6, 0x48,
0x86, 0x3c, 0x2b, 0x4f,
0x4b, 0x5f, 0xe9, 0x2f, 0x03, 0x40, 0x7f, 0xe9, 0x27, 0x7d, 0xf8, 0x3d,
0x5a, 0x2a, 0x65, 0x27,
0xb6, 0x6c, 0xc5, 0xae, 0xae, 0x19, 0x5f, 0x2a, 0xbb, 0x95, 0x8c, 0xcf,
0xea, 0xe8, 0x0c, 0x8b,
0x0a, 0x69, 0xf4, 0x7a, 0xc7, 0x58, 0x58, 0xca, 0x1f, 0xa7, 0x94, 0x24,
0xfd, 0x68, 0xff, 0x46,
0x2e, 0x6a, 0x7c, 0x85, 0x25, 0x3e, 0x90, 0x06, 0x19, 0x8d, 0xb5, 0x06,
0xcb, 0x70, 0x79, 0x41,
0x5e, 0x6c, 0x83, 0x11, 0x32, 0x84, 0xde, 0x61, 0x32, 0x4e, 0x5e, 0xd5,
0xd6, 0xbd, 0xa4, 0x67,
0x5e, 0x22, 0x4f, 0x1e, 0x9a, 0x78, 0x4b, 0xca, 0xef, 0x9d, 0x37, 0x24,
0xdd, 0xe0, 0xbc, 0x21,
0x31, 0x74, 0x5d, 0xdb, 0xd5, 0xa1, 0xaa, 0x5d, 0x7a, 0x20, 0x9b, 0x85,
0xcd, 0xea, 0x34, 0x7a,
0x4d, 0x61, 0x6b, 0xee, 0xe7, 0xc6, 0x67, 0xf2, 0x99, 0x7c, 0x4e, 0xdc,
0x9c, 0x93, 0x72, 0xe2,
0x69, 0x08, 0x96, 0x19, 0x75, 0x19, 0x8c, 0xc4, 0x76, 0x03, 0x24, 0x81,
0xac, 0xf9, 0x9d, 0x7c,
0x21, 0x9f, 0x69, 0x7c, 0x65, 0x04, 0xaf, 0x34, 0x43, 0xb8, 0x3a, 0xac,
0x99, 0xdc, 0x21, 0xb9,
0x6d, 0xdd, 0xd1, 0x35, 0xb5, 0xc3, 0xc4, 0xe6, 0x94, 0xef, 0xed, 0x9f,
0x88, 0xc2, 0x25, 0x62,
0xac, 0x51, 0x86, 0x62, 0x89, 0xc8, 0xab, 0xc0, 0x48, 0x79, 0x4e, 0xc6,
0xca, 0x19, 0xec, 0xf6,
0xa9, 0x7c, 0x12, 0xc2, 0xcf, 0x05, 0xea, 0x8a, 0x39, 0x35, 0x1d, 0x92,
0xda, 0xc6, 0x58, 0x97,
0xc8, 0x23, 0xf2, 0x95, 0xfd, 0x43, 0x51, 0xf8, 0x42, 0x8e, 0x92, 0x0f,
0x87, 0x73, 0x45, 0x5d,
0x35, 0x46, 0x92, 0x45, 0x17, 0x90, 0x1d, 0x3f, 0x96, 0x0f, 0x43, 0xf8,
0x79, 0x60, 0x7c, 0x21,
0x8d, 0x35, 0x37, 0x27, 0xf9, 0xd7, 0xf6, 0xed, 0x27, 0xee, 0x4e, 0xbd,
0x64, 0x7f, 0x5f, 0xde,
0x67, 0xff, 0xfa, 0x5a, 0x56, 0x90, 0x0d, 0x47, 0x4b, 0xec, 0x4f, 0x44,
0x8c, 0x3c, 0x2f, 0x42,
0xa4, 0xaa, 0x5a, 0x32, 0x84, 0x6b, 0xc3, 0x87, 0x58, 0xe4, 0x7d, 0xe3,
0x73, 0x69, 0xf0, 0xb3,
0x99, 0xaa, 0x15, 0xe7, 0x17, 0x7c, 0x99, 0xf7, 0xae, 0xbc, 0x2b, 0xef,
0x11, 0x8b, 0x33, 0x89,
0xb0, 0x38, 0x89, 0xbf, 0x26, 0x44, 0x63, 0x37, 0xb5, 0xcb, 0x85, 0x70,
0x2d, 0x18, 0x28, 0x47,
0x88, 0xa1, 0x77, 0x8d, 0x4f, 0xc5, 0xe9, 0x67, 0xb3, 0x9b, 0xa7, 0x66,
0xc4, 0x7d, 0x61, 0x7f,
0xdb, 0xf1, 0x16, 0xe7, 0xad, 0xcf, 0x64, 0xaa, 0x44, 0x48, 0xa2, 0x24,
0x5d, 0x33, 0x12, 0x43,
0xb8, 0x66, 0x8c, 0x94, 0x63, 0xc4, 0xd1, 0x5b, 0xc6, 0x47, 0x52, 0x6f,
0xb5, 0x59, 0x75, 0x97,
0xd4, 0xbf, 0x95, 0x5f, 0x4c, 0xbf, 0x60, 0x9c, 0x97, 0xf3, 0xd8, 0x74,
0x16, 0x95, 0x44, 0x4a,
0x08, 0xbf, 0x11, 0x44, 0xc9, 0x6b, 0xf2, 0x96, 0x9c, 0x37, 0x3e, 0x90,
0xe9, 0x35, 0x1d, 0x4d,
0x9b, 0x85, 0x3b, 0x3b, 0x8e, 0xde, 0xe6, 0x78, 0xdb, 0x7e, 0x56, 0xce,
0x62, 0xd1, 0xd5, 0xec,
0x46, 0x69, 0x57, 0x81, 0x74, 0x13, 0x69, 0xd7, 0x1d, 0xe9, 0x57, 0xb9,
0x5a, 0xaa, 0xbe, 0x52,
0xaf, 0x61, 0x95, 0xf4, 0x5f, 0x54, 0xbe, 0x40, 0x88, 0x91, 0x43, 0x44,
0xd2, 0x59, 0xe3, 0x5d,
0x99, 0x66, 0xb1, 0xd9, 0x2d, 0x75, 0xa9, 0x71, 0x1f, 0xd8, 0x4f, 0x3b,
0x4e, 0xcb, 0x1b, 0xd2,
0xcc, 0xf9, 0x2a, 0x53, 0xb2, 0xae, 0x10, 0x99, 0x3e, 0x92, 0xa4, 0x4b,
0xc6, 0x15, 0xcf, 0xbc,
0x7a, 0x64, 0xfa, 0x69, 0x2d, 0xfd, 0xdf, 0xf2, 0x99, 0x89, 0xa5, 0xd4,
0x8e, 0xea, 0xaa, 0x63,
0xa3, 0xf1, 0xc3, 0x64, 0x66, 0x5c, 0xfd, 0x2a, 0x69, 0x7e, 0xf2, 0x65,
0x5e, 0x47, 0x09, 0x03,
0x23, 0x41, 0x0e, 0x12, 0x4b, 0xa7, 0x8d, 0x37, 0x65, 0xaa, 0xc7, 0x66,
0xd4, 0x8b, 0xb7, 0x54,
0x9d, 0x4d, 0x3f, 0x65, 0x9c, 0x90, 0x93, 0xf4, 0x8d, 0x83, 0xab, 0xb1,
0x57, 0x88, 0x2c, 0x19,
0x23, 0x2f, 0xc8, 0x30, 0xce, 0xdb, 0x0a, 0xc3, 0xa9, 0x33, 0xd3, 0x25,
0xfb, 0x8a, 0x67, 0x5f,
0x1d, 0x72, 0xd0, 0x57, 0x2c, 0x27, 0xc5, 0xa1, 0xe6, 0x6a, 0xa3, 0x69,
0xc9, 0x09, 0x3a, 0x3e,
0x93, 0x9d, 0x40, 0x5d, 0xb1, 0x54, 0x52, 0xb1, 0x58, 0x2f, 0x8d, 0x2c,
0x93, 0xa6, 0xc7, 0xe7,
0xc0, 0xa3, 0xb2, 0x4d, 0x86, 0x86, 0xb2, 0x81, 0x97, 0xe7, 0x6c, 0x2c,
0xfd, 0xa2, 0x29, 0x91,
0x15, 0x43, 0x59, 0xf1, 0x79, 0xf6, 0x0c, 0x65, 0xfb, 0x8c, 0xeb, 0x26,
0x65, 0x20, 0x24, 0xcb,
0x2b, 0x72, 0x5a, 0x4e, 0xb0, 0x6f, 0xd5, 0xd6, 0xba, 0x6c, 0xd6, 0x6d,
0x56, 0xc7, 0x48, 0x5b,
0xd1, 0xf9, 0x9c, 0x23, 0x54, 0x27, 0xa7, 0x39, 0x53, 0x65, 0x88, 0xed,
0x8a, 0xa1, 0xfc, 0x6e,
0xbf, 0x6c, 0x91, 0xcd, 0x1a, 0x4d, 0xf2, 0x2a, 0x3a, 0xcd, 0x11, 0xfb,
0x55, 0x50, 0xb8, 0x72,
0xe4, 0xa2, 0x77, 0xa7, 0xec, 0x34, 0x57, 0xdb, 0x2e, 0x6b, 0xa9, 0x93,
0xc6, 0x06, 0x1d, 0x9f,
0x49, 0x74, 0xf9, 0xde, 0x45, 0xa8, 0x46, 0xe3, 0x36, 0xb8, 0xcb, 0xc1,
0xd3, 0x46, 0x70, 0xee,
0x1f, 0xa4, 0x31, 0x84, 0x3d, 0x3e, 0x03, 0xea, 0x36, 0xdd, 0x97, 0xc9,
0x2a, 0x07, 0x90, 0x64,
0x73, 0x1b, 0x34, 0xc9, 0x4a, 0x99, 0x27, 0xe5, 0xd8, 0x7d, 0x04, 0x67,
0xcf, 0x04, 0x2c, 0x9d,
0x7b, 0x5d, 0xe4, 0x0c, 0xa4, 0xe5, 0xfd, 0x72, 0x5c, 0x8e, 0x18, 0x67,
0x64, 0xb2, 0x3b, 0xce,
0xc2, 0x9d, 0x5d, 0x22, 0x0f, 0x18, 0x47, 0x8c, 0x43, 0x72, 0x98, 0xbd,
0x6e, 0xac, 0x18, 0x72,
0xa5, 0x3f, 0x06, 0x3e, 0x99, 0xe2, 0xa7, 0x97, 0xdb, 0xd0, 0xc8, 0xf5,
0xf9, 0xb1, 0xa1, 0xdb,
0x26, 0x9f, 0xb5, 0xde, 0x94, 0x87, 0xd0, 0x72, 0xb0, 0x9f, 0x4c, 0xa2,
0xe2, 0x0b, 0xf9, 0xc1,
0x7c, 0xbe, 0xd7, 0x0a, 0xb7, 0x23, 0x34, 0xd7, 0x69, 0x52, 0x88, 0x77,
0x36, 0xbb, 0x71, 0x48,
0x5a, 0x88, 0x44, 0x97, 0xdc, 0x06, 0xd6, 0x7b, 0xfe, 0xb2, 0x77, 0x90,
0xbe, 0xc6, 0xaa, 0xd1,
0xc4, 0x62, 0x16, 0x3c, 0xfd, 0x12, 0x3f, 0x59, 0xb2, 0x07, 0xcb, 0x1c,
0x32, 0x4e, 0xca, 0xc4,
0x9a, 0x8e, 0x89, 0xca, 0x66, 0x9d, 0xa7, 0x45, 0xc4, 0xbe, 0x6e, 0x6f,
0x76, 0x34, 0x13, 0x67,
0x0d, 0x70, 0x5d, 0x70, 0x85, 0x28, 0xe4, 0x4a, 0xc3, 0x2b, 0x5b, 0x3d,
0xf7, 0xf1, 0x41, 0xab,
0xfc, 0x51, 0xf2, 0xe8, 0x29, 0xbc, 0x62, 0x2a, 0x57, 0xbe, 0x9a, 0x90,
0xb3, 0x56, 0xc9, 0x8f,
0xe6, 0x5a, 0xdf, 0xc9, 0x51, 0xb9, 0x5b, 0xf2, 0x03, 0xae, 0xa5, 0xda,
0x72, 0xb0, 0xd0, 0xa7,
0xe8, 0xd7, 0xcb, 0x9b, 0xca, 0xe3, 0xaa, 0x27, 0x85, 0x59, 0xea, 0xf9,
0x83, 0x0b, 0xad, 0x9c,
0xfb, 0x9f, 0xc0, 0x66, 0x8a, 0xeb, 0x7c, 0xf4, 0x33, 0xd8, 0x47, 0xa2,
0x40, 0xf8, 0x5a, 0x3f,
0x7b, 0x9a, 0x43, 0x8c, 0x8e, 0x15, 0xc7, 0xcf, 0x2e, 0x69, 0x5b, 0xe4,
0xc9, 0x6e, 0xfc, 0xaa,
0xd9, 0x38, 0x26, 0xd5, 0x6e, 0x9b, 0xdd, 0x34, 0x71, 0x69, 0x6a, 0x8b,
0x71, 0x80, 0x9c, 0xb9,
0x5f, 0x8a, 0xd8, 0xcd, 0x8a, 0x2e, 0x8b, 0x62, 0xa0, 0xfe, 0x1d, 0xa7,
0x33, 0x49, 0xab, 0x7c,
0x6e, 0xa2, 0x55, 0xda, 0xe3, 0xf9, 0x81, 0x66, 0x78, 0xe7, 0xfd, 0x34,
0x14, 0xc3, 0xfb, 0x48,
0x59, 0x21, 0xdf, 0x9a, 0x6b, 0x7d, 0x45, 0x5e, 0xb8, 0x87, 0xd6, 0x60,
0x34, 0xf3, 0xc8, 0x9c,
0x1f, 0x11, 0x69, 0x17, 0xdd, 0x50, 0x36, 0x8b, 0xd0, 0x12, 0xa6, 0xd0,
0xe7, 0xe5, 0xfa, 0x12,
0x67, 0x9b, 0xfb, 0x89, 0x98, 0x22, 0xdd, 0x97, 0x43, 0xae, 0xb4, 0x4a,
0x14, 0x1c, 0xad, 0x64,
0xea, 0x61, 0x78, 0xd2, 0xb8, 0x9f, 0x20, 0x4b, 0xb1, 0x45, 0x2b, 0x97,
0x87, 0x21, 0x3b, 0xd8,
0x75, 0x0e, 0x18, 0x87, 0xa5, 0xb2, 0x16, 0x9b, 0x55, 0x87, 0xa5, 0xdc,
0x56, 0x71, 0x32, 0x75,
0xaf, 0xec, 0x25, 0xde, 0x97, 0xb2, 0x7e, 0x69, 0x50, 0x94, 0x81, 0x52,
0x19, 0x2f, 0x25, 0x7a,
0xad, 0x12, 0x3e, 0x95, 0x92, 0xd1, 0x93, 0xd0, 0xa2, 0xf7, 0x9e, 0x58,
0xab, 0x74, 0x44, 0x8b,
0xae, 0x91, 0xbe, 0x33, 0xc6, 0xb9, 0x65, 0x73, 0xcd, 0xf3, 0x8c, 0x08,
0xbe, 0x8e, 0xff, 0x88,
0x32, 0x68, 0x44, 0xc1, 0xe1, 0x25, 0x73, 0xad, 0xcf, 0x90, 0xe3, 0x7e,
0xe8, 0x05, 0xa3, 0x95,
0x0f, 0x6f, 0xff, 0x72, 0x3f, 0x13, 0x72, 0xd9, 0x4c, 0xd5, 0x91, 0x6a,
0x6c, 0x06, 0x36, 0xfb,
0xc6, 0xa4, 0xf3, 0x09, 0x67, 0x9f, 0x07, 0xd0, 0xbd, 0x8b, 0x8a, 0x8d,
0x4a, 0xe3, 0xfb, 0x2b,
0xbc, 0x03, 0xf8, 0x23, 0xd6, 0xcf, 0x80, 0x83, 0xc0, 0x72, 0x28, 0xb9,
0x95, 0xb4, 0xe3, 0x03,
0x68, 0xa3, 0xc8, 0xad, 0x8f, 0x62, 0xb7, 0x36, 0x4a, 0xff, 0x8d, 0x3e,
0x4a, 0x89, 0xff, 0x6d,
0xb2, 0x4f, 0xf6, 0x1a, 0xcd, 0x52, 0xae, 0x6a, 0x90, 0xea, 0xce, 0xa9,
0x11, 0x25, 0xcd, 0x59,
0x3b, 0xd9, 0xdb, 0xf7, 0x4b, 0x0d, 0x3b, 0x6c, 0x45, 0x10, 0x54, 0x72,
0x95, 0xb3, 0x82, 0x50,
0x31, 0x25, 0xe3, 0xb1, 0x69, 0xd8, 0xab, 0x10, 0xaf, 0x4c, 0x42, 0x2b,
0xef, 0x9a, 0xf8, 0x5e,
0x6e, 0x81, 0x97, 0x4a, 0x0d, 0x35, 0xab, 0x4c, 0x7b, 0x49, 0x26, 0xe3,
0xe3, 0x75, 0xed, 0x36,
0x86, 0xdc, 0x63, 0xc0, 0x69, 0x99, 0x9b, 0x66, 0x39, 0x1c, 0x15, 0x61,
0xe5, 0x7c, 0x33, 0xa7,
0x95, 0x68, 0x1e, 0x5c, 0xab, 0x95, 0x40, 0xcb, 0xd3, 0x33, 0x8e, 0xbe,
0x18, 0x59, 0x2c, 0x1f,
0x9b, 0x6b, 0x7d, 0x88, 0x9f, 0xfd, 0x4d, 0x53, 0x2a, 0x63, 0x64, 0xa1,
0x39, 0x32, 0x9f, 0xb1,
0xc5, 0x9a, 0xd7, 0x6c, 0xe9, 0x21, 0x37, 0x49, 0x07, 0x8d, 0x9b, 0xc1,
0x7d, 0xd8, 0x4a, 0x71,
0xa4, 0xb8, 0xb8, 0x68, 0xd2, 0x79, 0x5f, 0xce, 0xc9, 0x5f, 0x90, 0x64,
0x9c, 0x5e, 0x5b, 0xd8,
0xcf, 0xbe, 0xb4, 0x48, 0xa4, 0x70, 0xc9, 0x8d, 0x4f, 0xf1, 0x01, 0x6b,
0xfb, 0x47, 0xb2, 0x4b,
0x06, 0x6a, 0x69, 0x8a, 0xcd, 0xf5, 0x0b, 0xa1, 0x5f, 0xaa, 0xa5, 0xb2,
0xe9, 0x3a, 0x3d, 0x9f,
0xcf, 0x15, 0xa6, 0x36, 0x4a, 0xdc, 0xfa, 0x8b, 0xd7, 0x77, 0x64, 0x93,
0xa8, 0x2e, 0x6c, 0x3a,
0x4e, 0xca, 0x4d, 0x8d, 0x05, 0x42, 0x09, 0x75, 0xd7, 0x2e, 0xd9, 0x49,
0x2e, 0x2c, 0xad, 0xb9,
0x25, 0x91, 0x9a, 0x71, 0x74, 0x4d, 0xc1, 0xee, 0xbc, 0xed, 0x54, 0x61,
0x5b, 0x99, 0x39, 0x31,
0x28, 0x26, 0x40, 0x73, 0x1c, 0xd2, 0xa6, 0xf0, 0x79, 0x31, 0x15, 0x54,
0x23, 0xdc, 0xc4, 0xea,
0x3a, 0xfa, 0x23, 0x64, 0xf6, 0xe0, 0x92, 0x74, 0x41, 0x57, 0xae, 0xf1,
0x55, 0x7c, 0xca, 0x65,
0x44, 0x3a, 0xf5, 0xda, 0x22, 0xd9, 0x48, 0xfd, 0xb0, 0x89, 0x99, 0x55,
0x50, 0x88, 0x25, 0x7f,
0x96, 0xd2, 0xaa, 0xc6, 0x14, 0xf3, 0x39, 0x85, 0x2a, 0x4c, 0x21, 0x09,
0xaf, 0x55, 0x3d, 0x13,
0x98, 0x5f, 0x05, 0xa7, 0x79, 0xcc, 0x4d, 0xd4, 0x3d, 0x63, 0xb0, 0xbb,
0xb0, 0xef, 0x2f, 0x40,
0x53, 0x9e, 0xb5, 0xde, 0x26, 0x63, 0x3c, 0xc4, 0xb8, 0x4a, 0xf4, 0x94,
0x61, 0xd2, 0x48, 0xe4,
0xd3, 0x58, 0xb4, 0x53, 0xae, 0xf5, 0x1f, 0x47, 0x75, 0x38, 0x50, 0x9e,
0x05, 0x83, 0xb0, 0x45,
0xaa, 0xf6, 0xef, 0x5c, 0x72, 0x6c, 0x16, 0xda, 0xf7, 0xd0, 0xb9, 0xc0,
0x09, 0xe7, 0x2f, 0xd0,
0xce, 0x40, 0xa2, 0x32, 0x68, 0x8d, 0xc4, 0x2f, 0xce, 0x59, 0xf0, 0x31,
0x19, 0x55, 0xdd, 0x8d,
0x48, 0x86, 0xaf, 0x3d, 0x96, 0x79, 0x0a, 0x5f, 0xca, 0x3f, 0xb1, 0x93,
0xb2, 0x4f, 0xaa, 0x7b,
0xfd, 0x64, 0x5d, 0x83, 0xd9, 0xb0, 0x4a, 0xae, 0x4c, 0x41, 0xee, 0x32,
0x56, 0x74, 0xc9, 0x53,
0x8a, 0xb7, 0xc6, 0xe1, 0xeb, 0x65, 0x48, 0xb1, 0x01, 0x2b, 0x6c, 0x95,
0x97, 0x64, 0x2a, 0x72,
0xc5, 0x60, 0xc5, 0x12, 0xfa, 0x27, 0x04, 0xd5, 0x7d, 0x05, 0x9a, 0xdb,
0x21, 0xdb, 0x8d, 0xbd,
0x52, 0x8c, 0xcd, 0xc2, 0x67, 0x75, 0x89, 0x58, 0x23, 0x5b, 0xed, 0x8a,
0xc2, 0x32, 0x66, 0xd5,
0x04, 0xc5, 0x04, 0x38, 0x8b, 0xa6, 0xd6, 0x3d, 0x8f, 0xae, 0x2e, 0xf0,
0xef, 0x9b, 0x68, 0xaf,
0x45, 0xd7, 0xcc, 0xef, 0x51, 0x83, 0x79, 0xf0, 0xb1, 0x84, 0xa1, 0x2b,
0xd7, 0xf8, 0xf1, 0xe8,
0xcf, 0x4e, 0x2c, 0xbc, 0xa9, 0x67, 0x78, 0xf4, 0xa3, 0x3e, 0x6f, 0xd5,
0xf7, 0x26, 0xca, 0xe0,
0xa6, 0x1a, 0xc9, 0x8e, 0xa0, 0xb3, 0xe3, 0x6e, 0xbc, 0x41, 0x6b, 0x1e,
0xed, 0x35, 0xf4, 0xe4,
0xc9, 0x5c, 0x79, 0xdd, 0xec, 0x39, 0x2f, 0x93, 0xc8, 0x5a, 0xf3, 0x98,
0xed, 0x59, 0xeb, 0x1c,
0x72, 0x3f, 0xcc, 0xb8, 0x12, 0x7c, 0x60, 0xbb, 0x9c, 0x32, 0x47, 0x9e,
0x24, 0x72, 0xd4, 0xee,
0x57, 0x01, 0x85, 0x63, 0x8c, 0x3b, 0xe5, 0xc6, 0x05, 0xc6, 0xaa, 0x13,
0x65, 0x33, 0x23, 0x4e,
0xca, 0x19, 0x0b, 0xd7, 0x67, 0x98, 0x75, 0x02, 0x7a, 0x55, 0x68, 0xb5,
0x08, 0x0b, 0x59, 0x25,
0x3a, 0xcd, 0xce, 0xd5, 0x0e, 0xdf, 0x78, 0x4c, 0x1e, 0x91, 0xbb, 0xe4,
0x77, 0xe8, 0xf9, 0xbc,
0xa5, 0xef, 0x7d, 0xe4, 0xcf, 0x46, 0xef, 0xfb, 0x2d, 0xeb, 0xbf, 0x23,
0x3d, 0xb1, 0xcd, 0x7e,
0xfe, 0x7f, 0x0b, 0x7f, 0xce, 0xa3, 0x77, 0x32, 0x12, 0x95, 0xe9, 0xfb,
0x28, 0x4d, 0x70, 0xf1,
0x8e, 0xa9, 0x8d, 0xf3, 0xa2, 0xee, 0xed, 0x1e, 0x84, 0xdb, 0x18, 0xae,
0x6a, 0xc6, 0x05, 0xd3,
0xfd, 0x7a, 0x66, 0x6e, 0x31, 0x76, 0xca, 0x38, 0x6c, 0x16, 0xe6, 0xbc,
0x3b, 0x62, 0x9b, 0x7d,
0x23, 0x51, 0xb0, 0x59, 0x66, 0xe3, 0x17, 0x53, 0x03, 0xa0, 0x8e, 0xab,
0x16, 0x2f, 0x89, 0x23,
0x7f, 0xbe, 0x4e, 0xad, 0x76, 0xc4, 0xc4, 0x71, 0xd6, 0x2c, 0x83, 0x73,
0x6f, 0xcb, 0x3b, 0xf2,
0x27, 0x24, 0xaf, 0x63, 0x1d, 0x65, 0xb1, 0x25, 0x70, 0x75, 0xdc, 0xd2,
0xeb, 0xc1, 0x09, 0xe6,
0x4d, 0xc2, 0x27, 0x2b, 0x91, 0x25, 0x4b, 0x66, 0xa0, 0xb3, 0xa3, 0x6e,
0xa8, 0xf3, 0xe1, 0x08,
0x78, 0x9f, 0x8a, 0x04, 0xf1, 0xd8, 0xfb, 0x84, 0xbb, 0xfd, 0x18, 0x2b,
0xdf, 0x43, 0x04, 0xcc,
0x46, 0x37, 0x5e, 0x2a, 0xeb, 0xd0, 0x63, 0x29, 0xe3, 0x96, 0x6b, 0xbe,
0x5c, 0x38, 0x8e, 0x1e,
0x9f, 0x64, 0x9f, 0xab, 0x86, 0x7a, 0x32, 0xf6, 0x39, 0x6e, 0xf6, 0x9c,
0x47, 0x02, 0x75, 0xd7,
0x7b, 0xbf, 0xa6, 0xea, 0xcb, 0xd1, 0x31, 0xdd, 0x1f, 0x8f, 0x56, 0xcb,
0xd8, 0x35, 0xcf, 0xf9,
0xf4, 0x29, 0x99, 0xaa, 0x65, 0x1a, 0x98, 0x04, 0xb7, 0xd1, 0xf8, 0x95,
0xb7, 0xef, 0x0d, 0xe8,
0x25, 0x43, 0x75, 0xa7, 0xc9, 0xe9, 0x51, 0xc6, 0x77, 0x14, 0x75, 0x77,
0x42, 0xf5, 0x9f, 0xe3,
0xdc, 0x9f, 0x8a, 0xf6, 0x14, 0x2f, 0x53, 0x91, 0xfa, 0x44, 0x00, 0x6d,
0x28, 0x7f, 0x5c, 0xcf,
0xb8, 0x12, 0xb4, 0xe6, 0xd2, 0xb6, 0x3f, 0x6a, 0x64, 0x0d, 0x16, 0xda,
0x68, 0x6c, 0x93, 0x82,
0xda, 0x5b, 0x92, 0xba, 0xce, 0x78, 0x2a, 0xea, 0x65, 0xfb, 0x5a, 0xc7,
0x5a, 0x66, 0xcd, 0x42,
0x7b, 0x33, 0x03, 0x62, 0x06, 0x5a, 0xcc, 0x90, 0x85, 0xf0, 0xf3, 0x6a,
0x1b, 0xbc, 0xe6, 0xf3,
0xdb, 0x59, 0xf9, 0x33, 0x63, 0xa7, 0x63, 0x8b, 0x64, 0xe2, 0xf6, 0xb8,
0xd9, 0x7e, 0x90, 0x1a,
0xef, 0x08, 0xd7, 0x41, 0xb3, 0xe5, 0x04, 0xde, 0x93, 0x8e, 0x16, 0x4a,
0xd0, 0xd1, 0x29, 0xb3,
0xb5, 0x19, 0xe9, 0xfb, 0x41, 0x61, 0x06, 0x51, 0x92, 0x80, 0xdc, 0x9e,
0xf6, 0xc3, 0x64, 0xd5,
0x3f, 0x21, 0xbd, 0xd3, 0xb2, 0xde, 0x21, 0x32, 0xf4, 0xc3, 0x5a, 0x23,
0x27, 0x2c, 0xf3, 0xcf,
0xb1, 0x87, 0x75, 0x25, 0x5a, 0x66, 0x42, 0x7f, 0x0c, 0xb9, 0xac, 0xd9,
0xec, 0x3b, 0xc9, 0x89,
0x5a, 0x69, 0x78, 0xbb, 0xa5, 0xcd, 0x8a, 0x13, 0xf4, 0x67, 0xe1, 0x71,
0xb1, 0x16, 0x7a, 0x2e,
0x99, 0x6e, 0x83, 0x4f, 0xa5, 0x85, 0x5a, 0xb2, 0x5e, 0x86, 0x45, 0x2a,
0x45, 0x33, 0x8a, 0xac,
0x99, 0x44, 0xc4, 0xb7, 0x98, 0x6d, 0xc7, 0x90, 0xeb, 0x84, 0x65, 0xcd,
0x74, 0xe4, 0xc9, 0xc1,
0xe2, 0xc7, 0x03, 0xae, 0xea, 0xc2, 0x51, 0x59, 0x8b, 0x37, 0x4c, 0x64,
0x54, 0x20, 0xfd, 0x4f,
0xe3, 0x8c, 0xb3, 0x4e, 0xd6, 0x1a, 0x9b, 0xc5, 0x51, 0xd3, 0x29, 0xb1,
0xcb, 0xb4, 0x11, 0xb1,
0x9b, 0xed, 0x2b, 0x45, 0x61, 0x56, 0x10, 0x34, 0x60, 0x03, 0x55, 0x85,
0x1d, 0x64, 0x1f, 0xbc,
0x1c, 0x8e, 0xca, 0xed, 0x44, 0xeb, 0x34, 0x4e, 0x2d, 0xb5, 0x68, 0xc6,
0xd3, 0xba, 0x1b, 0xfd,
0x2e, 0x20, 0x67, 0xce, 0x87, 0xc6, 0x6e, 0xcb, 0xd8, 0x24, 0x72, 0xfd,
0x64, 0x4e, 0x5d, 0x9b,
0xd0, 0xad, 0xa7, 0xf5, 0x90, 0x0c, 0x65, 0xb5, 0xe9, 0x7a, 0x27, 0x7f,
0xc5, 0x6c, 0x6d, 0x61,
0x37, 0x7a, 0x8e, 0x5d, 0x62, 0x1a, 0x51, 0xe2, 0x69, 0xdb, 0x47, 0x1c,
0xdf, 0x81, 0xcd, 0x5b,
0x2c, 0xeb, 0x9c, 0x90, 0x07, 0xa5, 0x1b, 0x51, 0xd1, 0x08, 0xdf, 0x93,
0xb1, 0xcf, 0x56, 0xcb,
0x7a, 0x2d, 0xc4, 0x69, 0x2a, 0xb9, 0x78, 0x17, 0xda, 0x3b, 0xe4, 0xc3,
0xf5, 0x1e, 0x1d, 0x1f,
0xe7, 0xf4, 0x3e, 0x3b, 0x91, 0x68, 0x6b, 0xf6, 0xe9, 0x3d, 0x46, 0x5d,
0x95, 0xaf, 0x2b, 0x3e,
0x21, 0x6f, 0xd6, 0x5b, 0x38, 0x50, 0xdc, 0x0e, 0xc0, 0xce, 0xa9, 0xc4,
0xc1, 0x1e, 0x0b, 0x17,
0xbb, 0xcc, 0x55, 0x5b, 0x64, 0x14, 0x56, 0x2e, 0x46, 0x1f, 0x87, 0x2d,
0xb3, 0x76, 0x6b, 0x1f,
0x6e, 0xb1, 0xcc, 0xd9, 0x45, 0x4b, 0x0d, 0x23, 0xeb, 0xf0, 0xca, 0xb6,
0x16, 0xa8, 0x27, 0x93,
0x60, 0x21, 0x63, 0xbd, 0xd8, 0xb1, 0x59, 0xe7, 0xa9, 0x71, 0x71, 0xeb,
0xec, 0xcb, 0x88, 0x89,
0xa5, 0xe4, 0x9d, 0x40, 0x98, 0xc3, 0x35, 0x03, 0x49, 0x5f, 0x62, 0x17,
0xdc, 0x6a, 0x62, 0x3b,
0xfa, 0x6c, 0x61, 0x9d, 0x3d, 0x96, 0x36, 0x85, 0x83, 0x9c, 0x72, 0xeb,
0xf4, 0xea, 0xbb, 0xcc,
0xb6, 0x6d, 0x9c, 0x22, 0xba, 0xcb, 0x7f, 0xa2, 0xcb, 0x8e, 0x68, 0xf4,
0x80, 0xd9, 0xbe, 0x03,
0x4e, 0xa2, 0xb4, 0xef, 0x16, 0x22, 0x85, 0xa7, 0x75, 0x37, 0x96, 0xc9,
0x81, 0x46, 0x1e, 0xeb,
0x7a, 0x57, 0x3c, 0x2c, 0xe1, 0xec, 0x35, 0x0e, 0xfc, 0x61, 0xa7, 0xd9,
0xf6, 0x32, 0x96, 0x79,
0x1c, 0x7a, 0xdb, 0xcc, 0x75, 0x0e, 0xb1, 0xeb, 0xdc, 0x4a, 0x84, 0xce,
0x85, 0xeb, 0x39, 0xe4,
0x94, 0x34, 0xf6, 0xfa, 0x6d, 0xe6, 0xf8, 0x7d, 0x78, 0x47, 0x0e, 0x36,
0x19, 0x2a, 0x37, 0xca,
0x53, 0x16, 0x3e, 0xb6, 0xe3, 0x33, 0x37, 0x63, 0x97, 0x4e, 0xf2, 0x77,
0xbd, 0xa3, 0x27, 0x92,
0x93, 0xad, 0x32, 0xed, 0x97, 0xde, 0xfa, 0xe4, 0x9c, 0x8f, 0xd7, 0xcd,
0xb1, 0xc8, 0xa5, 0xd0,
0x42, 0x16, 0x2e, 0x64, 0xc7, 0x5a, 0xae, 0x6b, 0x38, 0xaf, 0xc4, 0xd6,
0x35, 0xd5, 0x3d, 0xce,
0x55, 0x96, 0xfe, 0x6d, 0x50, 0x4c, 0x93, 0x47, 0x39, 0x07, 0x6e, 0x41,
0x06, 0xeb, 0x3a, 0xc3,
0x89, 0xe7, 0x46, 0xad, 0x71, 0x5f, 0x34, 0x62, 0x1d, 0x6c, 0x64, 0xac,
0x91, 0xbc, 0xda, 0x4e,
0x89, 0x9d, 0x6a, 0xd3, 0x12, 0x56, 0xda, 0x17, 0x8b, 0xc2, 0x82, 0x20,
0x98, 0x8f, 0x06, 0x33,
0x58, 0x73, 0x9d, 0x89, 0x0d, 0xec, 0x7e, 0x0f, 0xc8, 0x7f, 0x53, 0x41,
0xa7, 0xa2, 0xd7, 0x75,
0x16, 0xec, 0x92, 0x7b, 0x89, 0x11, 0x55, 0x5d, 0x6c, 0x36, 0xdb, 0xb6,
0x22, 0x53, 0x7b, 0x64,
0x9e, 0x82, 0xff, 0x0f, 0x67, 0xc7, 0x6e, 0x32, 0x7b, 0xb6, 0x93, 0xc5,
0xab, 0xd0, 0x52, 0x2c,
0xa3, 0xd7, 0xbb, 0xdb, 0x36, 0x52, 0x67, 0x0c, 0xa3, 0x2d, 0x07, 0xcf,
0xf2, 0xb4, 0x6d, 0xc2,
0xfb, 0xee, 0x84, 0x8b, 0x22, 0x64, 0xda, 0x64, 0xe1, 0x62, 0x01, 0xb2,
0x6c, 0x74, 0xff, 0xb6,
0x1e, 0x4d, 0xdf, 0x4f, 0x66, 0x9e, 0x4a, 0x0e, 0x77, 0xf1, 0x3d, 0x83,
0x75, 0xbd, 0x34, 0xd4,
0x6a, 0x23, 0xb0, 0xfb, 0x1c, 0xec, 0x92, 0xc8, 0xce, 0xb6, 0xcd, 0x42,
0x67, 0x39, 0x5c, 0x67,
0x62, 0x97, 0x6a, 0xac, 0x3d, 0x4d, 0x47, 0xe7, 0x3a, 0x1f, 0xbc, 0x0c,
0xcf, 0x0a, 0x5b, 0x2c,
0xab, 0xbb, 0x78, 0x5d, 0x8a, 0x8f, 0xd4, 0x52, 0xd9, 0x2c, 0x82, 0xca,
0x3a, 0x3f, 0xac, 0x67,
0xf4, 0x2e, 0x6c, 0x96, 0x82, 0x57, 0x36, 0x59, 0xda, 0xf7, 0xb0, 0x5a,
0x07, 0x2c, 0xd6, 0x97,
0x9c, 0xbb, 0xce, 0x32, 0xaf, 0x09, 0x0e, 0x6c, 0x70, 0xb0, 0x30, 0x80,
0x0d, 0xb4, 0x85, 0x8c,
0x15, 0x32, 0x56, 0xd9, 0xac, 0x26, 0x2b, 0x71, 0xa9, 0xa1, 0x5a, 0x17,
0x92, 0x69, 0x16, 0x07,
0xc0, 0x12, 0x7a, 0x6a, 0xc8, 0x61, 0x6b, 0x90, 0xcc, 0x83, 0x2d, 0x9c,
0x8b, 0xee, 0x85, 0xd3,
0x5c, 0xf9, 0x07, 0xbe, 0xb7, 0xda, 0xd2, 0xb3, 0x59, 0xfe, 0x8a, 0xcd,
0x0a, 0xf0, 0x8c, 0x95,
0x66, 0xdb, 0x26, 0xec, 0xdb, 0x47, 0xdf, 0xcd, 0x53, 0x77, 0x79, 0x5f,
0x44, 0x16, 0x4f, 0xcf,
0x5a, 0x5a, 0x6d, 0xd8, 0x23, 0x85, 0x6b, 0xa5, 0x85, 0x46, 0x1f, 0x5d,
0xe7, 0x7b, 0x57, 0xdc,
0x28, 0x83, 0xd9, 0x17, 0xe6, 0x90, 0x9d, 0xaa, 0x7c, 0x56, 0x5b, 0x69,
0x99, 0xb5, 0x16, 0x9e,
0xd4, 0xbe, 0xf3, 0x12, 0x1c, 0xbb, 0xe0, 0xc4, 0xee, 0x8b, 0x64, 0x85,
0x39, 0x62, 0x03, 0xbe,
0x50, 0xa0, 0xa5, 0x9c, 0x42, 0x0e, 0x5c, 0x6b, 0xa1, 0xb2, 0x80, 0xaa,
0x65, 0xb6, 0xce, 0x35,
0x4b, 0xd8, 0x3d, 0x52, 0x2d, 0x7d, 0xff, 0x1e, 0x4d, 0x9c, 0x20, 0x5e,
0x60, 0xef, 0xb0, 0xc3,
0xdb, 0x4a, 0x9f, 0x9e, 0x55, 0xd8, 0x7d, 0x0d, 0x3e, 0x30, 0x15, 0x3f,
0x49, 0xc1, 0x4b, 0x56,
0x5b, 0x56, 0x5b, 0x2c, 0xff, 0xa7, 0x4f, 0x3f, 0x73, 0xe8, 0xb1, 0xea,
0x75, 0x15, 0x5e, 0x16,
0x41, 0x84, 0x2c, 0x69, 0x63, 0x89, 0x25, 0x2e, 0x3b, 0x1a, 0x4b, 0x25,
0x5b, 0xc7, 0x59, 0x46,
0xe2, 0x22, 0x43, 0x65, 0x92, 0xb9, 0x48, 0xb7, 0x2c, 0x00, 0x96, 0x33,
0x63, 0x22, 0xd9, 0xdc,
0x1b, 0x87, 0x8b, 0xe0, 0x32, 0x1c, 0xaf, 0x5f, 0x89, 0x7e, 0x6a, 0xd9,
0x39, 0x97, 0x5a, 0xfc,
0x61, 0x15, 0xf9, 0x45, 0xed, 0x66, 0x8d, 0x16, 0x6f, 0x59, 0x08, 0x1f,
0x0b, 0x88, 0x9e, 0xb9,
0x5c, 0xf3, 0xc1, 0x42, 0x0b, 0xa5, 0xa9, 0xd8, 0x70, 0x2e, 0x12, 0x64,
0x41, 0xcb, 0xd3, 0xba,
0x8c, 0x8c, 0x99, 0x48, 0xac, 0x2e, 0x31, 0x5b, 0x56, 0x10, 0x3f, 0xd5,
0x70, 0x50, 0xee, 0xc3,
0x87, 0x2f, 0x96, 0xe3, 0xb9, 0x39, 0x7a, 0xf6, 0x72, 0xf7, 0x35, 0x07,
0xaf, 0xb2, 0xf2, 0xb1,
0x9c, 0x1d, 0xb1, 0x98, 0x7f, 0x97, 0xc2, 0xa1, 0xcd, 0x42, 0x7d, 0x11,
0x3b, 0xc6, 0x93, 0x8c,
0x5e, 0xae, 0x67, 0x39, 0xa9, 0x19, 0x5e, 0x0a, 0x9a, 0x73, 0xac, 0x50,
0x67, 0xa3, 0x1b, 0x91,
0x60, 0x01, 0x59, 0x73, 0xa6, 0x4f, 0x74, 0x2c, 0xc1, 0x6f, 0x6f, 0x92,
0xff, 0xa0, 0x16, 0xba,
0x15, 0xff, 0x13, 0x7c, 0x7e, 0x91, 0xd9, 0xf7, 0x12, 0x5c, 0x0e, 0x40,
0x8a, 0x15, 0x7c, 0x9a,
0xc4, 0xe7, 0x97, 0x2c, 0x7c, 0x38, 0xf1, 0x81, 0xf9, 0x6e, 0x3e, 0xac,
0x58, 0xe1, 0xca, 0xf6,
0xc6, 0x42, 0xc9, 0xc0, 0x66, 0x9d, 0x6b, 0x13, 0xe3, 0xe7, 0x19, 0x6a,
0x9f, 0x6b, 0xc4, 0x17,
0x56, 0x06, 0xc0, 0x2a, 0x64, 0x9c, 0x80, 0xae, 0xe6, 0x30, 0xc2, 0x85,
0xb9, 0xe8, 0xee, 0x51,
0xf8, 0x5a, 0x0d, 0xad, 0x06, 0x32, 0xf3, 0x3c, 0xb3, 0xa7, 0x91, 0xd6,
0x07, 0xe0, 0xd7, 0xa1,
0xe9, 0x79, 0xe1, 0x9f, 0x9d, 0xbd, 0x58, 0x84, 0xb6, 0x16, 0xf0, 0x7f,
0x14, 0x9f, 0x3c, 0x6d,
0xf3, 0xd8, 0x21, 0xfa, 0xa1, 0xd7, 0xd9, 0xe6, 0x7a, 0x95, 0x44, 0xf5,
0x42, 0xf8, 0xa8, 0x44,
0xe7, 0x73, 0x7d, 0xe6, 0x5b, 0xb1, 0x10, 0x2a, 0xf5, 0x48, 0xe8, 0xe2,
0x5a, 0x3d, 0x37, 0xb1,
0xe1, 0xb9, 0xb3, 0x2d, 0x6b, 0x0d, 0x46, 0x8e, 0x55, 0x70, 0x3d, 0x83,
0x28, 0xf6, 0x72, 0x3d,
0x07, 0xff, 0x7b, 0x0a, 0x5d, 0xb9, 0x66, 0xcd, 0xc6, 0x7f, 0xe6, 0x05,
0x5d, 0xc3, 0x3b, 0x47,
0x9d, 0x87, 0xff, 0x8b, 0x3c, 0xba, 0x02, 0x99, 0x0b, 0xf9, 0x3c, 0xdb,
0x22, 0xed, 0x3c, 0xf9,
0x3d, 0xa7, 0xf8, 0x49, 0x7c, 0x9a, 0xcf, 0x55, 0xc2, 0x27, 0xaf, 0xf6,
0x16, 0xe0, 0xe5, 0xf1,
0x70, 0xa9, 0x22, 0x6f, 0x3a, 0x3b, 0xc5, 0x3c, 0xcb, 0xbc, 0x06, 0x2c,
0x3c, 0xd7, 0xcd, 0x87,
0x15, 0xab, 0xe9, 0xc3, 0x46, 0xc6, 0x3c, 0x49, 0xc3, 0x66, 0x5d, 0xa6,
0x8e, 0x8c, 0x9b, 0x6d,
0x9f, 0x81, 0x14, 0xf5, 0x96, 0xcc, 0xef, 0x9b, 0x95, 0x57, 0xe2, 0x27,
0x85, 0x8c, 0x98, 0xe6,
0xc6, 0x4c, 0x7e, 0x1b, 0x08, 0xdd, 0xf5, 0xe4, 0x90, 0xf9, 0xf8, 0xf2,
0x54, 0xd6, 0xf6, 0xf4,
0xcd, 0x26, 0x5b, 0x3a, 0xb1, 0x59, 0x9d, 0xd9, 0xe2, 0x9a, 0x51, 0x1f,
0x10, 0x33, 0xe1, 0xf0,
0x19, 0x7c, 0x6e, 0x99, 0xbe, 0xa7, 0xee, 0x59, 0x61, 0x3a, 0xd1, 0xfb,
0x0c, 0x94, 0x3c, 0xb3,
0x1b, 0x91, 0x3f, 0x12, 0x4e, 0x56, 0x52, 0x09, 0x5a, 0xf9, 0xf0, 0xc7,
0x4c, 0x2c, 0x92, 0x0d,
0xb5, 0x35, 0x5a, 0x92, 0xb5, 0x7c, 0x52, 0x1e, 0xee, 0xe5, 0xad, 0x01,
0x3a, 0x15, 0xf4, 0xad,
0xe1, 0x93, 0x4d, 0x57, 0xd0, 0x2e, 0xcc, 0x20, 0x8f, 0xf4, 0xc2, 0x06,
0xeb, 0xf4, 0x3c, 0x25,
0xd1, 0x4c, 0x3f, 0xca, 0x56, 0x9e, 0x9d, 0xcc, 0x9e, 0x47, 0x5b, 0x7f,
0x2c, 0x96, 0x86, 0xc5,
0xd6, 0xc3, 0xfd, 0x78, 0xbc, 0x7a, 0xba, 0x65, 0xf4, 0x58, 0xf2, 0xb4,
0xca, 0xe8, 0x1b, 0xb8,
0x96, 0xeb, 0xbb, 0x70, 0x5e, 0xae, 0xd5, 0x9b, 0x36, 0x39, 0x58, 0x61,
0x03, 0x7c, 0xcc, 0x62,
0xb7, 0xf0, 0xae, 0xa5, 0x28, 0x28, 0x0f, 0x6e, 0x6b, 0x83, 0x8d, 0xfa,
0x1c, 0x36, 0xc3, 0x68,
0x94, 0x94, 0xda, 0xce, 0xd4, 0xfa, 0x03, 0x62, 0x1a, 0xec, 0x75, 0x8e,
0x3a, 0xb4, 0xbc, 0x81,
0x9d, 0x67, 0x63, 0x1b, 0xa8, 0x5d, 0xb7, 0x8e, 0x8c, 0x5d, 0x83, 0xb7,
0xb8, 0x50, 0x83, 0x4d,
0x86, 0xb2, 0xea, 0x66, 0x66, 0xcc, 0xc7, 0x63, 0xbd, 0x3d, 0x93, 0x58,
0xf7, 0x31, 0x74, 0x5c,
0xc0, 0xbe, 0x33, 0xc9, 0x32, 0x3e, 0x5f, 0x3f, 0x1b, 0xf6, 0xc0, 0xfa,
0x04, 0xd6, 0x86, 0xb6,
0x96, 0xb1, 0x82, 0x93, 0xba, 0x7f, 0x8a, 0x39, 0x63, 0x0a, 0x55, 0x89,
0xf7, 0x37, 0x27, 0x27,
0xb3, 0x09, 0xec, 0xa1, 0x6b, 0x68, 0x33, 0x7c, 0x56, 0xf3, 0xc7, 0x14,
0x72, 0xea, 0x14, 0xbc,
0x69, 0xa3, 0x96, 0x64, 0xa9, 0xbe, 0x17, 0x32, 0xd9, 0xec, 0xad, 0x23,
0x27, 0x4d, 0xa0, 0x67,
0x03, 0x5e, 0x6f, 0xe5, 0x7a, 0x32, 0x79, 0xb8, 0x37, 0x5c, 0x6c, 0x42,
0x22, 0x75, 0x77, 0x2d,
0xcf, 0x6f, 0x8d, 0x5a, 0xf7, 0xb3, 0x6d, 0x17, 0xef, 0x31, 0x50, 0xf9,
0xb3, 0xfc, 0x0f, 0x7b,
0x40, 0xb1, 0xae, 0x8e, 0x36, 0xe1, 0x4b, 0xe5, 0x50, 0xf0, 0xae, 0xa3,
0xf2, 0x7d, 0x8c, 0xae,
0xd3, 0x14, 0xc5, 0x55, 0xb4, 0xe4, 0xfb, 0xf4, 0x46, 0x41, 0x65, 0xad,
0xae, 0xba, 0x94, 0xef,
0x58, 0xf9, 0xa8, 0xa4, 0xbe, 0x5e, 0xaa, 0x69, 0xfa, 0xda, 0xa0, 0x09,
0x3f, 0xc0, 0x42, 0x46,
0xbd, 0x8c, 0xc1, 0x66, 0x61, 0x33, 0x1e, 0x8d, 0x72, 0xda, 0x6b, 0x1c,
0x6a, 0xe6, 0x06, 0xf6,
0xcd, 0xa6, 0x36, 0xd8, 0x0a, 0x85, 0xd9, 0xac, 0x52, 0xa1, 0xef, 0xe0,
0x95, 0xeb, 0x3b, 0xb8,
0x25, 0xc4, 0xd9, 0x62, 0xc6, 0xaf, 0xc5, 0x4b, 0xf2, 0x2c, 0x3d, 0xe5,
0x50, 0x79, 0x82, 0x1c,
0xa4, 0xee, 0xe2, 0x7b, 0x5b, 0x6b, 0x38, 0x45, 0xdd, 0xc2, 0x19, 0xe0,
0x5e, 0xae, 0xbb, 0xf9,
0x7c, 0x3b, 0xf8, 0xb3, 0xc6, 0x9d, 0x72, 0x0f, 0x5c, 0x2b, 0x9e, 0x56,
0xe0, 0xb3, 0x25, 0x96,
0x39, 0x95, 0x96, 0x4f, 0xf9, 0xd4, 0x35, 0x2b, 0xa8, 0xf3, 0x36, 0xe0,
0x11, 0xbe, 0xab, 0x95,
0x63, 0x03, 0xdf, 0xdf, 0xab, 0xa8, 0x08, 0x17, 0xc0, 0xf1, 0x56, 0x4d,
0x53, 0xdd, 0x39, 0xf7,
0xf6, 0x4f, 0xa4, 0x52, 0x9b, 0x4c, 0xcf, 0x16, 0x46, 0xd8, 0x7c, 0xe4,
0x29, 0xe4, 0x1c, 0xbe,
0x50, 0xfb, 0xf3, 0x16, 0x74, 0x66, 0xf8, 0xd1, 0xac, 0x93, 0x76, 0x70,
0x7d, 0x0f, 0xb8, 0x9b,
0xeb, 0x21, 0xa8, 0x24, 0x63, 0xc7, 0x75, 0xee, 0x8a, 0xbe, 0x09, 0x2d,
0x4c, 0xf0, 0x91, 0x77,
0x02, 0x36, 0xcb, 0xd6, 0xf7, 0x13, 0x95, 0xf6, 0xd6, 0xeb, 0xb8, 0xab,
0xb4, 0x70, 0x98, 0x06,
0x8f, 0xab, 0xe9, 0x5b, 0x8f, 0x3c, 0x36, 0x1f, 0x99, 0x0d, 0x72, 0xf4,
0xba, 0x00, 0x56, 0xd8,
0xc1, 0xc8, 0xc9, 0x52, 0x63, 0x4c, 0x93, 0xc4, 0x9a, 0xce, 0x89, 0xe1,
0xce, 0x3b, 0x22, 0x6a,
0xed, 0xea, 0x3e, 0x64, 0x25, 0xfe, 0xb2, 0x93, 0xde, 0xb6, 0xd8, 0x86,
0x1c, 0xd9, 0x3e, 0xcf,
0x7a, 0xca, 0x38, 0x29, 0x96, 0x22, 0x79, 0x83, 0xbe, 0xef, 0x6e, 0xed,
0x29, 0x47, 0xfa, 0xe5,
0xda, 0x33, 0xbd, 0xad, 0xa5, 0x8c, 0xce, 0x42, 0x27, 0xcb, 0xb0, 0xf3,
0x6c, 0xd6, 0x2e, 0xd5,
0x99, 0xb0, 0x50, 0xdf, 0xab, 0x99, 0xaf, 0x6b, 0xf0, 0x1d, 0x68, 0xab,
0x82, 0x6a, 0xbb, 0x24,
0xc0, 0xb3, 0xa3, 0x72, 0x62, 0x20, 0x1e, 0xbe, 0x5f, 0x46, 0x0b, 0x33,
0x7d, 0xe8, 0x16, 0xc1,
0xf3, 0x5f, 0xc9, 0xa2, 0x15, 0x96, 0x96, 0x12, 0x38, 0x2d, 0xd0, 0xfa,
0xdc, 0x41, 0x5c, 0xaa,
0xb3, 0x6c, 0xb1, 0x85, 0xd2, 0x33, 0x78, 0xf9, 0xcb, 0xf4, 0x2d, 0xc1,
0xf6, 0xc5, 0x96, 0xa7,
0x59, 0x25, 0xf4, 0x94, 0x93, 0xa7, 0x57, 0x61, 0xed, 0x15, 0xcc, 0xf1,
0xe5, 0xa0, 0x42, 0x1e,
0x81, 0xfb, 0xd5, 0xf4, 0xae, 0x06, 0xeb, 0xe1, 0x63, 0x07, 0x54, 0x5e,
0x36, 0xf5, 0xb3, 0x11,
0x99, 0xc4, 0x47, 0xde, 0xe1, 0xd0, 0xdf, 0xa6, 0x47, 0xa8, 0x53, 0xc2,
0x62, 0x2a, 0x51, 0xab,
0x64, 0xa5, 0xe4, 0x55, 0xb5, 0x6b, 0x2d, 0xa2, 0xd5, 0xe1, 0x33, 0x2f,
0x92, 0xca, 0x76, 0xab,
0x85, 0xb2, 0x07, 0x7b, 0xe0, 0x7b, 0x82, 0x4c, 0x34, 0xa6, 0x48, 0x5c,
0x4d, 0xe7, 0x84, 0x6e,
0xb3, 0xc2, 0x22, 0xc6, 0x4b, 0xb5, 0xbd, 0x0a, 0x9e, 0x1b, 0x39, 0xd5,
0xed, 0x0e, 0x88, 0x8d,
0x58, 0x26, 0xcf, 0xe7, 0x69, 0x77, 0x01, 0xb9, 0xcc, 0x0e, 0xf2, 0xfc,
0x9e, 0x82, 0x8f, 0xc3,
0x53, 0xd6, 0x63, 0xe3, 0x31, 0x70, 0x63, 0xfd, 0x89, 0xc6, 0x53, 0x54,
0xad, 0x51, 0xa5, 0xdf,
0x05, 0x70, 0x68, 0xb8, 0x7e, 0xd6, 0x41, 0x7f, 0x0f, 0x7c, 0x2e, 0xc1,
0x32, 0x8e, 0x00, 0xcf,
0xd5, 0xc7, 0x51, 0x7b, 0xcd, 0x64, 0xcc, 0x5e, 0x6c, 0xdb, 0xa8, 0xef,
0xee, 0x7b, 0x7e, 0xf2,
0x99, 0xd1, 0x81, 0x88, 0x1f, 0xeb, 0x33, 0xaf, 0x80, 0xb5, 0x1a, 0xf4,
0xdf, 0x32, 0x6e, 0x44,
0x0b, 0x63, 0x2d, 0x3d, 0x85, 0xf2, 0x34, 0x5c, 0xa8, 0x3b, 0x14, 0x2b,
0xe0, 0xc2, 0xf7, 0x0d,
0x0a, 0xf5, 0x54, 0xc9, 0x86, 0x2f, 0x2a, 0xbb, 0x14, 0xfa, 0xf5, 0x8d,
0x93, 0x9e, 0xd8, 0x69,
0x9f, 0xec, 0x35, 0xb1, 0xc7, 0x47, 0x3b, 0x4d, 0xe4, 0xe3, 0x5c, 0x1f,
0x0e, 0x9e, 0x83, 0xfe,
0x2e, 0xf7, 0xa8, 0x9d, 0xf0, 0x91, 0xeb, 0xd3, 0xef, 0x20, 0xd2, 0x32,
0xf5, 0x53, 0x92, 0x5c,
0x9f, 0x75, 0xc6, 0xcb, 0x7d, 0x5c, 0x7b, 0xfc, 0xa8, 0x2b, 0xbc, 0x42,
0x14, 0x54, 0x48, 0x95,
0x31, 0x49, 0x62, 0x6a, 0xbb, 0x24, 0x76, 0x9b, 0xd5, 0x39, 0x22, 0xa9,
0xa0, 0x2a, 0xaf, 0x4c,
0x3f, 0xe5, 0x69, 0x81, 0xb3, 0xb6, 0xd8, 0x8f, 0xb6, 0x1a, 0xd0, 0x44,
0x9e, 0xcf, 0x4e, 0x94,
0x1b, 0xf0, 0x0d, 0x21, 0x3b, 0xfb, 0xd3, 0x16, 0x7d, 0x3a, 0x1c, 0x63,
0x19, 0x91, 0xab, 0xdf,
0x99, 0xb2, 0x41, 0xc1, 0xfa, 0xb6, 0x52, 0x1e, 0xbc, 0x3f, 0x48, 0xc6,
0x53, 0x2b, 0xec, 0xd5,
0x92, 0xb5, 0x7d, 0xdf, 0x2b, 0x0f, 0xdf, 0xf8, 0x3b, 0xde, 0xbf, 0x1f,
0xec, 0xc4, 0x3b, 0xd3,
0x7c, 0xfa, 0x62, 0xe5, 0x79, 0xfd, 0xac, 0xd8, 0xee, 0xf7, 0x7e, 0x56,
0x0a, 0x9a, 0xdf, 0xc5,
0x8e, 0x51, 0x4e, 0xdd, 0xee, 0xcb, 0x5b, 0xbd, 0x96, 0x68, 0x9d, 0x7e,
0x8f, 0x67, 0xac, 0x9f,
0x3c, 0x79, 0xc4, 0xc7, 0x34, 0x3c, 0xae, 0xc8, 0xef, 0x9d, 0x2a, 0x97,
0x4c, 0x07, 0x02, 0xea,
0x46, 0x61, 0x3b, 0x9e, 0x90, 0xe9, 0x33, 0x7e, 0x20, 0xf2, 0xef, 0x85,
0x63, 0x57, 0xff, 0xcb,
0xd4, 0x0f, 0xa3, 0x7d, 0xb4, 0x97, 0xa7, 0xdf, 0xfc, 0xf2, 0xdf, 0xd9,
0x53, 0x38, 0x5f, 0xae,
0x34, 0x67, 0x59, 0xd1, 0xcc, 0x9e, 0x33, 0x5e, 0xca, 0x8c, 0x2a, 0x89,
0xc2, 0x66, 0xed, 0xaa,
0xbb, 0xa6, 0xf6, 0x2e, 0xa9, 0xcc, 0x2a, 0xd1, 0x4f, 0xe3, 0x76, 0x06,
0xbc, 0x7b, 0x7a, 0x10,
0x3a, 0x4d, 0xfa, 0xee, 0x6a, 0x46, 0x80, 0xb7, 0x34, 0xd5, 0xfb, 0x8c,
0xde, 0xdf, 0xb2, 0xf0,
0xe5, 0xed, 0xac, 0xb2, 0x06, 0x4d, 0xa6, 0x59, 0xc6, 0x67, 0x04, 0x98,
0x6b, 0xc0, 0x63, 0x12,
0xba, 0x70, 0xad, 0xb2, 0x8b, 0xbc, 0x19, 0xd9, 0x66, 0x54, 0x0e, 0xb9,
0x36, 0x01, 0x3f, 0x3b,
0x08, 0xf6, 0x92, 0xa1, 0x92, 0x2d, 0x7d, 0x99, 0x9c, 0x40, 0x63, 0xc9,
0x41, 0xe3, 0x65, 0xa4,
0x7e, 0x27, 0xd1, 0xbb, 0x56, 0x2c, 0x1e, 0xb8, 0x0d, 0x3d, 0x57, 0xe1,
0x39, 0x5e, 0x8a, 0xd9,
0xe4, 0x80, 0x06, 0xbd, 0x56, 0x13, 0x76, 0x49, 0x69, 0xc3, 0x4f, 0x36,
0xb6, 0x99, 0x88, 0x7f,
0x8c, 0x27, 0x97, 0xa5, 0xb7, 0x91, 0xe9, 0x60, 0xd0, 0xfb, 0xbb, 0x3b,
0xf5, 0x5d, 0x01, 0x2b,
0x9d, 0x7e, 0xc4, 0xea, 0x2b, 0xee, 0x19, 0x07, 0xf5, 0x5b, 0x5c, 0xe9,
0x54, 0x25, 0x99, 0x41,
0xdf, 0x74, 0x4d, 0xd7, 0xef, 0x7d, 0xa9, 0x7b, 0x45, 0x07, 0x02, 0xae,
0x73, 0x84, 0xd3, 0x29,
0x79, 0xdf, 0x28, 0x97, 0xc8, 0xda, 0x2e, 0x09, 0xed, 0xaa, 0xc3, 0x53,
0xfe, 0x54, 0x51, 0x99,
0x5a, 0xa8, 0xdf, 0x91, 0x99, 0xab, 0xef, 0x9e, 0xb6, 0x45, 0x0b, 0x56,
0x9b, 0x43, 0xa5, 0x9c,
0xae, 0x9f, 0xfc, 0x59, 0x91, 0xca, 0x6a, 0x03, 0xb0, 0x8e, 0xf7, 0xf7,
0x7e, 0xfa, 0xce, 0xe8,
0x7e, 0x3c, 0xb6, 0xa7, 0x7e, 0x4a, 0x96, 0x1c, 0x10, 0xea, 0x5e, 0xed,
0xdf, 0xe5, 0x7e, 0xf6,
0xef, 0xc3, 0xee, 0x35, 0x5e, 0x25, 0xd2, 0xd4, 0x73, 0x6c, 0xdf, 0x71,
0x59, 0xd4, 0x2b, 0x33,
0xf4, 0x98, 0xc3, 0xfa, 0xdd, 0x87, 0x31, 0x96, 0x11, 0xea, 0x3d, 0xc4,
0x44, 0xfc, 0x63, 0x33,
0x36, 0x4b, 0xf4, 0xe3, 0x6c, 0x34, 0xf9, 0x6f, 0x33, 0xde, 0x19, 0x6f,
0x69, 0x4b, 0xc3, 0x66,
0xf3, 0xe0, 0xed, 0x10, 0xd9, 0xa7, 0x11, 0x7b, 0xfb, 0xf3, 0x96, 0x06,
0xc7, 0xb5, 0xe8, 0xb7,
0x42, 0x3f, 0xb9, 0x4c, 0xf6, 0x93, 0xe9, 0x70, 0x40, 0xcd, 0x28, 0xec,
0x45, 0x37, 0x49, 0x3e,
0x74, 0xfa, 0x60, 0xf7, 0x66, 0xcb, 0x8c, 0x03, 0x44, 0xf6, 0x20, 0xea,
0xc5, 0xb6, 0xfa, 0xf3,
0xcc, 0xc8, 0xa5, 0x4a, 0x7b, 0x9a, 0x88, 0x0c, 0xbc, 0xc2, 0x09, 0x5d,
0x89, 0x15, 0x1a, 0x25,
0x32, 0x4a, 0xc5, 0x99, 0x7a, 0xef, 0x6a, 0x52, 0x4a, 0x72, 0x81, 0xe1,
0xd0, 0xf7, 0x60, 0x8f,
0xb6, 0x79, 0xb2, 0xe4, 0xc2, 0x6b, 0xac, 0x5b, 0x23, 0xff, 0xa4, 0xe2,
0x49, 0x32, 0xff, 0xe6,
0x25, 0x41, 0x3f, 0x85, 0xf8, 0x03, 0x3b, 0x74, 0x9a, 0x65, 0xfd, 0xe7,
0x18, 0x79, 0x54, 0x8f,
0x9f, 0xce, 0x59, 0x6d, 0x28, 0x2d, 0x49, 0x8c, 0x8c, 0xb7, 0xcc, 0x4a,
0x42, 0x0b, 0x51, 0xd2,
0x89, 0x2a, 0x6c, 0x05, 0x94, 0x8f, 0x9a, 0x2b, 0xec, 0x23, 0x2e, 0x22,
0x7d, 0x64, 0x51, 0x6f,
0xaa, 0x3f, 0x84, 0x24, 0x47, 0xf5, 0xb8, 0x16, 0xf2, 0xa8, 0x7a, 0x56,
0xe5, 0xed, 0x7d, 0x1e,
0x8f, 0x79, 0x0d, 0xcf, 0x9c, 0x23, 0x43, 0x7c, 0xb4, 0x96, 0x0c, 0x9f,
0x45, 0x44, 0x5a, 0x3d,
0x19, 0xdd, 0xaa, 0xfb, 0xde, 0x9c, 0xc2, 0x8e, 0x6a, 0x4a, 0x3b, 0xe1,
0x64, 0x84, 0x7e, 0x47,
0xc2, 0xf3, 0x57, 0x20, 0x49, 0xd0, 0xeb, 0xcd, 0xce, 0xa9, 0xf6, 0xfb,
0x68, 0x3f, 0x9d, 0xba,
0x64, 0x3a, 0x12, 0x10, 0xea, 0xf9, 0xd4, 0x0a, 0x1f, 0x6f, 0x4b, 0xa5,
0xb2, 0xac, 0xb6, 0x48,
0xa6, 0x64, 0x6b, 0xa1, 0x32, 0x53, 0x7f, 0x77, 0x9e, 0xc8, 0xb8, 0x44,
0x1f, 0x6d, 0xa8, 0xb7,
0x34, 0x86, 0x72, 0x76, 0x18, 0x80, 0x8f, 0x05, 0x5b, 0xe3, 0x0c, 0x3b,
0xad, 0x5d, 0x1c, 0x46,
0xa1, 0xbc, 0xa8, 0xe2, 0x4c, 0xfd, 0x9d, 0xe0, 0xb4, 0xee, 0x31, 0x85,
0x76, 0x9b, 0x43, 0xbd,
0xc5, 0xb9, 0x5a, 0xce, 0x62, 0xd5, 0x40, 0x50, 0xbc, 0x55, 0xa3, 0xc1,
0x1e, 0x44, 0xb9, 0x4b,
0xc6, 0x68, 0xe2, 0xe4, 0x77, 0xc8, 0x93, 0xcd, 0x09, 0xf2, 0x2e, 0x5d,
0xc7, 0xdf, 0xcd, 0xff,
0xf1, 0x70, 0x78, 0x52, 0x8f, 0x57, 0xcf, 0x5f, 0x9e, 0xa5, 0x9e, 0xef,
0x81, 0xd7, 0x7b, 0xfe,
0xc2, 0x63, 0x0c, 0x9f, 0x9f, 0x92, 0xce, 0xf2, 0xbf, 0xe8, 0x7b, 0x8d,
0x0f, 0xfd, 0xe3, 0xf8,
0xe5, 0x26, 0x22, 0xe7, 0x2e, 0x93, 0x96, 0xaa, 0xac, 0xbb, 0xe0, 0x47,
0x47, 0x4c, 0x0e, 0xf6,
0xe1, 0x8f, 0xf7, 0x59, 0xfa, 0xef, 0xc2, 0x32, 0xa7, 0xe4, 0x18, 0x51,
0x5d, 0x8a, 0x7f, 0x78,
0xdb, 0x55, 0xcf, 0x20, 0xe2, 0x76, 0x35, 0xff, 0xde, 0x69, 0xb6, 0xdd,
0x29, 0x8f, 0xd2, 0xa6,
0x78, 0x3b, 0xc6, 0x5a, 0x6b, 0xb1, 0xf3, 0xed, 0xcc, 0xea, 0xa5, 0xff,
0x8e, 0x7f, 0x00, 0xa7,
0xd9, 0xee, 0xf2, 0x00, 0xb5, 0xdc, 0x21, 0xb4, 0xdb, 0xd3, 0x32, 0xcb,
0x2a, 0x53, 0x60, 0xbc,
0x86, 0x57, 0x45, 0x5b, 0xf8, 0xbe, 0x4b, 0xfe, 0xc2, 0x19, 0xd8, 0x77,
0xfc, 0x31, 0x46, 0x6d,
0xc1, 0x93, 0xd4, 0x59, 0x61, 0xa8, 0xe9, 0x27, 0x63, 0xf0, 0xc9, 0x27,
0xf4, 0x1b, 0x2b, 0xc9,
0xfa, 0x39, 0x52, 0x30, 0x9c, 0xd7, 0x6f, 0x69, 0xd8, 0x88, 0xab, 0x11,
0xb5, 0x5d, 0x13, 0x5c,
0xef, 0x11, 0x87, 0x8d, 0xca, 0x34, 0x72, 0x0d, 0xf5, 0xde, 0x73, 0x36,
0xfd, 0x67, 0x7c, 0x9e,
0xac, 0x7b, 0x71, 0x12, 0xad, 0x6d, 0x60, 0xbd, 0x7b, 0x24, 0x0c, 0xad,
0xb7, 0x97, 0x9b, 0xf1,
0x9c, 0x3a, 0x72, 0x80, 0xaa, 0x38, 0x5c, 0x3b, 0x96, 0x7a, 0xb3, 0x76,
0xb5, 0xf9, 0xdc, 0xfe,
0x14, 0x9f, 0x0e, 0xea, 0xea, 0xe5, 0x3e, 0xc6, 0x87, 0x11, 0x59, 0x1d,
0xe5, 0x46, 0xfe, 0x7d,
0x8c, 0x91, 0x4b, 0xb1, 0xd1, 0xeb, 0x7e, 0x2b, 0x9d, 0x82, 0xfe, 0x72,
0x76, 0xb0, 0x74, 0xf7,
0x3b, 0xd9, 0x8a, 0x5e, 0x11, 0x7e, 0xef, 0xed, 0x3f, 0x46, 0x85, 0x60,
0x33, 0xfb, 0xb3, 0xc8,
0xff, 0x4d, 0x50, 0x39, 0x0d, 0xad, 0x83, 0xec, 0x44, 0x19, 0x26, 0x32,
0xf5, 0xb3, 0x4b, 0xf5,
0xd4, 0xae, 0xde, 0xa7, 0x6d, 0x2a, 0xb6, 0xf2, 0xd0, 0x3a, 0xce, 0x8e,
0x53, 0x8f, 0xae, 0xfa,
0xcb, 0xe3, 0xd8, 0xf2, 0x51, 0xec, 0x34, 0x80, 0xda, 0x60, 0x1f, 0x3d,
0x2d, 0xfa, 0x59, 0x92,
0x97, 0x07, 0xab, 0x4c, 0x81, 0xa0, 0x9e, 0x9c, 0x2f, 0xd6, 0xbb, 0xba,
0x67, 0x46, 0x25, 0xf9,
0xf2, 0x4c, 0xc0, 0x71, 0x6b, 0xd0, 0xf0, 0x13, 0xd2, 0x15, 0x74, 0x46,
0x13, 0x37, 0x92, 0x11,
0x7b, 0xb0, 0xea, 0x26, 0xe8, 0xbf, 0x1e, 0x94, 0xfe, 0x69, 0x79, 0x1b,
0x3d, 0x64, 0xc9, 0x58,
0xc3, 0x26, 0xc3, 0xdc, 0x36, 0x53, 0x75, 0x48, 0x9f, 0xa2, 0xbc, 0x9c,
0x2c, 0xfd, 0xf6, 0xfd,
0x62, 0x79, 0x57, 0xce, 0x06, 0xc1, 0xeb, 0xfa, 0xfd, 0x8c, 0xdd, 0x68,
0x76, 0x0e, 0x1e, 0xd9,
0x84, 0xef, 0xb8, 0x5a, 0xcf, 0xb8, 0x39, 0x54, 0xfd, 0x67, 0xf5, 0xe5,
0x9d, 0x71, 0x06, 0x4d,
0xef, 0x45, 0xd7, 0xf3, 0xf5, 0x9d, 0xc3, 0xe5, 0xfa, 0x29, 0xb1, 0x7a,
0x97, 0xe3, 0x8d, 0x00,
0xf4, 0xcf, 0x58, 0x68, 0x9d, 0xd6, 0xbf, 0x9d, 0xf5, 0xa1, 0x77, 0xc6,
0x0d, 0x57, 0xef, 0x19,
0x68, 0x78, 0x56, 0xb4, 0xce, 0x73, 0xf5, 0xf9, 0x8e, 0xf6, 0x50, 0x7b,
0xdd, 0x4f, 0x1a, 0xa5,
0xc7, 0x66, 0xbd, 0xef, 0x1f, 0xc2, 0x63, 0x4e, 0xb9, 0xe9, 0x58, 0x69,
0xb5, 0x95, 0xa9, 0xad,
0x56, 0xac, 0x7c, 0xab, 0xcf, 0x6f, 0x04, 0x19, 0xaf, 0x68, 0x29, 0x3f,
0xde, 0xe2, 0x7e, 0x5a,
0xb9, 0x4c, 0x3f, 0xf3, 0x3b, 0x13, 0x50, 0x17, 0x56, 0xbc, 0x47, 0xb5,
0x41, 0x2d, 0x44, 0x54,
0x0d, 0x31, 0x6d, 0xd6, 0x2d, 0xa5, 0x6b, 0x55, 0x46, 0x6a, 0xba, 0x91,
0xa6, 0xdf, 0x1e, 0x3a,
0x8a, 0x5d, 0xcf, 0x07, 0xc4, 0x05, 0x0d, 0xf5, 0xde, 0xc9, 0x3b, 0xfa,
0x0d, 0x95, 0xb7, 0xdc,
0x2d, 0x6f, 0x5a, 0x70, 0x41, 0xbf, 0xe1, 0x63, 0x1d, 0xff, 0xa6, 0x7e,
0x8b, 0xc7, 0x35, 0x47,
0xfd, 0xff, 0x96, 0xdf, 0x28, 0x5f, 0xfa, 0x6f, 0x06, 0xa5, 0x76, 0x3e,
0xe0, 0x5a, 0x17, 0x7c,
0xd6, 0xf1, 0xef, 0xbb, 0x12, 0xde, 0xde, 0x72, 0x23, 0xd8, 0xac, 0x60,
0xdc, 0xb6, 0xa5, 0x74,
0xb9, 0xf1, 0xde, 0x15, 0x5d, 0xda, 0x78, 0x47, 0x6b, 0xe3, 0xc2, 0x65,
0xe8, 0x9f, 0x97, 0x0f,
0xc9, 0x64, 0x54, 0x2a, 0x46, 0xa6, 0x0c, 0xf6, 0xd8, 0xcc, 0xbd, 0xa7,
0x65, 0xda, 0x93, 0x1d,
0xc9, 0xd8, 0xcc, 0x2e, 0x9f, 0x6a, 0x5a, 0x21, 0xfc, 0x56, 0xf0, 0x29,
0xf5, 0x21, 0xb5, 0x17,
0x31, 0x35, 0xb0, 0xc6, 0x6b, 0xb3, 0x6e, 0xb3, 0xba, 0x46, 0x8c, 0x74,
0x8c, 0xb1, 0xab, 0x9d,
0x31, 0x82, 0xea, 0xe9, 0x22, 0xf1, 0xf8, 0xf3, 0xe1, 0x03, 0xf9, 0x38,
0xf4, 0x4d, 0x11, 0xd7,
0x80, 0xef, 0xd8, 0xc5, 0xe3, 0x24, 0xd1, 0x18, 0x23, 0x03, 0x2c, 0x71,
0xa6, 0xce, 0x69, 0xb7,
0x97, 0x8f, 0x49, 0x8b, 0x33, 0xe2, 0xe8, 0x7d, 0x41, 0x56, 0xc9, 0xd7,
0xf2, 0x2f, 0x74, 0xfd,
0x73, 0xe0, 0x13, 0x72, 0xc0, 0x0a, 0x7d, 0xaf, 0x2e, 0x84, 0x9f, 0x86,
0x4d, 0xfa, 0x6f, 0x3d,
0xe3, 0x8c, 0x44, 0xe9, 0x67, 0xb5, 0x19, 0xe8, 0x3a, 0xed, 0xb1, 0x98,
0x04, 0x7b, 0xb4, 0x43,
0xfd, 0x65, 0xe4, 0x10, 0x2a, 0x8c, 0x6f, 0x88, 0x8e, 0x8f, 0xae, 0x19,
0x17, 0xc9, 0xc6, 0x71,
0x32, 0x8c, 0xda, 0x3e, 0x84, 0x9f, 0x8e, 0xd1, 0x54, 0xdf, 0xd1, 0xc4,
0x53, 0x9f, 0xda, 0xb0,
0x78, 0x9f, 0xef, 0x9a, 0x20, 0x3f, 0xf6, 0x2d, 0x88, 0xc9, 0x55, 0xdf,
0xa4, 0x13, 0x81, 0x96,
0xd7, 0x49, 0xab, 0x7c, 0x46, 0x2e, 0xbd, 0x16, 0xa8, 0x68, 0x4d, 0x22,
0x6e, 0x23, 0x43, 0xb8,
0x76, 0x18, 0xd1, 0xf2, 0x4c, 0x6d, 0x58, 0x82, 0xff, 0xf7, 0xff, 0x75,
0x9d, 0x34, 0x78, 0x4c,
0xa4, 0xe1, 0xfa, 0xe6, 0xaa, 0x7e, 0x9c, 0xad, 0xd4, 0x77, 0xc4, 0x7d,
0xfe, 0x13, 0x71, 0x51,
0x7e, 0xe4, 0x3c, 0x38, 0x44, 0x46, 0xb8, 0xbf, 0x0b, 0x2b, 0xd2, 0x1e,
0xe9, 0x08, 0x5d, 0xd7,
0x70, 0xd9, 0xa2, 0x1c, 0x6d, 0x6c, 0xa6, 0x63, 0x2d, 0x7c, 0xd4, 0x73,
0x32, 0xca, 0xfe, 0x82,
0x28, 0x0c, 0xe4, 0x04, 0xf8, 0xa5, 0xfe, 0x0b, 0xba, 0x2f, 0xae, 0x1a,
0xdf, 0x32, 0x6f, 0x89,
0x0c, 0xc6, 0x62, 0x8a, 0xd2, 0x8b, 0xf6, 0x91, 0xd2, 0xab, 0xac, 0x57,
0x7a, 0xaf, 0xf2, 0x5f,
0xfb, 0x7a, 0x2a, 0xbd, 0x7b, 0x45, 0xf7, 0xb4, 0xee, 0xe5, 0xbd, 0xd2,
0x2e, 0x37, 0xb6, 0x67,
0x39, 0xe3, 0x18, 0xdb, 0xd3, 0x6c, 0x7b, 0x32, 0xfd, 0x91, 0xca, 0x47,
0x52, 0x1f, 0xa9, 0xe8,
0xc1, 0xdc, 0x9e, 0xf4, 0xf7, 0xcc, 0xe8, 0xf9, 0x4b, 0xca, 0x54, 0xd6,
0x3b, 0xfd, 0xe1, 0xba,
0xf0, 0x98, 0x40, 0xdf, 0xb5, 0x19, 0x36, 0xe9, 0xd9, 0xa4, 0x17, 0xec,
0xc3, 0x1d, 0xc3, 0x65,
0xb8, 0x0c, 0x92, 0x01, 0xd4, 0x23, 0xea, 0xef, 0x51, 0xbf, 0xba, 0x0a,
0xa8, 0xbf, 0x83, 0x3d,
0x2b, 0x29, 0xd2, 0x87, 0x0c, 0x0b, 0x15, 0x03, 0xbb, 0x95, 0xdd, 0x93,
0xde, 0xb5, 0x21, 0x2c,
0x22, 0x2c, 0x74, 0x5d, 0xf3, 0x15, 0xf0, 0xfb, 0x36, 0x89, 0xb5, 0x5e,
0x05, 0x2f, 0xd8, 0x86,
0x1a, 0x43, 0xf5, 0x77, 0x04, 0x3c, 0xad, 0x9f, 0x98, 0xb4, 0xea, 0xbf,
0x66, 0xfd, 0xe6, 0x32,
0xf8, 0xd6, 0xfd, 0x2d, 0xaa, 0xd5, 0xd8, 0x6b, 0xa0, 0x0c, 0xd5, 0x18,
0x0e, 0x9d, 0xbb, 0x66,
0x86, 0x8f, 0x0e, 0x7d, 0x33, 0xe6, 0xf5, 0xfd, 0x5e, 0xdb, 0xae, 0x75,
0xff, 0x88, 0x1b, 0x6a,
0x1b, 0x22, 0xcf, 0x81, 0xc1, 0xc4, 0x5a, 0x0f, 0xf6, 0xb7, 0x55, 0x3a,
0x4f, 0xba, 0x6c, 0xd7,
0xf6, 0x1b, 0xa4, 0x3d, 0xdf, 0x4f, 0x7c, 0x58, 0xf2, 0x19, 0xdd, 0x97,
0x59, 0x6a, 0xee, 0x73,
0xf6, 0x61, 0x8e, 0xbe, 0x13, 0xc3, 0x93, 0xc2, 0xab, 0x43, 0xdf, 0x6f,
0x7b, 0xdd, 0xbf, 0xdb,
0x96, 0x58, 0xbb, 0xb3, 0xe2, 0xd9, 0xd4, 0x21, 0xf6, 0x41, 0x0e, 0xd7,
0x37, 0x32, 0xf4, 0x97,
0xa7, 0xa8, 0x4a, 0xb2, 0x65, 0x99, 0xbc, 0x1d, 0xf0, 0x6f, 0xf9, 0x2f,
0xca, 0x3e, 0xa9, 0x60,
0xf7, 0x7a, 0x52, 0x47, 0x98, 0x9e, 0x63, 0x0c, 0x96, 0xa1, 0xc5, 0x0f,
0x67, 0x87, 0xcf, 0xea,
0x36, 0x2a, 0xa4, 0xd1, 0x5f, 0x26, 0xd6, 0xc2, 0x67, 0x85, 0x47, 0x3c,
0x58, 0x3c, 0x30, 0x7b,
0xa0, 0x7d, 0x80, 0x0c, 0x70, 0x7f, 0xf7, 0xf0, 0x33, 0xd8, 0xe4, 0x31,
0x79, 0x1c, 0xdb, 0x64,
0x4a, 0x91, 0x4c, 0x90, 0x49, 0x52, 0xc6, 0x19, 0x3d, 0x9a, 0xfc, 0xf9,
0x88, 0x74, 0x97, 0xde,
0xc4, 0x97, 0x7b, 0xac, 0xf1, 0xac, 0x0c, 0xca, 0x7f, 0xca, 0x76, 0x9b,
0x33, 0x3c, 0xa2, 0x5b,
0x28, 0xc6, 0x7e, 0x59, 0xbb, 0x39, 0x6f, 0x8d, 0x78, 0xb4, 0x70, 0x60,
0xee, 0xb3, 0xf6, 0xfe,
0xe2, 0x85, 0x7a, 0x7a, 0xd7, 0x5b, 0x7a, 0x49, 0x4f, 0x62, 0xaf, 0x27,
0x9f, 0x9e, 0xd1, 0xdf,
0x28, 0x6d, 0x02, 0x1b, 0x0f, 0x32, 0x7a, 0x19, 0xf7, 0xcc, 0x08, 0x8f,
0x0a, 0xd9, 0xeb, 0xd7,
0x8a, 0xb7, 0x6e, 0xa3, 0x1e, 0x1c, 0xff, 0x74, 0x66, 0x7f, 0x5b, 0xbf,
0xfc, 0xbe, 0x46, 0x5f,
0x09, 0x0a, 0xfa, 0xfa, 0xd9, 0xfa, 0x3b, 0xfa, 0x16, 0x3e, 0x9e, 0x7b,
0x47, 0x7d, 0xd8, 0xe8,
0x50, 0x4e, 0xfc, 0xd5, 0xf3, 0xe4, 0xa8, 0x3b, 0x26, 0x3f, 0x9c, 0xd0,
0xd3, 0x20, 0xca, 0xf2,
0xfa, 0xe6, 0xf7, 0xb5, 0xf7, 0x71, 0xf4, 0x31, 0xfa, 0x88, 0xbe, 0xec,
0x7d, 0x1d, 0x7d, 0x6d,
0xfd, 0x1c, 0xfd, 0xed, 0xcf, 0x38, 0x9e, 0xa8, 0xbc, 0x2f, 0x45, 0xed,
0x85, 0xa1, 0xf8, 0xfa,
0x6d, 0xd8, 0x4d, 0xd9, 0x22, 0xac, 0xa1, 0xdb, 0xa8, 0x3b, 0x6a, 0xef,
0x8f, 0x7f, 0xa8, 0xf4,
0xb1, 0x8c, 0x7f, 0x16, 0xf6, 0x18, 0xdb, 0xa3, 0xb0, 0x7b, 0xee, 0xe3,
0xe3, 0xff, 0x91, 0xf5,
0xc0, 0xa4, 0xbb, 0x93, 0x6e, 0x65, 0xff, 0x53, 0x7b, 0x60, 0xb7, 0x50,
0x7c, 0xfd, 0x26, 0x6d,
0x17, 0xde, 0xc0, 0xd5, 0x88, 0x8d, 0xd4, 0xa5, 0x3e, 0x63, 0xa7, 0x90,
0xad, 0x42, 0x08, 0x21,
0x30, 0xfe, 0x1f, 0x7e, 0x26, 0xe7, 0x5b
};

View File

@ -23,124 +23,18 @@
********************************************************************************/ ********************************************************************************/
#include "shared.h" #include "shared.h"
#include "gpback.h" #include "font.h"
#include "Overlay_bar_s2.h"
#include <png.h>
/* Backdrop */
char backdrop[(640 * 480 * 2) + 32];
/* Backdrop Frame Width (to avoid writing outside of the background frame) */ /* Backdrop Frame Width (to avoid writing outside of the background frame) */
u16 back_framewidth = 640; u16 back_framewidth = 640;
int font_size[256], fheight;
typedef struct
{
unsigned short font_type, first_char, last_char, subst_char, ascent_units, descent_units, widest_char_width,
leading_space, cell_width, cell_height;
unsigned long texture_size;
unsigned short texture_format, texture_columns, texture_rows, texture_width, texture_height, offset_charwidth;
unsigned long offset_tile, size_tile;
} FONT_HEADER;
static unsigned char fontWork[ 0x20000 ] __attribute__((aligned(32)));
static unsigned char fontFont[ 0x40000 ] __attribute__((aligned(32)));
/****************************************************************************
* YAY0 Decoding
****************************************************************************/
void yay0_decode(unsigned char *s, unsigned char *d)
{
int i, j, k, p, q, cnt;
i = *(unsigned long *)(s + 4); // size of decoded data
j = *(unsigned long *)(s + 8); // link table
k = *(unsigned long *)(s + 12); // byte chunks and count modifiers
q = 0; // current offset in dest buffer
cnt = 0; // mask bit counter
p = 16; // current offset in mask table
unsigned long r22 = 0, r5;
do
{
// if all bits are done, get next mask
if(cnt == 0)
{
// read word from mask data block
r22 = *(unsigned long *)(s + p);
p += 4;
cnt = 32; // bit counter
}
// if next bit is set, chunk is non-linked
if(r22 & 0x80000000)
{
// get next byte
*(unsigned char *)(d + q) = *(unsigned char *)(s + k);
k++, q++;
}
// do copy, otherwise
else
{
// read 16-bit from link table
int r26 = *(unsigned short *)(s + j);
j += 2;
// 'offset'
int r25 = q - (r26 & 0xfff);
// 'count'
int r30 = r26 >> 12;
if(r30 == 0)
{
// get 'count' modifier
r5 = *(unsigned char *)(s + k);
k++;
r30 = r5 + 18;
}
else r30 += 2;
// do block copy
unsigned char *pt = ((unsigned char*)d) + r25;
int i;
for(i=0; i<r30; i++)
{
*(unsigned char *)(d + q) = *(unsigned char *)(pt - 1);
q++, pt++;
}
}
// next bit in mask
r22 <<= 1;
cnt--;
} while(q < i);
}
void untile(unsigned char *dst, unsigned char *src, int xres, int yres)
{
// 8x8 tiles
int x, y;
int t=0;
for (y = 0; y < yres; y += 8)
for (x = 0; x < xres; x += 8)
{
t = !t;
int iy, ix;
for (iy = 0; iy < 8; ++iy, src+=2)
{
unsigned char *d = dst + (y + iy) * xres + x;
for (ix = 0; ix < 2; ++ix)
{
int v = src[ix];
*d++ = ((v>>6)&3);
*d++ = ((v>>4)&3);
*d++ = ((v>>2)&3);
*d++ = ((v)&3);
}
}
}
}
int font_offset[256], font_size[256], fheight;
extern void __SYS_ReadROM(void *buf,u32 len,u32 offset);
/* lowlevel Qoob Modchip disable (code from emukiddid) */
#ifndef HW_RVL #ifndef HW_RVL
/* disable Qoob Modchip before IPL access (emukiddid) */
void ipl_set_config(unsigned char c) void ipl_set_config(unsigned char c)
{ {
volatile unsigned long* exi = (volatile unsigned long*)0xCC006800; volatile unsigned long* exi = (volatile unsigned long*)0xCC006800;
@ -160,97 +54,65 @@ void ipl_set_config(unsigned char c)
} }
#endif #endif
//static u8 *sys_fontarea;
static sys_fontheader *fontHeader;
static u8 *texture;
extern u32 __SYS_LoadFont(void *src,void *dest);
void init_font(void) void init_font(void)
{ {
int i;
/* read font from IPL ROM */
//memcpy(&fontFont, &iplfont, sizeof(iplfont));
memset(fontFont,0,0x3000);
#ifndef HW_RVL #ifndef HW_RVL
/* disable Qoob before accessing IPL */
ipl_set_config(6); ipl_set_config(6);
#endif #endif
__SYS_ReadROM((unsigned char *)&fontFont,0x3000,0x1FCF00);
yay0_decode((unsigned char *)&fontFont, (unsigned char *)&fontWork); /* initialize IPL font */
FONT_HEADER *fnt = ( FONT_HEADER * )&fontWork; fontHeader = memalign(32,sizeof(sys_fontheader));
untile((unsigned char*)&fontFont, (unsigned char*)&fontWork[fnt->offset_tile], fnt->texture_width, fnt->texture_height); SYS_InitFont(&fontHeader);
int i,c;
for (i=0; i<256; ++i) for (i=0; i<256; ++i)
{ {
int c = i; if ((i < fontHeader->first_char) || (i > fontHeader->last_char)) c = fontHeader->inval_char;
else c = i - fontHeader->first_char;
if ((c < fnt->first_char) || (c > fnt->last_char)) c = fnt->subst_char; font_size[i] = ((unsigned char*)fontHeader)[fontHeader->width_table + c];
else c -= fnt->first_char;
font_size[i] = ((unsigned char*)fnt)[fnt->offset_charwidth + c];
int r = c / fnt->texture_columns;
c %= fnt->texture_columns;
font_offset[i] = (r * fnt->cell_height) * fnt->texture_width + (c * fnt->cell_width);
} }
fheight = fnt->cell_height; fheight = fontHeader->cell_height;
texture = memalign(32, fontHeader->cell_width * fontHeader->cell_height / 2);
} }
#define TRANSPARENCY (COLOR_BLACK) u8 draw_done = 0;
void font_DrawChar(unsigned char c, u32 xpos, u32 ypos, u32 color)
{
s32 width;
memset(texture,0,fontHeader->cell_width * fontHeader->cell_height / 2);
GXTexObj texobj;
GX_InitTexObj(&texobj, texture, fontHeader->cell_width, fontHeader->cell_height, GX_TF_I4, GX_CLAMP, GX_CLAMP, GX_FALSE);
GX_LoadTexObj(&texobj, GX_TEXMAP0);
SYS_GetFontTexel(c,texture,0,fontHeader->cell_width/2,&width);
unsigned int blit_lookup[4]={COLOR_BLACK, 0x6d896d77, 0xb584b57b, COLOR_WHITE}; DCFlushRange(texture, fontHeader->cell_width * fontHeader->cell_height / 2);
unsigned int blit_lookup_inv[4]={COLOR_WHITE, 0xb584b57b, 0x6d896d77, 0x258e2573}; GX_InvalidateTexAll();
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
GX_Position2s16(xpos, ypos - fontHeader->cell_height);
GX_TexCoord2f32(0.0, 0.0);
GX_Position2s16(xpos + fontHeader->cell_width, ypos - fontHeader->cell_height);
GX_TexCoord2f32(1.0, 0.0);
GX_Position2s16(xpos + fontHeader->cell_width, ypos);
GX_TexCoord2f32(1.0, 1.0);
GX_Position2s16(xpos, ypos);
GX_TexCoord2f32(0.0, 1.0);
GX_End ();
GX_DrawDone();
}
void setfontcolour (int fcolour) void setfontcolour (int fcolour)
{ {
if (fcolour == COLOR_WHITE)
{
blit_lookup[1] = 0x6d896d77;
blit_lookup[2] = 0xb584b57b;
blit_lookup[3] = COLOR_WHITE;
}
else
{
blit_lookup[1] = fcolour;
blit_lookup[2] = fcolour;
blit_lookup[3] = fcolour;
}
}
void blit_char(int x, int y, unsigned char c, unsigned int *lookup)
{
unsigned char *fnt = ((unsigned char*)fontFont) + font_offset[c];
int ay, ax;
unsigned int llookup;
for (ay=0; ay<fheight; ++ay)
{
int h = (ay + y) * 320;
for (ax=0; ax<font_size[c]; ax++)
{
int v0 = fnt[ax];
int p = h + (( ax + x ) >> 1);
unsigned long o = xfb[whichfb][p];
llookup = lookup[v0];
if ((o != TRANSPARENCY) && (v0 == 0) && (lookup[0] == TRANSPARENCY))
llookup = o;
if ((ax+x) & 1)
{
o &= ~0x00FFFFFF;
o |= llookup & 0x00FFFFFF;
}
else
{
o &= ~0xFF000000;
o |= llookup & 0xFF000000;
}
xfb[whichfb][p] = o;
}
fnt += 512;
}
} }
void write_font(int x, int y, char *string) void write_font(int x, int y, char *string)
@ -258,30 +120,13 @@ void write_font(int x, int y, char *string)
int ox = x; int ox = x;
while (*string && (x < (ox + back_framewidth))) while (*string && (x < (ox + back_framewidth)))
{ {
blit_char(x, y, *string, blit_lookup); font_DrawChar(*string, x -(vmode->fbWidth/2), y-(vmode->efbHeight/2),1);
x += font_size[(u8)*string]; x += font_size[(u8)*string];
string++; string++;
} }
} }
void writex(int x, int y, int sx, int sy, char *string, unsigned int *lookup) int hl = 0;
{
int ox = x;
while ((*string) && ((x) < (ox + sx)))
{
blit_char(x, y, *string, lookup);
x += font_size[(u8)*string];
string++;
}
int ay;
for (ay=0; ay<sy; ay++)
{
int ax;
for (ax=x; ax<(ox + sx); ax += 2) xfb[whichfb][(ay+y)*320+ax/2] = lookup[0];
}
}
void WriteCentre( int y, char *string) void WriteCentre( int y, char *string)
{ {
int x, t; int x, t;
@ -289,21 +134,28 @@ void WriteCentre( int y, char *string)
if (x>back_framewidth) x=back_framewidth; if (x>back_framewidth) x=back_framewidth;
x = (640 - x) >> 1; x = (640 - x) >> 1;
write_font(x, y, string); write_font(x, y, string);
if (hl)
{
png_texture texture;
texture.data = 0;
texture.width = 0;
texture.height = 0;
texture.format = 0;
OpenPNGFromMemory(&texture, Overlay_bar_s2);
DrawTexture(&texture, 0, y-fheight, 640, fheight);
}
} }
void WriteCentre_HL( int y, char *string) void WriteCentre_HL( int y, char *string)
{ {
int x,t,h; hl = 1;
for (x=t=0; t<strlen(string); t++) x += font_size[(u8)string[t]]; WriteCentre(y, string);
if (x>back_framewidth) x = back_framewidth; hl = 0;
h = x;
x = (640 - x) >> 1;
writex(x, y, h, fheight, string, blit_lookup_inv);
} }
/**************************************************************************** /****************************************************************************
* Draw functions * Draw functions (FrameBuffer)
* *
****************************************************************************/ ****************************************************************************/
void fntDrawHLine (int x1, int x2, int y, int color) void fntDrawHLine (int x1, int x2, int y, int color)
@ -336,6 +188,211 @@ void fntDrawBoxFilled (int x1, int y1, int x2, int y2, int color)
for (h = y1; h <= y2; h++) fntDrawHLine (x1, x2, h, color); for (h = y1; h <= y2; h++) fntDrawHLine (x1, x2, h, color);
} }
/****************************************************************************
* Draw functions (GX)
*
****************************************************************************/
/* Callback for the read function */
static void png_read_from_mem (png_structp png_ptr, png_bytep data, png_size_t length)
{
png_file *file = (png_file *)png_get_io_ptr (png_ptr);
/* copy data from image buffer */
memcpy (data, file->buffer + file->offset, length);
/* advance in the file */
file->offset += length;
}
void OpenPNGFromMemory(png_texture *texture, const u8 *buffer)
{
int i;
png_file file;
/* init PNG file structure */
file.buffer = (u8 *) buffer;
file.offset = 0;
/* check for valid magic number */
if (!png_check_sig (file.buffer, 8)) return;
/* create a png read struct */
png_structp png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr) return;
/* create a png info struct */
png_infop info_ptr = png_create_info_struct (png_ptr);
if (!info_ptr)
{
png_destroy_read_struct (&png_ptr, NULL, NULL);
return;
}
/* set callback for the read function */
png_set_read_fn (png_ptr, (png_voidp *)(&file), png_read_from_mem);
/* read png info */
png_read_info (png_ptr, info_ptr);
/* retrieve image information */
u32 width = png_get_image_width(png_ptr, info_ptr);
u32 height = png_get_image_height(png_ptr, info_ptr);
u32 bit_depth = png_get_bit_depth(png_ptr, info_ptr);
u32 color_type = png_get_color_type(png_ptr, info_ptr);
/* support for RGBA8 textures ONLY !*/
if ((color_type != PNG_COLOR_TYPE_RGB_ALPHA) || (bit_depth != 8))
{
png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
return;
}
/* 4x4 tiles are required */
if ((width%4) || (height%4))
{
png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
return;
}
/* allocate memory to store raw image data */
u32 stride = width << 2;
u8 *img_data = memalign (32, stride * height);
if (!img_data)
{
png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
return;
}
/* allocate row pointer data */
png_bytep *row_pointers = (png_bytep *)memalign (32, sizeof (png_bytep) * height);
if (!row_pointers)
{
free (img_data);
png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
return;
}
/* store raw image data */
for (i = 0; i < height; i++)
{
row_pointers[i] = img_data + (i * stride);
}
/* decode image */
png_read_image (png_ptr, row_pointers);
/* finish decompression and release memory */
png_read_end (png_ptr, NULL);
png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
free(row_pointers);
/* initialize texture */
texture->data = memalign(32, stride * height);
memset(texture->data, 0, stride * height);
texture->width = width;
texture->height = height;
texture->format = GX_TF_RGBA8;
/* encode to GX_TF_RGBA8 format (4x4 pixels paired titles) */
u16 *dst_ar = (u16 *)(texture->data);
u16 *dst_gb = (u16 *)(texture->data + 32);
u32 *src1 = (u32 *)(img_data);
u32 *src2 = (u32 *)(img_data + stride);
u32 *src3 = (u32 *)(img_data + 2*stride);
u32 *src4 = (u32 *)(img_data + 3*stride);
u32 pixel,h,w;
for (h=0; h<height; h+=4)
{
for (w=0; w<width; w+=4)
{
/* line N (4 pixels) */
for (i=0; i<4; i++)
{
pixel = *src1++;
*dst_ar++= ((pixel << 8) & 0xff00) | ((pixel >> 24) & 0x00ff);
*dst_gb++= (pixel >> 8) & 0xffff;
}
/* line N + 1 (4 pixels) */
for (i=0; i<4; i++)
{
pixel = *src2++;
*dst_ar++= ((pixel << 8) & 0xff00) | ((pixel >> 24) & 0x00ff);
*dst_gb++= (pixel >> 8) & 0xffff;
}
/* line N + 2 (4 pixels) */
for (i=0; i<4; i++)
{
pixel = *src3++;
*dst_ar++= ((pixel << 8) & 0xff00) | ((pixel >> 24) & 0x00ff);
*dst_gb++= (pixel >> 8) & 0xffff;
}
/* line N + 3 (4 pixels) */
for (i=0; i<4; i++)
{
pixel = *src4++;
*dst_ar++= ((pixel << 8) & 0xff00) | ((pixel >> 24) & 0x00ff);
*dst_gb++= (pixel >> 8) & 0xffff;
}
/* next paired tiles */
dst_ar += 16;
dst_gb += 16;
}
/* next 4 lines */
src1 = src4;
src2 = src1 + width;
src3 = src2 + width;
src4 = src3 + width;
}
/* release memory */
free(img_data);
/* flush texture data from cache */
DCFlushRange(texture->data, height * stride);
}
void DrawTexture(png_texture *texture, u32 xOrigin, u32 yOrigin, u32 w, u32 h)
{
if (texture->data)
{
/* load texture object */
GXTexObj texObj;
GX_InitTexObj(&texObj, texture->data, texture->width, texture->height, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE);
GX_LoadTexObj(&texObj, GX_TEXMAP0);
GX_InvalidateTexAll();
DCFlushRange(texture->data, texture->width * texture->height * 4);
/* current coordinate system */
xOrigin -= (vmode->fbWidth/2);
yOrigin -= (vmode->efbHeight/2);
/* Draw item */
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
GX_Position2s16(xOrigin,yOrigin+h);
GX_TexCoord2f32(0.0, 1.0);
GX_Position2s16(xOrigin+w,yOrigin+h);
GX_TexCoord2f32(1.0, 1.0);
GX_Position2s16(xOrigin+w,yOrigin);
GX_TexCoord2f32(1.0, 0.0);
GX_Position2s16(xOrigin,yOrigin);
GX_TexCoord2f32(0.0, 0.0);
GX_End ();
GX_DrawDone();
free(texture->data);
}
}
/**************************************************************************** /****************************************************************************
* Display functions * Display functions
* *
@ -344,16 +401,19 @@ u8 SILENT = 0;
void SetScreen () void SetScreen ()
{ {
GX_CopyDisp(xfb[whichfb], GX_FALSE);
GX_Flush();
VIDEO_SetNextFramebuffer (xfb[whichfb]); VIDEO_SetNextFramebuffer (xfb[whichfb]);
VIDEO_Flush (); VIDEO_Flush ();
VIDEO_WaitVSync (); VIDEO_WaitVSync ();
} }
void ClearScreen () void ClearScreen (GXColor color)
{ {
whichfb ^= 1; whichfb ^= 1;
memcpy (xfb[whichfb], backdrop, 1280 * 480); GX_SetCopyClear(color,0x00ffffff);
back_framewidth = 440; GX_CopyDisp(xfb[whichfb], GX_TRUE);
GX_Flush();
} }
void WaitButtonA () void WaitButtonA ()
@ -366,7 +426,7 @@ void WaitButtonA ()
void WaitPrompt (char *msg) void WaitPrompt (char *msg)
{ {
if (SILENT) return; if (SILENT) return;
ClearScreen(); ClearScreen((GXColor)BLACK);
WriteCentre(254, msg); WriteCentre(254, msg);
WriteCentre(254 + fheight, "Press A to Continue"); WriteCentre(254 + fheight, "Press A to Continue");
SetScreen(); SetScreen();
@ -377,7 +437,7 @@ void ShowAction (char *msg)
{ {
if (SILENT) return; if (SILENT) return;
ClearScreen(); ClearScreen((GXColor)BLACK);
WriteCentre(254, msg); WriteCentre(254, msg);
SetScreen(); SetScreen();
} }
@ -390,11 +450,4 @@ void ShowAction (char *msg)
****************************************************************************/ ****************************************************************************/
void unpackBackdrop () void unpackBackdrop ()
{ {
unsigned long res, inbytes, outbytes;
inbytes = gpback_COMPRESSED;
outbytes = gpback_RAW;
res = uncompress ((Bytef *) &backdrop[0], &outbytes, (Bytef *) &gpback[0], inbytes);
if (res != Z_OK) while (1);
} }

View File

@ -25,6 +25,26 @@
#ifndef _FONT_H #ifndef _FONT_H
#define _FONT_H #define _FONT_H
#define BLACK {0,0,0,255}
#define WHITE {255,255,255,255}
typedef struct
{
u8 *buffer;
u32 offset;
} png_file;
typedef struct
{
u8 *data;
u16 width;
u16 height;
u8 format;
} png_texture;
extern void OpenPNGFromMemory(png_texture *texture, const u8 *buffer);
extern void DrawTexture(png_texture *texture, u32 xOrigin, u32 yOrigin, u32 w, u32 h);
extern void init_font(void); extern void init_font(void);
extern void WriteCentre_HL( int y, char *string); extern void WriteCentre_HL( int y, char *string);
extern void WriteCentre (int y, char *text); extern void WriteCentre (int y, char *text);
@ -33,7 +53,7 @@ extern void WaitPrompt (char *msg);
extern void ShowAction (char *msg); extern void ShowAction (char *msg);
extern void WaitButtonA (); extern void WaitButtonA ();
extern void unpackBackdrop (); extern void unpackBackdrop ();
extern void ClearScreen (); extern void ClearScreen (GXColor color);
extern void SetScreen (); extern void SetScreen ();
extern void fntDrawBoxFilled (int x1, int y1, int x2, int y2, int color); extern void fntDrawBoxFilled (int x1, int y1, int x2, int y2, int color);
extern void setfontcolour (int fcolour); extern void setfontcolour (int fcolour);
@ -42,4 +62,6 @@ extern int font_size[256];
extern u16 back_framewidth; extern u16 back_framewidth;
extern u8 SILENT; extern u8 SILENT;
extern void font_DrawChar(unsigned char c, u32 xpos, u32 ypos, u32 color);
#endif #endif

View File

@ -165,7 +165,7 @@ void DrawGGCodes ()
int i,j; int i,j;
unsigned char c[2] = { 0, 0 }; unsigned char c[2] = { 0, 0 };
ClearScreen (); ClearScreen ((GXColor)BLACK);
WriteCentre (134, menutitle); WriteCentre (134, menutitle);
for (i = 0; i < MAXCODES; i++) for (i = 0; i < MAXCODES; i++)

File diff suppressed because it is too large Load Diff

View File

@ -24,25 +24,10 @@
#include "shared.h" #include "shared.h"
#include "font.h" #include "font.h"
#include "dkpro.h" #include "Background_intro_c1.h"
#include "Background_intro_c2.h"
/* #include "Background_intro_c3.h"
* Unpack the devkit pro logo #include "Background_intro_c4.h"
*/
u32 *dkproraw;
int dkunpack ()
{
unsigned long res, inbytes, outbytes;
inbytes = dkpro_COMPRESSED;
outbytes = dkpro_RAW;
dkproraw = malloc (dkpro_RAW + 16);
res = uncompress ((Bytef *) dkproraw, &outbytes, (Bytef *) &dkpro[0], inbytes);
if (res == Z_OK) return 1;
free (dkproraw);
return 0;
}
/* /*
* This is the legal stuff - which must be shown at program startup * This is the legal stuff - which must be shown at program startup
@ -53,11 +38,9 @@ int dkunpack ()
void legal () void legal ()
{ {
int ypos = 64; int ypos = 64;
png_texture texture;
whichfb ^= 1; ClearScreen((GXColor)BLACK);
VIDEO_ClearFrameBuffer(&TVNtsc480IntDf, xfb[whichfb], COLOR_BLACK);
back_framewidth = 640;
WriteCentre (ypos, "Genesis Plus Sega Mega Drive Emulator (v1.2a)"); WriteCentre (ypos, "Genesis Plus Sega Mega Drive Emulator (v1.2a)");
ypos += fheight; ypos += fheight;
WriteCentre (ypos, "(C) 1999 - 2003 Charles MacDonald"); WriteCentre (ypos, "(C) 1999 - 2003 Charles MacDonald");
@ -75,30 +58,54 @@ void legal ()
WriteCentre (ypos, "Nintendo Gamecube Porting code."); WriteCentre (ypos, "Nintendo Gamecube Porting code.");
ypos += fheight; ypos += fheight;
WriteCentre (ypos, "You are free to use it as you wish."); WriteCentre (ypos, "You are free to use it as you wish.");
ypos += 6 * fheight; ypos += 2*fheight;
if (dkunpack ()) texture.data = 0;
{ texture.width = 0;
int w, h, p, dispoffset; texture.height = 0;
p = 0; texture.format = 0;
dispoffset = (316 * 320) + ((640 - dkpro_WIDTH) >> 2); OpenPNGFromMemory(&texture, Background_intro_c4);
DrawTexture(&texture, (640-texture.width)/2, ypos, texture.width, texture.height);
ypos += texture.height + 2 * fheight;
for (h = 0; h < dkpro_HEIGHT; h++)
{
for (w = 0; w < dkpro_WIDTH >> 1; w++)
xfb[whichfb][dispoffset + w] = dkproraw[p++];
dispoffset += 320;
}
free (dkproraw);
}
else WriteCentre (ypos, "Developed with DevkitPPC and libOGC");
#ifdef HW_RVL #ifdef HW_RVL
SetScreen (); SetScreen ();
sleep(1); sleep(1);
#endif #endif
WriteCentre (ypos, "Press A to continue"); //WriteCentre (ypos, "Press A to continue");
SetScreen (); SetScreen ();
WaitButtonA (); //WaitButtonA ();
sleep (3);
ClearScreen((GXColor)BLACK);
texture.data = 0;
texture.width = 0;
texture.height = 0;
texture.format = 0;
OpenPNGFromMemory(&texture, Background_intro_c1);
DrawTexture(&texture, (640-texture.width)/2, (480-texture.height)/2, texture.width, texture.height);
SetScreen ();
sleep (2);
ClearScreen((GXColor)WHITE);
texture.data = 0;
texture.width = 0;
texture.height = 0;
texture.format = 0;
OpenPNGFromMemory(&texture, Background_intro_c2);
DrawTexture(&texture, (640-texture.width)/2, (480-texture.height)/2, texture.width, texture.height);
SetScreen ();
sleep (2);
ClearScreen((GXColor)BLACK);
texture.data = 0;
texture.width = 0;
texture.height = 0;
texture.format = 0;
OpenPNGFromMemory(&texture, Background_intro_c3);
DrawTexture(&texture, (640-texture.width)/2, (480-texture.height)/2, texture.width, texture.height);
SetScreen ();
sleep (3);
} }

View File

@ -28,11 +28,26 @@
#include "file_fat.h" #include "file_fat.h"
#include "filesel.h" #include "filesel.h"
#include "Banner_bottom.h"
#include "Banner_top.h"
#include "Banner_main.h"
#include "Background_main.h"
#include "Main_logo.h"
#include "Main_play.h"
#include "Main_load.h"
#include "Main_options.h"
#include "Main_file.h"
#include "Main_reset.h"
#include "Main_info.h"
#include "Button.h"
#include "Button_over.h"
#ifdef HW_RVL #ifdef HW_RVL
#include <wiiuse/wpad.h> #include <wiiuse/wpad.h>
#include <di/di.h> #include <di/di.h>
#endif #endif
/*************************************************************************** /***************************************************************************
* drawmenu * drawmenu
* *
@ -42,26 +57,118 @@
char menutitle[60] = { "" }; char menutitle[60] = { "" };
int menu = 0; int menu = 0;
#define SCROLL_V 0
#define SCROLL_H 1
#define SCROLL_NONE 2
typedef struct
{
u8 *img;
char txt[30];
u32 x;
u32 y;
u32 w;
u32 h;
} gui_item;
typedef struct
{
gui_item item;
u8 *img_norm;
u8 *img_over;
u8 scroll;
u32 x;
u32 y;
u32 w;
u32 h;
} gui_butn;
gui_butn main_buttons[6] =
{
{{Main_play , "", 108, 76, 92, 88}, Button, Button_over, SCROLL_NONE, 80, 50, 148, 132},
{{Main_load , "", 280, 72, 80, 92}, Button, Button_over, SCROLL_NONE, 246, 50, 148, 132},
{{Main_options, "", 456 , 76, 60, 88}, Button, Button_over, SCROLL_NONE, 412, 50, 148, 132},
{{Main_file , "", 114, 216, 80, 92}, Button, Button_over, SCROLL_NONE, 80, 194, 148, 132},
{{Main_reset , "", 282, 224, 76, 84}, Button, Button_over, SCROLL_NONE, 246, 194, 148, 132},
{{Main_info , "", 446, 212, 88, 96}, Button, Button_over, SCROLL_NONE, 412, 194, 148, 132}
};
void DrawMenu (gui_butn *butn_list, int nb_butns, int selected)
{
int i;
gui_item *item;
gui_butn *butn;
/* reset texture data */
png_texture texture;
memset(&texture,0,sizeof(png_texture));
/* draw background items */
ClearScreen ((GXColor)BLACK);
OpenPNGFromMemory(&texture, Background_main);
DrawTexture(&texture, (640-texture.width)/2, (480-124-texture.height)/2, texture.width, texture.height);
/**OpenPNGFromMemory(&texture, Banner_bottom);
DrawTexture(&texture, 640-texture.width, 480-texture.height, texture.width, texture.height);
OpenPNGFromMemory(&texture, Banner_top);
DrawTexture(&texture, 640-texture.width, 0, texture.width, texture.height);
OpenPNGFromMemory(&texture, Main_logo);
DrawTexture(&texture, 444, 28, 176, 48);*/
OpenPNGFromMemory(&texture, Banner_main);
DrawTexture(&texture, 0, 480-texture.height, texture.width, texture.height);
OpenPNGFromMemory(&texture, Main_logo);
DrawTexture(&texture, (640-texture.width)/2, 370, texture.width, texture.height);
/* draw selectable items */
for (i=0; i<nb_butns; i++)
{
butn = &butn_list[i];
/* draw button */
if (i == selected) OpenPNGFromMemory(&texture, butn->img_over);
else OpenPNGFromMemory(&texture, butn->img_norm);
DrawTexture(&texture, butn->x, butn->y, butn->w, butn->h);
memset(&texture,0,sizeof(png_texture));
/* draw item */
item = &butn->item;
if (item->img)
{
OpenPNGFromMemory(&texture, item->img);
DrawTexture(&texture, item->x, item->y, item->w, item->h);
memset(&texture,0,sizeof(png_texture));
}
else
{
/* TODO */
}
}
}
void drawmenu (char items[][25], int maxitems, int selected) void drawmenu (char items[][25], int maxitems, int selected)
{ {
int i; int i;
int ypos; int ypos;
ypos = (310 - (fheight * maxitems)) >> 1; ypos = (226 - (fheight * maxitems)) >> 1;
ypos += 130; ypos += 130;
ClearScreen (); DrawMenu (main_buttons, 6, selected);
WriteCentre (134, menutitle);
/*WriteCentre (134, menutitle);
for (i = 0; i < maxitems; i++) for (i = 0; i < maxitems; i++)
{ {
if (i == selected) WriteCentre_HL (i * fheight + ypos, (char *) items[i]); if (i == selected) WriteCentre_HL (i * fheight + ypos, (char *) items[i]);
else WriteCentre (i * fheight + ypos, (char *) items[i]); else WriteCentre (i * fheight + ypos, (char *) items[i]);
} }*/
SetScreen (); SetScreen ();
} }
/**************************************************************************** /****************************************************************************
* domenu * domenu
* *
@ -144,8 +251,8 @@ void soundmenu ()
menu = 0; menu = 0;
while (quit == 0) while (quit == 0)
{ {
sprintf (items[0], "PSG Volume: %1.2f", config.psg_preamp); sprintf (items[0], "PSG Volume: %1.2f", (double)config.psg_preamp/100.0);
sprintf (items[1], "FM Volume: %1.2f", config.fm_preamp); sprintf (items[1], "FM Volume: %1.2f", (double)config.fm_preamp/100.0);
sprintf (items[2], "Volume Boost: %dX", config.boost); sprintf (items[2], "Volume Boost: %dX", config.boost);
sprintf (items[3], "LowPass Filter: %s", config.filter ? " ON":"OFF"); sprintf (items[3], "LowPass Filter: %s", config.filter ? " ON":"OFF");
if (config.hq_fm == 0) sprintf (items[4], "HQ YM2612: OFF"); if (config.hq_fm == 0) sprintf (items[4], "HQ YM2612: OFF");
@ -158,18 +265,18 @@ void soundmenu ()
{ {
case 0: case 0:
case -2: case -2:
if (ret<0) config.psg_preamp -= 0.01; if (ret<0) config.psg_preamp --;
else config.psg_preamp += 0.01; else config.psg_preamp ++;
if (config.psg_preamp < 0.0) config.psg_preamp = 5.0; if (config.psg_preamp < 0) config.psg_preamp = 500;
if (config.psg_preamp > 5.0) config.psg_preamp = 0.0; if (config.psg_preamp > 500) config.psg_preamp = 0;
break; break;
case 1: case 1:
case -3: case -3:
if (ret<0) config.fm_preamp -= 0.01; if (ret<0) config.fm_preamp --;
else config.fm_preamp += 0.01; else config.fm_preamp ++;
if (config.fm_preamp < 0.0) config.fm_preamp = 5.0; if (config.fm_preamp < 0) config.fm_preamp = 500;
if (config.fm_preamp > 5.0) config.fm_preamp = 0.0; if (config.fm_preamp > 500) config.fm_preamp = 0;
break; break;
case 2: case 2:
@ -193,8 +300,8 @@ void soundmenu ()
case 5: case 5:
config.fm_core ^= 1; config.fm_core ^= 1;
config.psg_preamp = config.fm_core ? 2.5 : 1.5; config.psg_preamp = config.fm_core ? 250 : 150;
config.fm_preamp = 1.0; config.fm_preamp = 100;
if (genromsize) if (genromsize)
{ {
if (!config.fm_core) memcpy(fm_reg,YM2612.REG,sizeof(fm_reg)); if (!config.fm_core) memcpy(fm_reg,YM2612.REG,sizeof(fm_reg));
@ -1017,9 +1124,9 @@ void showrominfo ()
while (quit == 0) while (quit == 0)
{ {
if (redraw) if (redraw)
{ {
ClearScreen (); ClearScreen ((GXColor)BLACK);
ypos = 134; ypos = 134;
WriteCentre(ypos, "ROM Header Information"); WriteCentre(ypos, "ROM Header Information");
@ -1138,6 +1245,7 @@ void MainMenu (u32 fps)
while (quit == 0) while (quit == 0)
{ {
crccheck = crc32 (0, &sram.sram[0], 0x10000); crccheck = crc32 (0, &sram.sram[0], 0x10000);
strcpy (menutitle,"");
if (genromsize && (crccheck != sram.crc)) strcpy (menutitle, "*** SRAM has been modified ***"); if (genromsize && (crccheck != sram.crc)) strcpy (menutitle, "*** SRAM has been modified ***");
else if (genromsize) sprintf (menutitle, "%d FPS",fps); else if (genromsize) sprintf (menutitle, "%d FPS",fps);

254
source/ngc/gui/menu.c.gx Normal file
View File

@ -0,0 +1,254 @@
#include "shared.h"
#include "dvd.h"
#include "font.h"
#include "file_dvd.h"
#include "file_fat.h"
#include "filesel.h"
#include "Banner_bottom.h"
#include "Banner_top.h"
#include "Banner_main.h"
#include "Background_main.h"
#include "Main_logo.h"
#ifdef HW_RVL
#include <wiiuse/wpad.h>
#include <di/di.h>
#endif
#define SCROLL_V 0
#define SCROLL_H 1
#define SCROLL_NONE 2
typedef struct
{
u8 *img;
char txt[30];
u32 x;
u32 y;
u32 w;
u32 h;
} gui_item;
typedef struct
{
gui_item item;
u8 *img_norm;
u8 *img_over;
u8 scroll;
u32 x;
u32 y;
u32 w;
u32 h;
} gui_butn;
typedef struct
{
u8 nb_items;
u8 nb_butns;
u8 selected;
u8 stride;
gui_item *item_list;
gui_bttn *butn_list;
int (*bttn_callback)(int val);
int (*special_callback)();
} gui_menu;
gui_butn main_buttons[6] =
{
{{Main_play , "", 108, 76, 92, 88}, Button, Button_over, SCROLL_NONE, 80, 50, 148, 132},
{{Main_load , "", 280, 72, 80, 92}, Button, Button_over, SCROLL_NONE, 246, 50, 148, 132},
{{Main_options, "", 456 , 76, 60, 88}, Button, Button_over, SCROLL_NONE, 412, 50, 148, 132},
{{Main_file , "", 114, 216, 80, 92}, Button, Button_over, SCROLL_NONE, 80, 194, 148, 132},
{{Main_reset , "", 282, 224, 76, 84}, Button, Button_over, SCROLL_NONE, 246, 194, 148, 132},
{{Main_info , "", 446, 212, 88, 96}, Button, Button_over, SCROLL_NONE, 412, 194, 148, 132}
}
#ifdef HW_RVL
gui_butn loadrom_buttons[4] =
{
{{Load_recent, "", 276, 120, 88, 96}, Button, Button_over, SCROLL_NONE, 246, 102, 148, 132},
{{Load_sd , "", 110, 266, 88, 96}, Button, Button_over, SCROLL_NONE, 80, 248, 148, 132},
{{Load_usb , "", 276, 266, 88, 96}, Button, Button_over, SCROLL_NONE, 246, 248, 148, 132},
{{Load_dvd , "", 442, 266, 88, 96}, Button, Button_over, SCROLL_NONE, 412, 248, 148, 132}
}
#else
gui_butn loadrom_buttons[3] =
{
{{Load_recent, "", 110, 198, 88, 96}, Button, Button_over, SCROLL_NONE, 80, 180, 148, 132},
{{Load_sd , "", 276, 198, 88, 96}, Button, Button_over, SCROLL_NONE, 246, 180, 148, 132},
{{Load_dvd , "", 442, 198, 88, 96}, Button, Button_over, SCROLL_NONE, 412, 180, 148, 132}
}
#endif
gui_butn options_buttons[5] =
{
{{Option_system, "", 114, 142, 80, 92}, Button, Button_over, SCROLL_NONE, 80, 120, 148, 132},
{{Option_video , "", 288, 150, 64, 84}, Button, Button_over, SCROLL_NONE, 246, 120, 148, 132},
{{Option_audio , "", 464, 154, 44, 80}, Button, Button_over, SCROLL_NONE, 412, 120, 148, 132},
{{Option_ctrl , "", 192, 286, 88, 92}, Button, Button_over, SCROLL_NONE, 162, 264, 148, 132},
{{Option_ggenie, "", 360, 282, 88, 96}, Button, Button_over, SCROLL_NONE, 330, 264, 148, 132}
}
gui_menu main_m = { 6, 6, 0, 3, &main_back, &main_buttons, main_func, exit_func};
gui_menu option_m = { 9, 5, 0, 3, &misc_back, &m_options_buttons, m_option_func, main_menu};
gui_menu manage_m = {12, 7, 0, 1, &misc_back, &manage_buttons, manage_func, main_menu};
gui_menu load_m = { 9, 4, 0, 1, &misc_back, &m_load_buttons, m_load_func, main_menu};
gui_menu video_m = { 9, 5, 0, 3, &m_options_back, &m_options_buttons, m_option_func, main_menu};
gui_menu option_m = {8, 5, 0, 3, &m_options_back, &m_options_buttons, m_option_func, main_menu};
void DrawMenu (gui_menu *menu)
{
int i;
gui_item *item;
gui_bttn *butn;
/* reset texture data */
png_texture texture;
memset(texture,0,sizeof(png_texture));
/* clear EFB */
ClearScreen ((GXColor)BLACK);
/* draw background items */
for (i=0; i<menu->nb_items; i++)
{
item = &menu->item_list[i];
if (item->img)
{
OpenPNGFromMemory(&texture, item->img);
DrawTexture(&texture, item->x, item->y, item->w, item->h);
memset(texture,0,sizeof(png_texture));
}
else
{
/* TODO */
}
}
/* draw selectable items */
for (i=0; i<menu->nb_butns; i++)
{
/* draw button */
butn = &menu->butn_list[i];
if (i == menu->selected) OpenPNGFromMemory(&texture, butn->img_over);
else OpenPNGFromMemory(&texture, butn->img_norm);
DrawTexture(&texture, butn->x, butn->y, butn->w, butn->h);
memset(texture,0,sizeof(png_texture));
/* draw item */
item = butn->item;
if (item->img)
{
OpenPNGFromMemory(&texture, item->img);
DrawTexture(&texture, item->x, item->y, item->w, item->h);
memset(texture,0,sizeof(png_texture));
}
else
{
/* TODO */
}
}
}
int DoMenu (gui_menu *menu)
{
int redraw = 1;
int sel = 0;
short p;
gui_bttn *butn;
while (1)
{
if (redraw & 1) DrawMenu (menu);
redraw = 0;
p = GetInputKeys();
if (p & MENU_KEY_UP)
{
butn = &menu->butn_list[menu->selected];
if (butn->scroll == TYPE_SCROLL_V)
{
ret = (*menu->butn_callback)(-menu->selected);
if (ret != -1) return ret;
redraw = 1;
}
else
{
sel = menu->selected - menu->stride;
if (sel < 0) sel = 0;
if (sel != menu->selected) redraw = 1;
menu->selected = sel;
}
}
else if (p & MENU_KEY_DOWN)
{
butn = &menu->butn_list[menu->selected];
if (butn->scroll == TYPE_SCROLL_V)
{
ret = (*menu->butn_callback)(menu->selected);
if (ret != -1) return ret;
redraw = 1;
}
else
{
sel = menu->selected + menu->stride;
if (sel >= menu->max_butns) sel = menu->max_butns;
if (sel != menu->selected) redraw = 1;
menu->selected = sel;
}
}
else if (p & MENU_KEY_RIGHT)
{
butn = &menu->butn_list[menu->selected];
if (butn->scroll == TYPE_SCROLL_H)
{
ret = (*menu->butn_callback)(menu->selected);
if (ret != -1) return ret;
redraw = 1;
}
else
{
sel = menu->selected + 1;
if (sel >= menu->max_butns) sel = menu->max_butns;
if (sel != menu->selected) redraw = 1;
menu->selected = sel;
}
}
else if (p & MENU_KEY_LEFT)
{
butn = &menu->butn_list[menu->selected];
if (butn->scroll == TYPE_SCROLL_H)
{
ret = (*menu->butn_callback)(-menu->selected);
if (ret != -1) return ret;
redraw = 1;
}
else
{
sel = menu->selected - menu->stride;
if (sel < 0) sel = 0;
if (sel != menu->selected) redraw = 1;
menu->selected = sel;
}
}
if (p & MENU_KEY_SELECT)
{
ret = (*menu->butn_callback)(menu->selected);
redraw = 1;
if (ret != -1) return ret;
}
else if (p & MENU_KEY_CANCEL)
{
return 0;
}
}
return 0;
}

View File

@ -199,23 +199,23 @@ int main (int argc, char *argv[])
MainMenu (FramesPerSecond); MainMenu (FramesPerSecond);
ConfigRequested = 0; ConfigRequested = 0;
/* reset framesync */
frameticker = 0;
/* reset framecounts */ /* reset framecounts */
RenderedFrames = 0; RenderedFrames = 0;
TotalFrames = 0; TotalFrames = 0;
FramesPerSecond = vdp_rate; FramesPerSecond = vdp_rate;
/* start audio & video */ /* start audio & video */
ogc_audio__start();
ogc_video__start(); ogc_video__start();
ogc_audio__start();
/* reset framesync */
frameticker = 1;
} }
if (frameticker > 1) if (frameticker > 1)
{ {
/* skip frame */ /* skip frame */
frameticker--; frameticker-=2;
system_frame (1); system_frame (1);
/* update audio only */ /* update audio only */
@ -225,19 +225,17 @@ int main (int argc, char *argv[])
{ {
/* framesync */ /* framesync */
while (frameticker < 1) usleep(1); while (frameticker < 1) usleep(1);
frameticker--;
/* render frame */ /* render frame */
system_frame (0); system_frame (0);
/* update video & audio */ /* update video & audio */
ogc_audio__update();
ogc_video__update(); ogc_video__update();
ogc_audio__update();
RenderedFrames++; RenderedFrames++;
} }
/* update framesync */
frameticker--;
/* update framecounts */ /* update framecounts */
TotalFrames++; TotalFrames++;
if (TotalFrames == vdp_rate) if (TotalFrames == vdp_rate)

View File

@ -3,7 +3,7 @@
* *
* Genesis Plus GX audio support * Genesis Plus GX audio support
* *
* code by Softdev (2006), Eke-Eke (2007,2008) * code by Eke-Eke (2007,2008)
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -28,28 +28,33 @@
To prevent audio clashes, we use double buffering technique: To prevent audio clashes, we use double buffering technique:
one buffer is the active DMA buffer one buffer is the active DMA buffer
the other one is the current work buffer (updated during frame emulation) the other one is the current work buffer (updated during frame emulation)
We do not need more since frame emulation is synchronized with DMA execution We do not need more since frame emulation and DMA operation are synchronized
*/ */
u8 soundbuffer[2][3840] ATTRIBUTE_ALIGN(32); u8 soundbuffer[2][3840] ATTRIBUTE_ALIGN(32);
/* Current work soundbuffer */ /* Current work soundbuffer */
u8 mixbuffer; u8 mixbuffer;
/* Current DMA length (required to be a factor of 32-bytes) /* Next DMA length */
length is calculated regarding current emulation timings: static u32 dma_len;
PAL timings : 50 frames/sec, 48000 samples/sec = 960 samples per frame = 3840 bytes (16 bits stereo samples)
NTSC timings: 60 frames/sec, 48000 samples/sec = 800 samples per frame = 3200 bytes (16 bits stereo samples) /* Current delta between output & expected sample counts */
*/ static int delta;
static u32 dma_len = 3200;
/* Expected sample count x 100 */
static u32 dma_sync;
/* audio DMA status */
static u8 audioStarted;
/*** /***
AudioDmaCallback AudioDmaCallback
Genesis Plus only provides sound data on completion of each frame. In 50Hz emulation mode, we synchronize frame emulation with audio DMA
To try to make the audio less choppy, we synchronize frame emulation with audio DMA 50Hz VSYNC period is shorter than DMA period so there is no video frameskipping
This ensure we don't access current active audiobuffer until a new DMA has been started In 60Hz modes, VSYNC period is longer than default DMA period so it requires different sync.
This also makes frame emulation sync completely independent from video sync
***/ ***/
static void AudioDmaCallback() static void AudioDmaCallback()
{ {
frameticker++; frameticker++;
@ -58,60 +63,95 @@ static void AudioDmaCallback()
/*** /***
ogc_audio__init ogc_audio__init
This function initializes the Audio Interface and DMA callback This function initializes the Audio Interface
Default samplerate is set to 48khZ Default samplerate is set to 48khZ
***/ ***/
void ogc_audio__init(void) void ogc_audio__init(void)
{ {
AUDIO_Init (NULL); AUDIO_Init (NULL);
AUDIO_SetDSPSampleRate (AI_SAMPLERATE_48KHZ); AUDIO_SetDSPSampleRate (AI_SAMPLERATE_48KHZ);
AUDIO_RegisterDMACallback (AudioDmaCallback);
memset(soundbuffer, 0, 2 * 3840);
} }
/*** /***
ogc_audio__update ogc_audio__update
This function is called at the end of each frame, once the current soundbuffer has been updated This function is called at the end of each frame
DMA sync and switching ensure we never access the active DMA buffer Genesis Plus only provides sound data on completion of each frame.
This function set the next DMA buffer DMA sync and switching ensure we never access the active DMA buffer and sound clashes never happen
Parameters will be taken in account ONLY when current DMA has finished This function retrieves samples for the frame then set the next DMA parameters
Parameters will be taken in account only when current DMA operation is over
***/ ***/
void ogc_audio__update(void) void ogc_audio__update()
{ {
AUDIO_InitDMA((u32) soundbuffer[mixbuffer], dma_len); u32 size = dma_len;
DCFlushRange(soundbuffer[mixbuffer], dma_len);
/* get audio samples */
audio_update(dma_len);
/* update DMA parameters */
s16 *sb = (s16 *)(soundbuffer[mixbuffer]);
mixbuffer ^= 1; mixbuffer ^= 1;
size = size << 2;
DCFlushRange((void *)sb, size);
AUDIO_InitDMA((u32) sb, size);
/* Start Audio DMA */
/* this is only called once, DMA is automatically restarted when previous one is over */
/* When DMA parameters are not updated, same soundbuffer is played again */
if (!audioStarted)
{
audioStarted = 1;
AUDIO_StartDMA();
if (frameticker > 1) frameticker = 1;
}
/* VIDEO interrupt sync: we approximate DMA length (see below) */
/* DMA length should be 32 bytes so we use 800 or 808 samples */
if (dma_sync)
{
delta += (dma_len * 100) - dma_sync;
if (delta < 0) dma_len = 808;
else dma_len = 800;
}
} }
/*** /***
ogc_audio__start ogc_audio__start
This function restarts Audio DMA processing This function resets the audio engine
This is called only ONCE, when emulation loop starts or when coming back from Main Menu This is called when coming back from Main Menu
DMA length is used for frame emulation synchronization (PAL & NTSC timings)
DMA is *automatically* restarted once the configured audio length has been output
When DMA parameters are not updated, same soundbuffer is played again
DMA parameters can be updated using successive calls to AUDIO_InitDMA (see above)
***/ ***/
void ogc_audio__start(void) void ogc_audio__start(void)
{ {
dma_len = vdp_pal ? 3840 : 3200; /* initialize default DMA length */
memset(soundbuffer[0], 0, dma_len); /* PAL (50Hz): 20000 us period --> 960 samples/frame at 48kHz */
AUDIO_InitDMA((u32) soundbuffer[0], dma_len); /* NTSC (60Hz): 16667 us period --> 800 samples/frame at 48kHz */
DCFlushRange(soundbuffer[0], dma_len); dma_len = vdp_pal ? 960 : 800;
AUDIO_StartDMA(); dma_sync = 0;
mixbuffer = 1; mixbuffer = 0;
delta = 0;
/* default case: we use DMA interrupt to synchronize frame emulation */
if (vdp_pal | gc_pal) AUDIO_RegisterDMACallback (AudioDmaCallback);
/* 60hz video mode requires synchronization with Video interrupt */
/* VSYNC period is 16715 us which is approx. 802.32 samples */
/* to prevent audio/video desynchronization, we approximate the exact */
/* number of samples by using alternate audio length */
else dma_sync = 80232;
} }
/*** /***
ogc_audio__stop ogc_audio__stop
This function reset current Audio DMA process This function stops current Audio DMA process
This is called when going back to Main Menu This is called when going back to Main Menu
DMA need to be restarted when going back to the game (see above) DMA need to be restarted when going back to the game (see above)
***/ ***/
void ogc_audio__stop(void) void ogc_audio__stop(void)
{ {
AUDIO_RegisterDMACallback(NULL);
AUDIO_StopDMA (); AUDIO_StopDMA ();
memset(soundbuffer, 0, 2 * 3840);
audioStarted = 0;
} }

View File

@ -140,7 +140,7 @@ static void pad_config(int num, int padtype)
PAD_ScanPads(); PAD_ScanPads();
} }
ClearScreen(); ClearScreen((GXColor)BLACK);
sprintf(msg,"Press key for %s",keys_name[i]); sprintf(msg,"Press key for %s",keys_name[i]);
WriteCentre(254, msg); WriteCentre(254, msg);
SetScreen(); SetScreen();
@ -367,7 +367,7 @@ static void wpad_config(u8 num, u8 exp, u8 padtype)
} }
/* user information */ /* user information */
ClearScreen(); ClearScreen((GXColor)BLACK);
sprintf(msg,"Press key for %s",keys_name[i]); sprintf(msg,"Press key for %s",keys_name[i]);
WriteCentre(254, msg); WriteCentre(254, msg);
SetScreen(); SetScreen();

View File

@ -40,6 +40,9 @@ int whichfb = 0; /* Current Framebuffer */
GXRModeObj *vmode; /* Default Video Mode */ GXRModeObj *vmode; /* Default Video Mode */
u8 *texturemem; /* Texture Data */ u8 *texturemem; /* Texture Data */
/* 50/60hz flag */
u8 gc_pal = 0;
/*** NTSC Filters ***/ /*** NTSC Filters ***/
sms_ntsc_t sms_ntsc; sms_ntsc_t sms_ntsc;
md_ntsc_t md_ntsc; md_ntsc_t md_ntsc;
@ -276,9 +279,6 @@ static GXRModeObj *tvmodes[6] =
&TV50hz_576i &TV50hz_576i
}; };
/* 50/60hz flag */
static u8 gc_pal = 0;
typedef struct tagcamera typedef struct tagcamera
{ {
Vector pos; Vector pos;
@ -308,31 +308,6 @@ static camera cam = {
{0.0F, 0.0F, 0.0F} {0.0F, 0.0F, 0.0F}
}; };
/* Rendering Initialization */
static void draw_init(void)
{
/* Clear all Vertex params */
GX_ClearVtxDesc();
/* Set Position Params (quad aspect ratio) */
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0);
GX_SetVtxDesc(GX_VA_POS, GX_INDEX8);
GX_SetArray(GX_VA_POS, square, 3 * sizeof (s16));
/* Set Tex Coord Params */
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT);
GX_SetTevOp(GX_TEVSTAGE0, GX_REPLACE);
GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLORNULL);
GX_SetNumTexGens(1);
GX_SetNumChans(0);
/* Set Modelview */
Mtx view;
memset (&view, 0, sizeof (Mtx));
guLookAt(view, &cam.pos, &cam.up, &cam.view);
GX_LoadPosMtxImm(view, GX_PNMTX0);
}
/* Vertex Rendering */ /* Vertex Rendering */
static inline void draw_vert(u8 pos, f32 s, f32 t) static inline void draw_vert(u8 pos, f32 s, f32 t)
@ -352,49 +327,85 @@ static inline void draw_square(void)
GX_End (); GX_End ();
} }
/* Initialize GX */ /* Initialize GX renderer */
static void gxStart(void) static void gxStart(void)
{ {
Mtx p;
GXColor gxbackground = {0, 0, 0, 0xff};
/*** Clear out FIFO area ***/ /*** Clear out FIFO area ***/
memset(&gp_fifo, 0, DEFAULT_FIFO_SIZE); memset(&gp_fifo, 0, DEFAULT_FIFO_SIZE);
/*** GX default ***/ /*** GX default ***/
GX_Init(&gp_fifo, DEFAULT_FIFO_SIZE); GX_Init(&gp_fifo, DEFAULT_FIFO_SIZE);
GX_SetCopyClear(gxbackground, 0x00ffffff);
GX_SetViewport(0.0F, 0.0F, vmode->fbWidth, vmode->efbHeight, 0.0F, 1.0F);
GX_SetScissor(0, 0, vmode->fbWidth, vmode->efbHeight);
f32 yScale = GX_GetYScaleFactor(vmode->efbHeight, vmode->xfbHeight);
u16 xfbHeight = GX_SetDispCopyYScale(yScale);
GX_SetDispCopySrc(0, 0, vmode->fbWidth, vmode->efbHeight);
GX_SetDispCopyDst(vmode->fbWidth, xfbHeight);
GX_SetCopyFilter(vmode->aa, vmode->sample_pattern, GX_TRUE, vmode->vfilter);
GX_SetFieldMode(vmode->field_rendering, ((vmode->viHeight == 2 * vmode->xfbHeight) ? GX_ENABLE : GX_DISABLE));
GX_SetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR); GX_SetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR);
GX_SetCullMode(GX_CULL_NONE); GX_SetCullMode(GX_CULL_NONE);
GX_SetDispCopyGamma(GX_GM_1_0); GX_SetDispCopyGamma(GX_GM_1_0);
GX_SetBlendMode(GX_BM_BLEND,GX_BL_SRCALPHA,GX_BL_INVSRCALPHA,GX_LO_CLEAR);
GX_SetZMode(GX_FALSE, GX_ALWAYS, GX_TRUE); GX_SetZMode(GX_FALSE, GX_ALWAYS, GX_TRUE);
GX_SetColorUpdate(GX_TRUE); GX_SetColorUpdate(GX_TRUE);
guOrtho(p, vmode->efbHeight/2, -(vmode->efbHeight/2), -(vmode->fbWidth/2), vmode->fbWidth/2, 100, 1000); GX_SetTevOp(GX_TEVSTAGE0, GX_REPLACE);
GX_LoadProjectionMtx(p, GX_ORTHOGRAPHIC); GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLORNULL);
GX_SetNumTexGens(1);
GX_SetNumChans(0);
/*** Reset XFB ***/ /* Modelview */
GX_CopyDisp(xfb[whichfb ^ 1], GX_TRUE); Mtx view;
memset (&view, 0, sizeof (Mtx));
guLookAt(view, &cam.pos, &cam.up, &cam.view);
GX_LoadPosMtxImm(view, GX_PNMTX0);
GX_Flush(); GX_Flush();
/*** Initialize texture data ***/ /*** Initialize texture data ***/
texturemem = memalign(32, TEX_SIZE); texturemem = memalign(32, TEX_SIZE);
memset (texturemem, 0, TEX_SIZE); memset (texturemem, 0, TEX_SIZE);
}
/*** Initialize renderer */ /* Reset GX vertex attributes */
draw_init(); static void gxResetVtx(bool isMenu)
{
GX_ClearVtxDesc();
/* Set Position Params (quad aspect ratio) */
if (isMenu)
{
/* menu uses direct position */
GX_SetBlendMode(GX_BM_BLEND,GX_BL_SRCALPHA,GX_BL_INVSRCALPHA,GX_LO_CLEAR);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_S16, 0);
GX_SetVtxDesc(GX_VA_POS, GX_DIRECT);
}
else
{
/* emulation uses an indexed array for easy control on aspect ratio */
GX_SetBlendMode(GX_BM_NONE,GX_BL_SRCALPHA,GX_BL_INVSRCALPHA,GX_LO_CLEAR);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0);
GX_SetVtxDesc(GX_VA_POS, GX_INDEX8);
GX_SetArray(GX_VA_POS, square, 3 * sizeof (s16));
}
/* Set Tex Coord Params */
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT);
GX_Flush();
}
/* Reset GX 2D rendering */
static void gxResetView(GXRModeObj *tvmode)
{
Mtx44 p;
f32 yScale = GX_GetYScaleFactor(tvmode->efbHeight, tvmode->xfbHeight);
u16 xfbHeight = GX_SetDispCopyYScale(yScale);
GX_SetCopyClear((GXColor)BLACK,0x00ffffff);
GX_SetViewport(0.0F, 0.0F, tvmode->fbWidth, tvmode->efbHeight, 0.0F, 1.0F);
GX_SetScissor(0, 0, tvmode->fbWidth, tvmode->efbHeight);
GX_SetDispCopySrc(0, 0, tvmode->fbWidth, tvmode->efbHeight);
GX_SetDispCopyDst(tvmode->fbWidth, xfbHeight);
GX_SetCopyFilter(tvmode->aa, tvmode->sample_pattern, GX_TRUE, tvmode->vfilter);
GX_SetFieldMode(tvmode->field_rendering, ((tvmode->viHeight == 2 * tvmode->xfbHeight) ? GX_ENABLE : GX_DISABLE));
guOrtho(p, tvmode->efbHeight/2, -(tvmode->efbHeight/2), -(tvmode->fbWidth/2), tvmode->fbWidth/2, 100, 1000);
GX_LoadProjectionMtx(p, GX_ORTHOGRAPHIC);
} }
/* Reset GX/VI scaler */ /* Reset GX/VI scaler */
static void gxScale(u32 width, u32 height) static void gxResetScale(u32 width, u32 height)
{ {
int temp = 0; int temp = 0;
int xscale, yscale, xshift, yshift; int xscale, yscale, xshift, yshift;
@ -497,38 +508,45 @@ static void gxScale(u32 width, u32 height)
GX_InvVtxCache(); GX_InvVtxCache();
} }
static void xfb_swap(u32 cnt)
static void VSyncCallback(u32 cnt)
{ {
VIDEO_SetNextFramebuffer (xfb[whichfb]); frameticker++;
VIDEO_Flush ();
whichfb ^= 1;
} }
/* Restore Menu Video mode */ /* Restore Menu Video mode */
void ogc_video__stop(void) void ogc_video__stop(void)
{ {
VIDEO_WaitVSync();
VIDEO_Configure(vmode); VIDEO_Configure(vmode);
VIDEO_ClearFrameBuffer(vmode, xfb[0], COLOR_BLACK); VIDEO_ClearFrameBuffer(vmode, xfb[0], COLOR_BLACK);
VIDEO_ClearFrameBuffer(vmode, xfb[1], COLOR_BLACK); VIDEO_ClearFrameBuffer(vmode, xfb[1], COLOR_BLACK);
VIDEO_Flush();
VIDEO_WaitVSync();
VIDEO_WaitVSync();
}
/* Update Video settings */
void ogc_video__start()
{
/* clear screen */
VIDEO_ClearFrameBuffer(vmode, xfb[0], COLOR_BLACK);
VIDEO_ClearFrameBuffer(vmode, xfb[1], COLOR_BLACK);
VIDEO_SetPreRetraceCallback(NULL); VIDEO_SetPreRetraceCallback(NULL);
VIDEO_Flush(); VIDEO_Flush();
VIDEO_WaitVSync(); VIDEO_WaitVSync();
VIDEO_WaitVSync();
/* reset GX */
gxResetVtx(GX_TRUE);
gxResetView(vmode);
}
/* Update Video settings */
void ogc_video__start()
{
/* 50Hz/60Hz mode */ /* 50Hz/60Hz mode */
if ((config.tv_mode == 1) || ((config.tv_mode == 2) && vdp_pal)) gc_pal = 1; if ((config.tv_mode == 1) || ((config.tv_mode == 2) && vdp_pal)) gc_pal = 1;
else gc_pal = 0; else gc_pal = 0;
/* Video Interrupt synchronization */
if (!gc_pal && !vdp_pal) VIDEO_SetPreRetraceCallback(VSyncCallback);
/* clear screen */
VIDEO_ClearFrameBuffer(vmode, xfb[0], COLOR_BLACK);
VIDEO_ClearFrameBuffer(vmode, xfb[1], COLOR_BLACK);
VIDEO_Flush();
VIDEO_WaitVSync();
/* interlaced/progressive mode */ /* interlaced/progressive mode */
if (config.render == 2) if (config.render == 2)
{ {
@ -566,6 +584,10 @@ void ogc_video__start()
/* apply changes on next video update */ /* apply changes on next video update */
bitmap.viewport.changed = 1; bitmap.viewport.changed = 1;
/* reset GX */
gxResetVtx(GX_FALSE);
} }
/* GX render update */ /* GX render update */
@ -606,40 +628,19 @@ void ogc_video__update()
else rmode = tvmodes[gc_pal*3 + interlaced]; else rmode = tvmodes[gc_pal*3 + interlaced];
/* reset aspect ratio */ /* reset aspect ratio */
gxScale(vwidth,vheight); gxResetScale(vwidth,vheight);
/* configure GX */ /* reset GX */
GX_SetViewport(0.0F, 0.0F, rmode->fbWidth, rmode->efbHeight, 0.0F, 1.0F); gxResetView(rmode);
GX_SetScissor(0, 0, rmode->fbWidth, rmode->efbHeight);
f32 yScale = GX_GetYScaleFactor(rmode->efbHeight, rmode->xfbHeight);
u16 xfbHeight = GX_SetDispCopyYScale(yScale);
GX_SetDispCopySrc(0, 0, rmode->fbWidth, rmode->efbHeight);
GX_SetDispCopyDst(rmode->fbWidth, xfbHeight);
GX_SetCopyFilter(rmode->aa, rmode->sample_pattern, config.render ? GX_TRUE : GX_FALSE, rmode->vfilter);
GX_SetFieldMode(rmode->field_rendering, ((rmode->viHeight == 2 * rmode->xfbHeight) ? GX_ENABLE : GX_DISABLE));
GX_SetPixelFmt(rmode->aa ? GX_PF_RGB565_Z16 : GX_PF_RGB8_Z24, GX_ZC_LINEAR);
Mtx p;
guOrtho(p, rmode->efbHeight/2, -(rmode->efbHeight/2), -(rmode->fbWidth/2), rmode->fbWidth/2, 100, 1000);
GX_LoadProjectionMtx(p, GX_ORTHOGRAPHIC);
GX_Flush();
/* configure VI */ /* configure VI */
whichfb = odd_frame;
VIDEO_Configure(rmode); VIDEO_Configure(rmode);
VIDEO_SetNextFramebuffer(xfb[whichfb]);
VIDEO_Flush(); VIDEO_Flush();
VIDEO_WaitVSync(); VIDEO_WaitVSync();
if (rmode->viTVMode & VI_NON_INTERLACE) VIDEO_WaitVSync(); if (rmode->viTVMode & VI_NON_INTERLACE) VIDEO_WaitVSync();
else while (VIDEO_GetNextField() != odd_frame) VIDEO_WaitVSync(); else while (VIDEO_GetNextField() != odd_frame) VIDEO_WaitVSync();
/* resynchronize interlaced field */ if (frameticker > 1) frameticker = 1;
if (rmode->field_rendering)
{
whichfb = odd_frame;
VIDEO_SetPreRetraceCallback(xfb_swap);
VIDEO_Flush();
VIDEO_WaitVSync();
}
} }
/* texture is now directly mapped by the line renderer */ /* texture is now directly mapped by the line renderer */
@ -652,25 +653,10 @@ void ogc_video__update()
draw_square(); draw_square();
GX_DrawDone(); GX_DrawDone();
/* in SF interlaced modes, swap is done just before VSYNC */ /* swap XFB */
/* this ensures VSYNC does not miss any fields */ whichfb ^= 1;
if (rmode->field_rendering) VIDEO_SetNextFramebuffer(xfb[whichfb]);
{ VIDEO_Flush();
/* if we are out of sync, it's better not to draw this one */
if (odd_frame == whichfb)
{
/* resynchronize fields */
odd_frame ^= 1;
return;
}
}
else
{
/* swap XFB */
whichfb ^= 1;
VIDEO_SetNextFramebuffer(xfb[whichfb]);
VIDEO_Flush();
}
/* copy EFB to XFB */ /* copy EFB to XFB */
GX_CopyDisp(xfb[whichfb], GX_TRUE); GX_CopyDisp(xfb[whichfb], GX_TRUE);
@ -779,10 +765,13 @@ void ogc_video__init(void)
VIDEO_WaitVSync(); VIDEO_WaitVSync();
VIDEO_WaitVSync(); VIDEO_WaitVSync();
/* Initialize GX */
gxStart();
gxResetVtx(GX_TRUE);
gxResetView(vmode);
/* Initialize GUI */ /* Initialize GUI */
unpackBackdrop(); unpackBackdrop();
init_font(); init_font();
/* Initialize GX */
gxStart();
} }

View File

@ -28,6 +28,7 @@ extern unsigned int *xfb[2];
extern int whichfb; extern int whichfb;
extern GXRModeObj *vmode; extern GXRModeObj *vmode;
extern u8 *texturemem; extern u8 *texturemem;
extern u8 gc_pal;
extern void ogc_video__init(void); extern void ogc_video__init(void);
extern void ogc_video__start(void); extern void ogc_video__start(void);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 347 B

After

Width:  |  Height:  |  Size: 335 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 268 B

After

Width:  |  Height:  |  Size: 233 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

View File

@ -1717,12 +1717,12 @@ static void OPNWriteReg(int r, int v)
void YM2612UpdateOne(int **buffer, int length) void YM2612UpdateOne(int **buffer, int length)
{ {
int i; int i;
int *bufL,*bufR;
int lt,rt; int lt,rt;
/* set buffer */ /* set buffers */
bufL = buffer[0]; int *bufL = buffer[0];
bufR = buffer[1]; int *bufR = buffer[1];
float *bufSRC = snd.fm.src_buffer ? (snd.fm.src_buffer + (2*snd.fm.lastStage)) : 0;
/* refresh PG and EG */ /* refresh PG and EG */
refresh_fc_eg_chan(&ym2612.CH[0]); refresh_fc_eg_chan(&ym2612.CH[0]);
@ -1804,15 +1804,15 @@ void YM2612UpdateOne(int **buffer, int length)
Limit(rt,MAXOUT,MINOUT); Limit(rt,MAXOUT,MINOUT);
/* buffering */ /* buffering */
if (src_buffer) if (bufSRC)
{ {
src_buffer[i*2] = (float) lt / (8.0 * 0x10000000); *bufSRC++ = ((float) (lt)) / (8.0 * 0x10000000);
src_buffer[i*2 + 1] = (float) rt / (8.0 * 0x10000000); *bufSRC++ = ((float) (rt)) / (8.0 * 0x10000000);
} }
else else
{ {
bufL[i] = lt; *bufL++ = lt;
bufR[i] = rt; *bufR++ = rt;
} }
/* timer A control */ /* timer A control */

View File

@ -23,9 +23,6 @@
#include "shared.h" #include "shared.h"
#define CLOCK_NTSC 53693175
#define CLOCK_PAL 53203424
/* generic functions */ /* generic functions */
int (*_YM2612_Write)(unsigned char adr, unsigned char data); int (*_YM2612_Write)(unsigned char adr, unsigned char data);
int (*_YM2612_Read)(void); int (*_YM2612_Read)(void);
@ -35,23 +32,20 @@ int (*_YM2612_Reset)(void);
/* cycle-accurate samples */ /* cycle-accurate samples */
static int m68cycles_per_sample[2]; static int m68cycles_per_sample[2];
/* pointer to current SRC buffer */
float *src_buffer;
/* YM2612 register arrays */ /* YM2612 register arrays */
int fm_reg[2][0x100]; int fm_reg[2][0x100];
/* return the number of samples that should have been rendered so far */ /* return the number of samples that should have been rendered so far */
static inline uint32 fm_sample_cnt(uint8 is_z80) static inline uint32 fm_sample_cnt(uint8 is_z80)
{ {
if (is_z80) return ((count_z80 + current_z80 - z80_ICount) * 15) / (7 * m68cycles_per_sample[0]); if (is_z80) return ((count_z80 + current_z80 - z80_ICount) * 15) / (m68cycles_per_sample[0] * 7);
else return count_m68k / m68cycles_per_sample[0]; else return (count_m68k / m68cycles_per_sample[0]);
} }
static inline uint32 psg_sample_cnt(uint8 is_z80) static inline uint32 psg_sample_cnt(uint8 is_z80)
{ {
if (is_z80) return ((count_z80 + current_z80 - z80_ICount) * 15) / (7 * m68cycles_per_sample[1]); if (is_z80) return ((count_z80 + current_z80 - z80_ICount) * 15) / (m68cycles_per_sample[1] * 7);
else return count_m68k / m68cycles_per_sample[1]; else return (count_m68k / m68cycles_per_sample[1]);
} }
/* update FM samples */ /* update FM samples */
@ -62,12 +56,6 @@ static inline void fm_update()
int *tempBuffer[2]; int *tempBuffer[2];
tempBuffer[0] = snd.fm.buffer[0] + snd.fm.lastStage; tempBuffer[0] = snd.fm.buffer[0] + snd.fm.lastStage;
tempBuffer[1] = snd.fm.buffer[1] + snd.fm.lastStage; tempBuffer[1] = snd.fm.buffer[1] + snd.fm.lastStage;
if (src_buffer)
{
src_buffer = src_data.data_in + (snd.fm.lastStage * 2);
}
_YM2612_Update(tempBuffer, snd.fm.curStage - snd.fm.lastStage); _YM2612_Update(tempBuffer, snd.fm.curStage - snd.fm.lastStage);
snd.fm.lastStage = snd.fm.curStage; snd.fm.lastStage = snd.fm.curStage;
} }
@ -89,19 +77,14 @@ void sound_init(int rate)
double vclk = (vdp_pal ? (double)CLOCK_PAL : (double)CLOCK_NTSC) / 7.0; /* 68000 and YM2612 clock */ double vclk = (vdp_pal ? (double)CLOCK_PAL : (double)CLOCK_NTSC) / 7.0; /* 68000 and YM2612 clock */
double zclk = (vdp_pal ? (double)CLOCK_PAL : (double)CLOCK_NTSC) / 15.0; /* Z80 and SN76489 clock */ double zclk = (vdp_pal ? (double)CLOCK_PAL : (double)CLOCK_NTSC) / 15.0; /* Z80 and SN76489 clock */
/* cycle-accurate samples */ /* cycle-accurate FM & PSG samples */
m68cycles_per_sample[0] = (m68cycles_per_line * lines_per_frame * vdp_rate) / rate; m68cycles_per_sample[0] = (int)(((double)m68cycles_per_line * (double)lines_per_frame * (double)vdp_rate / (double)rate) + 0.5);
m68cycles_per_sample[1] = (m68cycles_per_line * lines_per_frame * vdp_rate) / rate; m68cycles_per_sample[1] = m68cycles_per_sample[0];
/* YM2612 is emulated at the original frequency */ /* YM2612 is emulated at original frequency (VLCK/144) */
src_buffer = 0; if (config.hq_fm && !config.fm_core)
if (src_data.data_in)
{ {
/* YM2612 original frequency is VCLK/144 */
m68cycles_per_sample[0] = 144; m68cycles_per_sample[0] = 144;
/* Initialize SRC buffer */
src_buffer = src_data.data_in;
} }
/* initialize sound chips */ /* initialize sound chips */
@ -126,46 +109,16 @@ void sound_init(int rate)
} }
} }
void sound_update(void) void sound_update(int fm_len, int psg_len)
{ {
/* finalize sound buffers */ /* finalize sound buffers */
snd.fm.curStage = (src_data.data_in) ? src_data.input_frames : snd.buffer_size; snd.fm.curStage = fm_len;
snd.psg.curStage = snd.buffer_size; snd.psg.curStage = psg_len;
/* update last samples (if needed) */ /* update last samples (if needed) */
fm_update(); fm_update();
psg_update(); psg_update();
/* Resampling */
if (src_data.data_in)
{
/* samplerate conversion */
src_simple (&src_data, (config.hq_fm&1) ? SRC_LINEAR : SRC_SINC_FASTEST, 2);
/* this is basically libsamplerate "src_float_to_int_array" function, adapted to interlace samples */
double scaled_value;
int len = snd.buffer_size;
while (len)
{
len -- ;
scaled_value = src_data.data_out[len*2] * (8.0 * 0x10000000);
if (scaled_value >= (1.0 * 0x7FFFFFFF))
snd.fm.buffer[0][len] = 0x7fffffff;
else if (scaled_value <= (-8.0 * 0x10000000))
snd.fm.buffer[0][len] = -1 - 0x7fffffff;
else
snd.fm.buffer[0][len] = lrint(scaled_value);
scaled_value = src_data.data_out[len*2+1] * (8.0 * 0x10000000);
if (scaled_value >= (1.0 * 0x7FFFFFFF))
snd.fm.buffer[1][len] = 0x7fffffff;
else if (scaled_value <= (-8.0 * 0x10000000))
snd.fm.buffer[1][len] = -1 - 0x7fffffff;
else
snd.fm.buffer[1][len] = lrint(scaled_value);
}
}
/* reset samples count */ /* reset samples count */
snd.fm.curStage = 0; snd.fm.curStage = 0;
snd.fm.lastStage = 0; snd.fm.lastStage = 0;

View File

@ -26,13 +26,10 @@
/* Global variables */ /* Global variables */
extern int fm_reg[2][0x100]; extern int fm_reg[2][0x100];
extern double fm_timera_tab[0x400];
extern double fm_timerb_tab[0x100];
extern float *src_buffer;
/* Function prototypes */ /* Function prototypes */
extern void sound_init(int rate); extern void sound_init(int rate);
extern void sound_update(void); extern void sound_update(int fm_len, int psg_len);
extern void fm_restore(void); extern void fm_restore(void);
extern void fm_write(unsigned int cpu, unsigned int address, unsigned int data); extern void fm_write(unsigned int cpu, unsigned int address, unsigned int data);
extern unsigned int fm_read(unsigned int cpu, unsigned int address); extern unsigned int fm_read(unsigned int cpu, unsigned int address);

View File

@ -22,6 +22,7 @@
****************************************************************************************/ ****************************************************************************************/
#include "shared.h" #include "shared.h"
#include "samplerate.h"
#define SND_SIZE (snd.buffer_size * sizeof(int16)) #define SND_SIZE (snd.buffer_size * sizeof(int16))
@ -35,9 +36,195 @@ uint32 count_z80;
uint32 line_z80; uint32 line_z80;
int32 current_z80; int32 current_z80;
uint8 system_hw; uint8 system_hw;
SRC_DATA src_data;
static inline void audio_update (void); /* SRC */
static SRC_DATA src_data;
static int ll, rr;
/****************************************************************
* AUDIO stream update
****************************************************************/
void audio_update (int size)
{
int i;
int l, r;
int psg_preamp = config.psg_preamp;
int fm_preamp = config.fm_preamp;
int boost = config.boost;
int filter = config.filter;
#ifndef DOS
int16 *sb = (int16 *) soundbuffer[mixbuffer];
#endif
int *fm_l = snd.fm.buffer[0];
int *fm_r = snd.fm.buffer[1];
int16 *psg = snd.psg.buffer;
float *src = src_data.data_out;
double scaled_value;
/* resampling */
if (src)
{
src_data.output_frames = size;
src_data.input_frames = (int)((double)size / src_data.src_ratio + 0.5);
sound_update(src_data.input_frames,size);
src_simple(&src_data,(config.hq_fm&1) ? SRC_LINEAR : SRC_SINC_FASTEST, 2);
}
else sound_update(size,size);
/* mix samples */
for (i = 0; i < size; i ++)
{
/* PSG samples (mono) */
l = r = (((int)*psg++) * psg_preamp)/100;
/* FM samples (stereo) */
if (src)
{
/* left channel */
scaled_value = (*src++) * (8.0 * 0x10000000);
if (scaled_value >= (1.0 * 0x7FFFFFFF))
l = 0x7fffffff;
else if (scaled_value <= (-8.0 * 0x10000000))
l = -1 - 0x7fffffff;
else
l += (lrint(scaled_value) * fm_preamp)/100;
/* right channel */
scaled_value = (*src++) * (8.0 * 0x10000000);
if (scaled_value >= (1.0 * 0x7FFFFFFF))
r = 0x7fffffff;
else if (scaled_value <= (-8.0 * 0x10000000))
r = -1 - 0x7fffffff;
else
r += (lrint(scaled_value) * fm_preamp)/100;
}
else
{
l += (*fm_l * fm_preamp)/100;
r += (*fm_r * fm_preamp)/100;
*fm_l++ = 0;
*fm_r++ = 0;
}
/* single-pole low-pass filter (6 dB/octave) */
if (filter)
{
l = (ll + l) >> 1;
r = (rr + r) >> 1;
ll = l;
rr = r;
}
/* boost volume if asked*/
l = l * boost;
r = r * boost;
/* clipping */
if (l > 32767) l = 32767;
else if (l < -32768) l = -32768;
if (r > 32767) r = 32767;
else if (r < -32768) r = -32768;
/* update sound buffer */
#ifdef DOS
snd.buffer[0][i] = l;
snd.buffer[1][i] = r;
#elif LSB_FIRST
*sb++ = l;
*sb++ = r;
#else
*sb++ = r;
*sb++ = l;
#endif
}
}
/****************************************************************
* AUDIO System initialization
****************************************************************/
int audio_init (int rate)
{
/* Shutdown first */
audio_shutdown();
/* Clear the sound data context */
memset(&snd, 0, sizeof (snd));
memset(&src_data, 0, sizeof(src_data));
/* Make sure the requested sample rate is valid */
if (!rate || ((rate < 8000) | (rate > 48000))) return (-1);
snd.sample_rate = rate;
/* Calculate the sound buffer size (for one frame) */
snd.buffer_size = (rate / vdp_rate) + 8;
#ifdef DOS
/* output buffers */
snd.buffer[0] = (int16 *) malloc(SND_SIZE);
snd.buffer[1] = (int16 *) malloc(SND_SIZE);
if (!snd.buffer[0] || !snd.buffer[1]) return (-1);
#endif
/* SRC */
if (config.hq_fm && !config.fm_core)
{
/* SRC ratio (YM2612 original samplerate is VCLK/144) */
src_data.src_ratio = ((double)rate * 144.0) / ((double) vdp_rate * (double)m68cycles_per_line * (double)lines_per_frame);
/* max. output */
src_data.output_frames = snd.buffer_size;
/* max. input */
snd.fm.size = (int)((double)src_data.output_frames / src_data.src_ratio + 0.5);
src_data.input_frames = snd.fm.size;
/* SRC buffers */
src_data.data_in = (float *) malloc(snd.fm.size*2*sizeof(float));
src_data.data_out = (float *) malloc(snd.buffer_size*2*sizeof(float));
if (!src_data.data_in || !src_data.data_out) return (-1);
snd.fm.src_buffer = src_data.data_in;
}
else
{
/* YM2612 stream buffers */
snd.fm.size = snd.buffer_size;
snd.fm.buffer[0] = (int *)malloc (snd.fm.size * sizeof(int));
snd.fm.buffer[1] = (int *)malloc (snd.fm.size * sizeof(int));
if (!snd.fm.buffer[0] || !snd.fm.buffer[1]) return (-1);
}
/* SN76489 stream buffers */
snd.psg.buffer = (int16 *)malloc (SND_SIZE);
if (!snd.psg.buffer) return (-1);
/* Set audio enable flag */
snd.enabled = 1;
/* Initialize Sound Chips emulation */
sound_init(rate);
return (0);
}
/****************************************************************
* AUDIO System shutdown
****************************************************************/
void audio_shutdown(void)
{
/* free sound buffers */
if (snd.buffer[0]) free(snd.buffer[0]);
if (snd.buffer[1]) free(snd.buffer[1]);
if (snd.fm.buffer[0]) free(snd.fm.buffer[0]);
if (snd.fm.buffer[1]) free(snd.fm.buffer[1]);
if (snd.psg.buffer) free(snd.psg.buffer);
/* SRC*/
if (src_data.data_in) free(src_data.data_in);
if (src_data.data_out) free(src_data.data_out);
}
/**************************************************************** /****************************************************************
* Virtual Genesis initialization * Virtual Genesis initialization
@ -66,13 +253,9 @@ void system_reset (void)
SN76489_Reset(0); SN76489_Reset(0);
/* Sound Buffers */ /* Sound Buffers */
if (snd.psg.buffer) memset(snd.psg.buffer, 0, SND_SIZE); if (snd.psg.buffer) memset (snd.psg.buffer, 0, SND_SIZE);
if (snd.fm.buffer[0]) memset(snd.fm.buffer[0], 0, SND_SIZE*2); if (snd.fm.buffer[0]) memset (snd.fm.buffer[0], 0, snd.fm.size * sizeof(int));
if (snd.fm.buffer[1]) memset(snd.fm.buffer[1], 0, SND_SIZE*2); if (snd.fm.buffer[1]) memset (snd.fm.buffer[1], 0, snd.fm.size * sizeof(int));
/* SRC */
if (src_data.data_in) memset(src_data.data_in, 0, src_data.input_frames * 2 * sizeof(float));
if (src_data.data_out) memset(src_data.data_out,0, src_data.output_frames * 2 * sizeof(float));
} }
/**************************************************************** /****************************************************************
@ -252,137 +435,5 @@ int system_frame (int do_skip)
if (svp) ssp1601_run(SVP_cycles); if (svp) ssp1601_run(SVP_cycles);
} }
audio_update ();
return gen_running; return gen_running;
} }
/****************************************************************
* Audio System
****************************************************************/
int audio_init (int rate)
{
/* Shutdown first */
audio_shutdown();
/* Clear the sound data context */
memset (&snd, 0, sizeof (snd));
/* Make sure the requested sample rate is valid */
if (!rate || ((rate < 8000) | (rate > 48000))) return (-1);
snd.sample_rate = rate;
/* Calculate the sound buffer size (for one frame) */
snd.buffer_size = (rate / vdp_rate);
#ifdef DOS
/* output buffers */
snd.buffer[0] = (int16 *) malloc(SND_SIZE);
snd.buffer[1] = (int16 *) malloc(SND_SIZE);
if (!snd.buffer[0] || !snd.buffer[1]) return (-1);
#endif
/* YM2612 stream buffers */
snd.fm.buffer[0] = (int *)malloc (SND_SIZE*2);
snd.fm.buffer[1] = (int *)malloc (SND_SIZE*2);
if (!snd.fm.buffer[0] || !snd.fm.buffer[1]) return (-1);
/* YM2612 resampling */
src_data.data_in = NULL;
src_data.data_out = NULL;
if (config.hq_fm && !config.fm_core)
{
/* initialize SRC */
src_data.input_frames = (int)(((double)m68cycles_per_line * (double)lines_per_frame / 144.0) + 0.5);
src_data.output_frames = snd.buffer_size;
src_data.data_in = (float *)malloc(src_data.input_frames * 2 * sizeof(float));
src_data.data_out = (float *)malloc(src_data.output_frames * 2 * sizeof(float));
src_data.src_ratio = (double)src_data.output_frames / (double)src_data.input_frames;
if (!src_data.data_in || !src_data.data_out) return (-1);
}
/* SN76489 stream buffers */
snd.psg.buffer = (int16 *)malloc (SND_SIZE);
if (!snd.psg.buffer) return (-1);
/* Set audio enable flag */
snd.enabled = 1;
/* Initialize Sound Chips emulation */
sound_init(rate);
return (0);
}
void audio_shutdown(void)
{
/* free sound buffers */
if (snd.buffer[0]) free(snd.buffer[0]);
if (snd.buffer[1]) free(snd.buffer[1]);
if (snd.fm.buffer[0]) free(snd.fm.buffer[0]);
if (snd.fm.buffer[1]) free(snd.fm.buffer[1]);
if (snd.psg.buffer) free(snd.psg.buffer);
if (src_data.data_in) free(src_data.data_in);
if (src_data.data_out) free(src_data.data_out);
}
static int ll, rr;
static inline void audio_update (void)
{
int i;
int l, r;
int psg_preamp = config.psg_preamp;
int fm_preamp = config.fm_preamp;
int boost = config.boost;
int filter = config.filter;
#ifndef DOS
int16 *sb = (int16 *) soundbuffer[mixbuffer];
#endif
/* get remaining samples */
sound_update();
/* mix samples */
for (i = 0; i < snd.buffer_size; i ++)
{
l = r = (snd.psg.buffer[i] * psg_preamp) / 100;
l += ((snd.fm.buffer[0][i] * fm_preamp) / 100);
r += ((snd.fm.buffer[1][i] * fm_preamp) / 100);
snd.fm.buffer[0][i] = 0;
snd.fm.buffer[1][i] = 0;
snd.psg.buffer[i] = 0;
/* single-pole low-pass filter (6 dB/octave) */
if (filter)
{
l = (ll + l) >> 1;
r = (rr + r) >> 1;
ll = l;
rr = r;
}
/* boost volume if asked*/
l = l * boost;
r = r * boost;
/* clipping */
if (l > 32767) l = 32767;
else if (l < -32768) l = -32768;
if (r > 32767) r = 32767;
else if (r < -32768) r = -32768;
/* update sound buffer */
#ifdef DOS
snd.buffer[0][i] = l;
snd.buffer[1][i] = r;
#elif LSB_FIRST
*sb++ = l;
*sb++ = r;
#else
*sb++ = r;
*sb++ = l;
#endif
}
}

View File

@ -24,8 +24,6 @@
#ifndef _SYSTEM_H_ #ifndef _SYSTEM_H_
#define _SYSTEM_H_ #define _SYSTEM_H_
#include "samplerate.h"
#define SYSTEM_GENESIS 0 #define SYSTEM_GENESIS 0
#define SYSTEM_MEGADRIVE 1 #define SYSTEM_MEGADRIVE 1
#define SYSTEM_PICO 2 #define SYSTEM_PICO 2
@ -34,6 +32,8 @@
#define z80cycles_per_line 228 #define z80cycles_per_line 228
#define m68cycles_per_line 488 #define m68cycles_per_line 488
#define CLOCK_NTSC 53693175
#define CLOCK_PAL 53203424
typedef struct typedef struct
{ {
@ -65,9 +65,11 @@ typedef struct
int16 *buffer[2]; /* Signed 16-bit stereo sound data */ int16 *buffer[2]; /* Signed 16-bit stereo sound data */
struct struct
{ {
int size;
int curStage; int curStage;
int lastStage; int lastStage;
int *buffer[2]; int *buffer[2];
float *src_buffer;
} fm; } fm;
struct struct
{ {
@ -87,7 +89,6 @@ extern uint32 count_z80;
extern uint32 line_z80; extern uint32 line_z80;
extern int32 current_z80; extern int32 current_z80;
extern uint8 system_hw; extern uint8 system_hw;
extern SRC_DATA src_data;
/* Function prototypes */ /* Function prototypes */
extern void system_init (void); extern void system_init (void);
@ -96,6 +97,7 @@ extern void system_shutdown (void);
extern int system_frame(int skip); extern int system_frame(int skip);
extern int audio_init (int rate); extern int audio_init (int rate);
extern void audio_shutdown (void); extern void audio_shutdown (void);
extern void audio_update (int len);
#endif /* _SYSTEM_H_ */ #endif /* _SYSTEM_H_ */

View File

@ -600,6 +600,8 @@ void vdp_ctrl_w(unsigned int data)
H40: 20 accesses --> 366/20 = 18 cycles per access H40: 20 accesses --> 366/20 = 18 cycles per access
VRAM access are byte wide --> VRAM writes takes 2x CPU cycles VRAM access are byte wide --> VRAM writes takes 2x CPU cycles
Memory access requires some additional cyles, the following values
seems to work fine (see Chaos Engine/Soldier of Fortune)
*/ */
fifo_latency = (reg[12] & 1) ? 27 : 30; fifo_latency = (reg[12] & 1) ? 27 : 30;
if ((code & 0x0F) == 0x01) fifo_latency = fifo_latency * 2; if ((code & 0x0F) == 0x01) fifo_latency = fifo_latency * 2;