├── utils.h ├── README.md ├── Makefile ├── draw.h ├── main.c ├── draw.c └── font_data.c /utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Sergi Granell (xerpi) 3 | */ 4 | 5 | #ifndef UTILS_H 6 | #define UTILS_H 7 | 8 | #define align_mem(addr, align) (((addr) + ((align) - 1)) & ~((align) - 1)) 9 | #define lerp(value, from_max, to_max) ((((value*10) * (to_max*10))/(from_max*10))/10) 10 | #define abs(x) ((x) < 0 ? (-x) : (x)) 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## vitahelloworld 2 | Homebrew sample for the PSVita. 3 | 4 | ## Compiling 5 | Prerequisites: 6 | * arm gcc ([devkitARM r44] (http://sourceforge.net/projects/devkitpro/files/devkitARM/devkitARM_r44/) for example) 7 | * [psp2sdk] (https://github.com/173210/psp2sdk) 8 | 9 | Once all the prerequisites have been met, you can compile this homebrew by typing: 10 | ``` 11 | $ make 12 | ``` 13 | 14 | ## Credits 15 | Thanks to yifanlu for Rejuvenate and UVLoader :D 16 | Thanks to 173210 and everybody who contributed to psp2sdk. 17 | Thanks to Cirne and everybody who contributed to vita-toolchain. 18 | Also thanks to everybody who has helped me on #vitadev :P 19 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | TITLE_ID = XERP00001 2 | TARGET = vitahelloworld 3 | OBJS = main.o draw.o font_data.o 4 | 5 | LIBS = -lc -lSceDisplay_stub -lSceGxm_stub -lSceCtrl_stub -lSceTouch_stub 6 | 7 | PREFIX = arm-vita-eabi 8 | CC = $(PREFIX)-gcc 9 | CFLAGS = -Wl,-q -Wall -O3 10 | ASFLAGS = $(CFLAGS) 11 | 12 | all: $(TARGET).vpk 13 | 14 | %.vpk: eboot.bin 15 | vita-mksfoex -s TITLE_ID=$(TITLE_ID) "$(TARGET)" param.sfo 16 | vita-pack-vpk -s param.sfo -b eboot.bin $@ 17 | 18 | eboot.bin: $(TARGET).velf 19 | vita-make-fself $< $@ 20 | 21 | %.velf: %.elf 22 | vita-elf-create $< $@ 23 | 24 | $(TARGET).elf: $(OBJS) 25 | $(CC) $(CFLAGS) $^ $(LIBS) -o $@ 26 | 27 | clean: 28 | @rm -rf $(TARGET).vpk $(TARGET).velf $(TARGET).elf $(OBJS) \ 29 | eboot.bin param.sfo 30 | 31 | vpksend: $(TARGET).vpk 32 | curl -T $(TARGET).vpk ftp://$(PSVITAIP):1337/ux0:/ 33 | @echo "Sent." 34 | 35 | send: eboot.bin 36 | curl -T eboot.bin ftp://$(PSVITAIP):1337/ux0:/app/$(TITLE_ID)/ 37 | @echo "Sent." 38 | -------------------------------------------------------------------------------- /draw.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Sergi Granell (xerpi) 3 | */ 4 | 5 | #ifndef DRAW_H 6 | #define DRAW_H 7 | 8 | #include 9 | 10 | #define RGBA8(r, g, b, a) ((((a)&0xFF)<<24) | (((b)&0xFF)<<16) | (((g)&0xFF)<<8) | (((r)&0xFF)<<0)) 11 | 12 | #define SCREEN_W 960 13 | #define SCREEN_H 544 14 | 15 | #define RED RGBA8(255, 0, 0, 255) 16 | #define GREEN RGBA8(0, 255, 0, 255) 17 | #define BLUE RGBA8(0, 0, 255, 255) 18 | #define CYAN RGBA8(0, 255, 255, 255) 19 | #define LIME RGBA8(50, 205, 50, 255) 20 | #define PURP RGBA8(147, 112, 219, 255) 21 | #define WHITE RGBA8(255, 255, 255, 255) 22 | #define BLACK RGBA8(0, 0, 0, 255) 23 | 24 | void init_video(); 25 | void end_video(); 26 | void swap_buffers(); 27 | void clear_screen(); 28 | void draw_pixel(uint32_t x, uint32_t y, uint32_t color); 29 | void draw_rectangle(uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint32_t color); 30 | void draw_circle(uint32_t x, uint32_t y, uint32_t radius, uint32_t color); 31 | 32 | void font_draw_char(int x, int y, uint32_t color, char c); 33 | void font_draw_string(int x, int y, uint32_t color, const char *string); 34 | void font_draw_stringf(int x, int y, uint32_t color, const char *s, ...); 35 | 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Sergi Granell (xerpi) 3 | */ 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "utils.h" 14 | #include "draw.h" 15 | 16 | int main() 17 | { 18 | init_video(); 19 | 20 | /* Enable analog stick */ 21 | sceCtrlSetSamplingMode(SCE_CTRL_MODE_ANALOG); 22 | 23 | /* Enable front touchscreen */ 24 | sceTouchSetSamplingState(SCE_TOUCH_PORT_FRONT, 1); 25 | 26 | /* FPS counting */ 27 | SceUInt64 cur_micros = 0, delta_micros = 0, last_micros = 0; 28 | uint32_t frames = 0; 29 | float fps = 0.0f; 30 | 31 | /* Square variables */ 32 | int w = 60; 33 | int h = 60; 34 | int x = SCREEN_W/2 - w/2; 35 | int y = SCREEN_H/2 - h/2; 36 | int speed = 2; 37 | uint32_t color = RGBA8(255, 0, 0, 255); 38 | 39 | /* Input variables */ 40 | SceCtrlData pad; 41 | SceTouchData touch; 42 | signed char lx, ly, rx, ry; 43 | 44 | while (1) { 45 | clear_screen(); 46 | 47 | /* Read controls and touchscreen */ 48 | sceCtrlPeekBufferPositive(0, &pad, 1); 49 | sceTouchPeek(0, &touch, 1); 50 | 51 | if (pad.buttons & SCE_CTRL_START) { 52 | break; 53 | } 54 | 55 | font_draw_string(10, 10, RGBA8(0, 0, 255, 255), "PSVita sample by xerpi!"); 56 | font_draw_stringf(SCREEN_W - 160, 10, RGBA8(0, 255, 0, 255), "FPS: %.2f", fps); 57 | font_draw_stringf(10, 30, RGBA8(255, 0, 0, 255), 58 | "(%3d, %3d) size: (%d, %d) speed: %d\n", x, y, w, h, speed); 59 | 60 | /* Move the rectangle */ 61 | if (pad.buttons & SCE_CTRL_UP) { 62 | y -= speed; 63 | } else if (pad.buttons & SCE_CTRL_DOWN) { 64 | y += speed; 65 | } 66 | if (pad.buttons & SCE_CTRL_LEFT) { 67 | x -= speed; 68 | } else if (pad.buttons & SCE_CTRL_RIGHT) { 69 | x += speed; 70 | } 71 | 72 | if (pad.buttons & SCE_CTRL_LTRIGGER) { 73 | speed--; 74 | if (speed < 0) speed = 0; 75 | } else if (pad.buttons & SCE_CTRL_RTRIGGER) { 76 | speed++; 77 | if (speed > 100) speed = 100; 78 | } 79 | 80 | if (pad.buttons & SCE_CTRL_CROSS) { 81 | color = RGBA8(rand()%255, rand()%255, rand()%255, 255); 82 | } 83 | 84 | /* Update joystick values */ 85 | lx = (signed char)pad.lx - 128; 86 | ly = (signed char)pad.ly - 128; 87 | rx = (signed char)pad.rx - 128; 88 | ry = (signed char)pad.ry - 128; 89 | 90 | /* Move using the left yoystick */ 91 | if (abs(lx) > 50) { 92 | x += speed * lx/50.0f; 93 | } 94 | if (abs(ly) > 50) { 95 | y += speed * ly/50.0f; 96 | } 97 | 98 | /* Resize using the right yoystick */ 99 | if (abs(rx) > 50) { 100 | w += rx/15.0f; 101 | if (w < 5) { 102 | w = 5; 103 | } else if (w > SCREEN_W) { 104 | w = SCREEN_W; 105 | } 106 | } 107 | if (abs(ry) > 50) { 108 | h += ry/15.0f; 109 | if (h < 5) { 110 | h = 5; 111 | } if (h > SCREEN_H) { 112 | h = SCREEN_H; 113 | } 114 | } 115 | 116 | /* Move using the touchscreen! */ 117 | if (touch.reportNum > 0) { 118 | /* Front touchscreen: 1920x1088 */ 119 | x = lerp(touch.report[0].x, 1920, SCREEN_W) - w/2; 120 | y = lerp(touch.report[0].y, 1088, SCREEN_H) - h/2; 121 | } 122 | 123 | /* Check left and right collisions */ 124 | if (x < 0) { 125 | x = 0; 126 | } else if ((x + w) > SCREEN_W) { 127 | x = SCREEN_W - w; 128 | } 129 | 130 | /* Check top and bottom collisions */ 131 | if (y < 0) { 132 | y = 0; 133 | } else if ((y + h) > SCREEN_H) { 134 | y = SCREEN_H - h; 135 | } 136 | 137 | /* Draw the rectangle */ 138 | draw_rectangle(x, y, w, h, color); 139 | 140 | /* Draw a circle */ 141 | draw_circle(SCREEN_W / 2, SCREEN_H / 2, 50, RGBA8(0,0,255,255)); 142 | 143 | /* Calculate FPS */ 144 | cur_micros = sceKernelGetProcessTimeWide(); 145 | 146 | if (cur_micros >= (last_micros + 1000000)) { 147 | delta_micros = cur_micros - last_micros; 148 | last_micros = cur_micros; 149 | fps = (frames/(double)delta_micros)*1000000.0f; 150 | frames = 0; 151 | } 152 | 153 | swap_buffers(); 154 | sceDisplayWaitVblankStart(); 155 | frames++; 156 | } 157 | 158 | end_video(); 159 | sceKernelExitProcess(0); 160 | return 0; 161 | } 162 | -------------------------------------------------------------------------------- /draw.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Sergi Granell (xerpi) 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "draw.h" 12 | #include "utils.h" 13 | 14 | extern const unsigned char msx_font[]; 15 | 16 | static SceDisplayFrameBuf fb[2]; 17 | static SceUID fb_memuid[2]; 18 | static int cur_fb = 0; 19 | 20 | void *gpu_alloc(SceKernelMemBlockType type, unsigned int size, unsigned int attribs, SceUID *uid) 21 | { 22 | void *mem; 23 | 24 | if (type == SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW) { 25 | size = align_mem(size, 256*1024); 26 | } else { 27 | size = align_mem(size, 4*1024); 28 | } 29 | 30 | *uid = sceKernelAllocMemBlock("gpu_mem", type, size, NULL); 31 | 32 | if (sceKernelGetMemBlockBase(*uid, &mem) < 0) 33 | return NULL; 34 | 35 | if (sceGxmMapMemory(mem, size, attribs) < 0) 36 | return NULL; 37 | 38 | return mem; 39 | } 40 | 41 | void gpu_free(SceUID uid) 42 | { 43 | void *mem = NULL; 44 | if (sceKernelGetMemBlockBase(uid, &mem) < 0) 45 | return; 46 | sceGxmUnmapMemory(mem); 47 | sceKernelFreeMemBlock(uid); 48 | } 49 | 50 | void init_video() 51 | { 52 | int ret; 53 | 54 | SceGxmInitializeParams params; 55 | 56 | params.flags = 0x0; 57 | params.displayQueueMaxPendingCount = 0x2; //Double buffering 58 | params.displayQueueCallback = 0x0; 59 | params.displayQueueCallbackDataSize = 0x0; 60 | params.parameterBufferSize = (16 * 1024 * 1024); 61 | 62 | /* Initialize the GXM */ 63 | ret = sceGxmInitialize(¶ms); 64 | printf("sceGxmInitialize(): 0x%08X\n", ret); 65 | 66 | /* Setup framebuffers */ 67 | fb[0].size = sizeof(fb[0]); 68 | fb[0].pitch = SCREEN_W; 69 | fb[0].pixelformat = SCE_DISPLAY_PIXELFORMAT_A8B8G8R8; 70 | fb[0].width = SCREEN_W; 71 | fb[0].height = SCREEN_H; 72 | 73 | fb[1].size = sizeof(fb[1]); 74 | fb[1].pitch = SCREEN_W; 75 | fb[1].pixelformat = SCE_DISPLAY_PIXELFORMAT_A8B8G8R8; 76 | fb[1].width = SCREEN_W; 77 | fb[1].height = SCREEN_H; 78 | 79 | /* Allocate memory for the framebuffers */ 80 | fb[0].base = gpu_alloc(SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, 81 | SCREEN_W * SCREEN_H * 4, SCE_GXM_MEMORY_ATTRIB_RW, &fb_memuid[0]); 82 | 83 | if (fb[0].base == NULL) { 84 | printf("Could not allocate memory for fb[0]. %p", fb[0].base); 85 | return; 86 | } 87 | 88 | fb[1].base = gpu_alloc(SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, 89 | SCREEN_W * SCREEN_H * 4, SCE_GXM_MEMORY_ATTRIB_RW, &fb_memuid[1]); 90 | 91 | if (fb[1].base == NULL) { 92 | printf("Could not allocate memory for fb[1]. %p", fb[1].base); 93 | return; 94 | } 95 | 96 | /* Display the framebuffer 0 */ 97 | cur_fb = 0; 98 | swap_buffers(); 99 | 100 | printf( 101 | "\nframebuffer 0:\n" 102 | "\tsize: 0x%08X\n" 103 | "\tbase: 0x%08X\n" 104 | "\tpitch: 0x%08X\n" 105 | "\tpixelformat: 0x%08X\n" 106 | "\twidth: 0x%08X\n" 107 | "\theight 0x%08X\n", 108 | fb[0].size, (uintptr_t)fb[0].base, 109 | fb[0].pitch, fb[0].pixelformat, fb[0].width, fb[0].height); 110 | 111 | printf( 112 | "\nframebuffer 1:\n" 113 | "\tsize: 0x%08X\n" 114 | "\tbase: 0x%08X\n" 115 | "\tpitch: 0x%08X\n" 116 | "\tpixelformat: 0x%08X\n" 117 | "\twidth: 0x%08X\n" 118 | "\theight 0x%08X\n", 119 | fb[1].size, (uintptr_t)fb[1].base, 120 | fb[1].pitch, fb[1].pixelformat, fb[1].width, fb[1].height); 121 | } 122 | 123 | void end_video() 124 | { 125 | gpu_free(fb_memuid[0]); 126 | gpu_free(fb_memuid[1]); 127 | sceGxmTerminate(); 128 | } 129 | 130 | void swap_buffers() 131 | { 132 | sceDisplaySetFrameBuf(&fb[cur_fb], SCE_DISPLAY_SETBUF_NEXTFRAME); 133 | cur_fb ^= 1; 134 | } 135 | 136 | void clear_screen() 137 | { 138 | memset(fb[cur_fb].base, 0xFF, SCREEN_W*SCREEN_H*4); 139 | } 140 | 141 | void draw_pixel(uint32_t x, uint32_t y, uint32_t color) 142 | { 143 | ((uint32_t *)fb[cur_fb].base)[x + y*fb[cur_fb].pitch] = color; 144 | } 145 | 146 | void draw_rectangle(uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint32_t color) 147 | { 148 | int i, j; 149 | for (i = 0; i < h; i++) { 150 | for (j = 0; j < w; j++) { 151 | ((uint32_t *)fb[cur_fb].base)[(x + j) + (y + i)*fb[cur_fb].pitch] = color; 152 | } 153 | } 154 | } 155 | 156 | void draw_circle(uint32_t x, uint32_t y, uint32_t radius, uint32_t color) 157 | { 158 | int r2 = radius * radius; 159 | int area = r2 << 2; 160 | int rr = radius << 1; 161 | 162 | int i; 163 | for (i = 0; i < area; i++) { 164 | int tx = (i % rr) - radius; 165 | int ty = (i / rr) - radius; 166 | 167 | if (tx * tx + ty * ty <= r2) { 168 | draw_pixel(x + tx, y + ty, color); 169 | } 170 | } 171 | } 172 | 173 | void font_draw_char(int x, int y, uint32_t color, char c) 174 | { 175 | unsigned char *font = (unsigned char *)(msx_font + (c - (uint32_t)' ') * 8); 176 | int i, j, pos_x, pos_y; 177 | for (i = 0; i < 8; ++i) { 178 | pos_y = y + i*2; 179 | for (j = 0; j < 8; ++j) { 180 | pos_x = x + j*2; 181 | if ((*font & (128 >> j))) { 182 | draw_pixel(pos_x + 0, pos_y + 0, color); 183 | draw_pixel(pos_x + 1, pos_y + 0, color); 184 | draw_pixel(pos_x + 0, pos_y + 1, color); 185 | draw_pixel(pos_x + 1, pos_y + 1, color); 186 | } 187 | } 188 | ++font; 189 | } 190 | } 191 | 192 | void font_draw_string(int x, int y, uint32_t color, const char *string) 193 | { 194 | if (string == NULL) return; 195 | 196 | int startx = x; 197 | const char *s = string; 198 | 199 | while (*s) { 200 | if (*s == '\n') { 201 | x = startx; 202 | y += 16; 203 | } else if (*s == ' ') { 204 | x += 16; 205 | } else if(*s == '\t') { 206 | x += 16*4; 207 | } else { 208 | font_draw_char(x, y, color, *s); 209 | x += 16; 210 | } 211 | ++s; 212 | } 213 | } 214 | 215 | void font_draw_stringf(int x, int y, uint32_t color, const char *s, ...) 216 | { 217 | char buf[256]; 218 | va_list argptr; 219 | va_start(argptr, s); 220 | vsnprintf(buf, sizeof(buf), s, argptr); 221 | va_end(argptr); 222 | font_draw_string(x, y, color, buf); 223 | } 224 | 225 | -------------------------------------------------------------------------------- /font_data.c: -------------------------------------------------------------------------------- 1 | /* 2 | * PSP Software Development Kit - http://www.pspdev.org 3 | * ----------------------------------------------------------------------- 4 | * Licensed under the BSD license, see LICENSE in PSPSDK root for details. 5 | * 6 | * font.c - Debug Font. 7 | * 8 | * Copyright (c) 2005 Marcus R. Brown 9 | * Copyright (c) 2005 James Forshaw 10 | * Copyright (c) 2005 John Kelley 11 | * 12 | * $Id: font.c 540 2005-07-08 19:35:10Z warren $ 13 | */ 14 | 15 | const unsigned char msx_font[] __attribute((aligned(4))) = 16 | /*"\x00\x00\x00\x00\x00\x00\x00\x00\x3c\x42\xa5\x81\xa5\x99\x42\x3c" 17 | "\x3c\x7e\xdb\xff\xff\xdb\x66\x3c\x6c\xfe\xfe\xfe\x7c\x38\x10\x00" 18 | "\x10\x38\x7c\xfe\x7c\x38\x10\x00\x10\x38\x54\xfe\x54\x10\x38\x00" 19 | "\x10\x38\x7c\xfe\xfe\x10\x38\x00\x00\x00\x00\x30\x30\x00\x00\x00" 20 | "\xff\xff\xff\xe7\xe7\xff\xff\xff\x38\x44\x82\x82\x82\x44\x38\x00" 21 | "\xc7\xbb\x7d\x7d\x7d\xbb\xc7\xff\x0f\x03\x05\x79\x88\x88\x88\x70" 22 | "\x38\x44\x44\x44\x38\x10\x7c\x10\x30\x28\x24\x24\x28\x20\xe0\xc0" 23 | "\x3c\x24\x3c\x24\x24\xe4\xdc\x18\x10\x54\x38\xee\x38\x54\x10\x00" 24 | "\x10\x10\x10\x7c\x10\x10\x10\x10\x10\x10\x10\xff\x00\x00\x00\x00" 25 | "\x00\x00\x00\xff\x10\x10\x10\x10\x10\x10\x10\xf0\x10\x10\x10\x10" 26 | "\x10\x10\x10\x1f\x10\x10\x10\x10\x10\x10\x10\xff\x10\x10\x10\x10" 27 | "\x10\x10\x10\x10\x10\x10\x10\x10\x00\x00\x00\xff\x00\x00\x00\x00" 28 | "\x00\x00\x00\x1f\x10\x10\x10\x10\x00\x00\x00\xf0\x10\x10\x10\x10" 29 | "\x10\x10\x10\x1f\x00\x00\x00\x00\x10\x10\x10\xf0\x00\x00\x00\x00" 30 | "\x81\x42\x24\x18\x18\x24\x42\x81\x01\x02\x04\x08\x10\x20\x40\x80" 31 | "\x80\x40\x20\x10\x08\x04\x02\x01\x00\x10\x10\xff\x10\x10\x00\x00"*/ 32 | "\x00\x00\x00\x00\x00\x00\x00\x00\x20\x20\x20\x20\x00\x00\x20\x00" 33 | "\x50\x50\x50\x00\x00\x00\x00\x00\x50\x50\xf8\x50\xf8\x50\x50\x00" 34 | "\x20\x78\xa0\x70\x28\xf0\x20\x00\xc0\xc8\x10\x20\x40\x98\x18\x00" 35 | "\x40\xa0\x40\xa8\x90\x98\x60\x00\x10\x20\x40\x00\x00\x00\x00\x00" 36 | "\x10\x20\x40\x40\x40\x20\x10\x00\x40\x20\x10\x10\x10\x20\x40\x00" 37 | "\x20\xa8\x70\x20\x70\xa8\x20\x00\x00\x20\x20\xf8\x20\x20\x00\x00" 38 | "\x00\x00\x00\x00\x00\x20\x20\x40\x00\x00\x00\x78\x00\x00\x00\x00" 39 | "\x00\x00\x00\x00\x00\x60\x60\x00\x00\x00\x08\x10\x20\x40\x80\x00" 40 | "\x70\x88\x98\xa8\xc8\x88\x70\x00\x20\x60\xa0\x20\x20\x20\xf8\x00" 41 | "\x70\x88\x08\x10\x60\x80\xf8\x00\x70\x88\x08\x30\x08\x88\x70\x00" 42 | "\x10\x30\x50\x90\xf8\x10\x10\x00\xf8\x80\xe0\x10\x08\x10\xe0\x00" 43 | "\x30\x40\x80\xf0\x88\x88\x70\x00\xf8\x88\x10\x20\x20\x20\x20\x00" 44 | "\x70\x88\x88\x70\x88\x88\x70\x00\x70\x88\x88\x78\x08\x10\x60\x00" 45 | "\x00\x00\x20\x00\x00\x20\x00\x00\x00\x00\x20\x00\x00\x20\x20\x40" 46 | "\x18\x30\x60\xc0\x60\x30\x18\x00\x00\x00\xf8\x00\xf8\x00\x00\x00" 47 | "\xc0\x60\x30\x18\x30\x60\xc0\x00\x70\x88\x08\x10\x20\x00\x20\x00" 48 | "\x70\x88\x08\x68\xa8\xa8\x70\x00\x20\x50\x88\x88\xf8\x88\x88\x00" 49 | "\xf0\x48\x48\x70\x48\x48\xf0\x00\x30\x48\x80\x80\x80\x48\x30\x00" 50 | "\xe0\x50\x48\x48\x48\x50\xe0\x00\xf8\x80\x80\xf0\x80\x80\xf8\x00" 51 | "\xf8\x80\x80\xf0\x80\x80\x80\x00\x70\x88\x80\xb8\x88\x88\x70\x00" 52 | "\x88\x88\x88\xf8\x88\x88\x88\x00\x70\x20\x20\x20\x20\x20\x70\x00" 53 | "\x38\x10\x10\x10\x90\x90\x60\x00\x88\x90\xa0\xc0\xa0\x90\x88\x00" 54 | "\x80\x80\x80\x80\x80\x80\xf8\x00\x88\xd8\xa8\xa8\x88\x88\x88\x00" 55 | "\x88\xc8\xc8\xa8\x98\x98\x88\x00\x70\x88\x88\x88\x88\x88\x70\x00" 56 | "\xf0\x88\x88\xf0\x80\x80\x80\x00\x70\x88\x88\x88\xa8\x90\x68\x00" 57 | "\xf0\x88\x88\xf0\xa0\x90\x88\x00\x70\x88\x80\x70\x08\x88\x70\x00" 58 | "\xf8\x20\x20\x20\x20\x20\x20\x00\x88\x88\x88\x88\x88\x88\x70\x00" 59 | "\x88\x88\x88\x88\x50\x50\x20\x00\x88\x88\x88\xa8\xa8\xd8\x88\x00" 60 | "\x88\x88\x50\x20\x50\x88\x88\x00\x88\x88\x88\x70\x20\x20\x20\x00" 61 | "\xf8\x08\x10\x20\x40\x80\xf8\x00\x70\x40\x40\x40\x40\x40\x70\x00" 62 | "\x00\x00\x80\x40\x20\x10\x08\x00\x70\x10\x10\x10\x10\x10\x70\x00" 63 | "\x20\x50\x88\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf8\x00" 64 | "\x40\x20\x10\x00\x00\x00\x00\x00\x00\x00\x70\x08\x78\x88\x78\x00" 65 | "\x80\x80\xb0\xc8\x88\xc8\xb0\x00\x00\x00\x70\x88\x80\x88\x70\x00" 66 | "\x08\x08\x68\x98\x88\x98\x68\x00\x00\x00\x70\x88\xf8\x80\x70\x00" 67 | "\x10\x28\x20\xf8\x20\x20\x20\x00\x00\x00\x68\x98\x98\x68\x08\x70" 68 | "\x80\x80\xf0\x88\x88\x88\x88\x00\x20\x00\x60\x20\x20\x20\x70\x00" 69 | "\x10\x00\x30\x10\x10\x10\x90\x60\x40\x40\x48\x50\x60\x50\x48\x00" 70 | "\x60\x20\x20\x20\x20\x20\x70\x00\x00\x00\xd0\xa8\xa8\xa8\xa8\x00" 71 | "\x00\x00\xb0\xc8\x88\x88\x88\x00\x00\x00\x70\x88\x88\x88\x70\x00" 72 | "\x00\x00\xb0\xc8\xc8\xb0\x80\x80\x00\x00\x68\x98\x98\x68\x08\x08" 73 | "\x00\x00\xb0\xc8\x80\x80\x80\x00\x00\x00\x78\x80\xf0\x08\xf0\x00" 74 | "\x40\x40\xf0\x40\x40\x48\x30\x00\x00\x00\x90\x90\x90\x90\x68\x00" 75 | "\x00\x00\x88\x88\x88\x50\x20\x00\x00\x00\x88\xa8\xa8\xa8\x50\x00" 76 | "\x00\x00\x88\x50\x20\x50\x88\x00\x00\x00\x88\x88\x98\x68\x08\x70" 77 | "\x00\x00\xf8\x10\x20\x40\xf8\x00\x18\x20\x20\x40\x20\x20\x18\x00" 78 | "\x20\x20\x20\x00\x20\x20\x20\x00\xc0\x20\x20\x10\x20\x20\xc0\x00" 79 | "\x40\xa8\x10\x00\x00\x00\x00\x00\x00\x00\x20\x50\xf8\x00\x00\x00" 80 | "\x70\x88\x80\x80\x88\x70\x20\x60\x90\x00\x00\x90\x90\x90\x68\x00" 81 | /*"\x10\x20\x70\x88\xf8\x80\x70\x00\x20\x50\x70\x08\x78\x88\x78\x00" 82 | "\x48\x00\x70\x08\x78\x88\x78\x00\x20\x10\x70\x08\x78\x88\x78\x00" 83 | "\x20\x00\x70\x08\x78\x88\x78\x00\x00\x70\x80\x80\x80\x70\x10\x60" 84 | "\x20\x50\x70\x88\xf8\x80\x70\x00\x50\x00\x70\x88\xf8\x80\x70\x00" 85 | "\x20\x10\x70\x88\xf8\x80\x70\x00\x50\x00\x00\x60\x20\x20\x70\x00" 86 | "\x20\x50\x00\x60\x20\x20\x70\x00\x40\x20\x00\x60\x20\x20\x70\x00" 87 | "\x50\x00\x20\x50\x88\xf8\x88\x00\x20\x00\x20\x50\x88\xf8\x88\x00" 88 | "\x10\x20\xf8\x80\xf0\x80\xf8\x00\x00\x00\x6c\x12\x7e\x90\x6e\x00" 89 | "\x3e\x50\x90\x9c\xf0\x90\x9e\x00\x60\x90\x00\x60\x90\x90\x60\x00" 90 | "\x90\x00\x00\x60\x90\x90\x60\x00\x40\x20\x00\x60\x90\x90\x60\x00" 91 | "\x40\xa0\x00\xa0\xa0\xa0\x50\x00\x40\x20\x00\xa0\xa0\xa0\x50\x00" 92 | "\x90\x00\x90\x90\xb0\x50\x10\xe0\x50\x00\x70\x88\x88\x88\x70\x00" 93 | "\x50\x00\x88\x88\x88\x88\x70\x00\x20\x20\x78\x80\x80\x78\x20\x20" 94 | "\x18\x24\x20\xf8\x20\xe2\x5c\x00\x88\x50\x20\xf8\x20\xf8\x20\x00" 95 | "\xc0\xa0\xa0\xc8\x9c\x88\x88\x8c\x18\x20\x20\xf8\x20\x20\x20\x40" 96 | "\x10\x20\x70\x08\x78\x88\x78\x00\x10\x20\x00\x60\x20\x20\x70\x00" 97 | "\x20\x40\x00\x60\x90\x90\x60\x00\x20\x40\x00\x90\x90\x90\x68\x00" 98 | "\x50\xa0\x00\xa0\xd0\x90\x90\x00\x28\x50\x00\xc8\xa8\x98\x88\x00" 99 | "\x00\x70\x08\x78\x88\x78\x00\xf8\x00\x60\x90\x90\x90\x60\x00\xf0" 100 | "\x20\x00\x20\x40\x80\x88\x70\x00\x00\x00\x00\xf8\x80\x80\x00\x00" 101 | "\x00\x00\x00\xf8\x08\x08\x00\x00\x84\x88\x90\xa8\x54\x84\x08\x1c" 102 | "\x84\x88\x90\xa8\x58\xa8\x3c\x08\x20\x00\x00\x20\x20\x20\x20\x00" 103 | "\x00\x00\x24\x48\x90\x48\x24\x00\x00\x00\x90\x48\x24\x48\x90\x00" 104 | "\x28\x50\x20\x50\x88\xf8\x88\x00\x28\x50\x70\x08\x78\x88\x78\x00" 105 | "\x28\x50\x00\x70\x20\x20\x70\x00\x28\x50\x00\x20\x20\x20\x70\x00" 106 | "\x28\x50\x00\x70\x88\x88\x70\x00\x50\xa0\x00\x60\x90\x90\x60\x00" 107 | "\x28\x50\x00\x88\x88\x88\x70\x00\x50\xa0\x00\xa0\xa0\xa0\x50\x00" 108 | "\xfc\x48\x48\x48\xe8\x08\x50\x20\x00\x50\x00\x50\x50\x50\x10\x20" 109 | "\xc0\x44\xc8\x54\xec\x54\x9e\x04\x10\xa8\x40\x00\x00\x00\x00\x00" 110 | "\x00\x20\x50\x88\x50\x20\x00\x00\x88\x10\x20\x40\x80\x28\x00\x00" 111 | "\x7c\xa8\xa8\x68\x28\x28\x28\x00\x38\x40\x30\x48\x48\x30\x08\x70" 112 | "\x00\x00\x00\x00\x00\x00\xff\xff\xf0\xf0\xf0\xf0\x0f\x0f\x0f\x0f" 113 | "\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00" 114 | "\x00\x00\x00\x3c\x3c\x00\x00\x00\xff\xff\xff\xff\xff\xff\x00\x00" 115 | "\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\x0f\x0f\x0f\x0f\xf0\xf0\xf0\xf0" 116 | "\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\x03\x03\x03\x03\x03\x03\x03\x03" 117 | "\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x11\x22\x44\x88\x11\x22\x44\x88" 118 | "\x88\x44\x22\x11\x88\x44\x22\x11\xfe\x7c\x38\x10\x00\x00\x00\x00" 119 | "\x00\x00\x00\x00\x10\x38\x7c\xfe\x80\xc0\xe0\xf0\xe0\xc0\x80\x00" 120 | "\x01\x03\x07\x0f\x07\x03\x01\x00\xff\x7e\x3c\x18\x18\x3c\x7e\xff" 121 | "\x81\xc3\xe7\xff\xff\xe7\xc3\x81\xf0\xf0\xf0\xf0\x00\x00\x00\x00" 122 | "\x00\x00\x00\x00\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x00\x00\x00\x00" 123 | "\x00\x00\x00\x00\xf0\xf0\xf0\xf0\x33\x33\xcc\xcc\x33\x33\xcc\xcc" 124 | "\x00\x20\x20\x50\x50\x88\xf8\x00\x20\x20\x70\x20\x70\x20\x20\x00" 125 | "\x00\x00\x00\x50\x88\xa8\x50\x00\xff\xff\xff\xff\xff\xff\xff\xff" 126 | "\x00\x00\x00\x00\xff\xff\xff\xff\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0" 127 | "\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\xff\xff\xff\xff\x00\x00\x00\x00" 128 | "\x00\x00\x68\x90\x90\x90\x68\x00\x30\x48\x48\x70\x48\x48\x70\xc0" 129 | "\xf8\x88\x80\x80\x80\x80\x80\x00\xf8\x50\x50\x50\x50\x50\x98\x00" 130 | "\xf8\x88\x40\x20\x40\x88\xf8\x00\x00\x00\x78\x90\x90\x90\x60\x00" 131 | "\x00\x50\x50\x50\x50\x68\x80\x80\x00\x50\xa0\x20\x20\x20\x20\x00" 132 | "\xf8\x20\x70\xa8\xa8\x70\x20\xf8\x20\x50\x88\xf8\x88\x50\x20\x00" 133 | "\x70\x88\x88\x88\x50\x50\xd8\x00\x30\x40\x40\x20\x50\x50\x50\x20" 134 | "\x00\x00\x00\x50\xa8\xa8\x50\x00\x08\x70\xa8\xa8\xa8\x70\x80\x00" 135 | "\x38\x40\x80\xf8\x80\x40\x38\x00\x70\x88\x88\x88\x88\x88\x88\x00" 136 | "\x00\xf8\x00\xf8\x00\xf8\x00\x00\x20\x20\xf8\x20\x20\x00\xf8\x00" 137 | "\xc0\x30\x08\x30\xc0\x00\xf8\x00\x18\x60\x80\x60\x18\x00\xf8\x00" 138 | "\x10\x28\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\xa0\x40" 139 | "\x00\x20\x00\xf8\x00\x20\x00\x00\x00\x50\xa0\x00\x50\xa0\x00\x00" 140 | "\x00\x18\x24\x24\x18\x00\x00\x00\x00\x30\x78\x78\x30\x00\x00\x00" 141 | "\x00\x00\x00\x00\x30\x00\x00\x00\x3e\x20\x20\x20\xa0\x60\x20\x00" 142 | "\xa0\x50\x50\x50\x00\x00\x00\x00\x40\xa0\x20\x40\xe0\x00\x00\x00" 143 | "\x00\x38\x38\x38\x38\x38\x38\x00\x00\x00\x00\x00\x00\x00\x00"*/; 144 | --------------------------------------------------------------------------------