// Game Boy Advance library for Logic Machines F'05 // Version 4, October 28, 2005 // These includes come from libgba #include "gba_input.h" #include "gba_video.h" #include "gba_sprites.h" #include "gba_systemcalls.h" #include "gbaio.h" static void srand(void); static void load_web_palette(unsigned short *palette); static void init_sprites(void); // **************************************************************************************************** // Initialization void start_game(void) { srand(); start_drawing(); // set up video on the vblank so there are no screen glitches video_mode(3); init_sprites(); } // **************************************************************************************************** // Input static unsigned short previous_buttons_down = 0, buttons_down = 0; void start_input(void) { previous_buttons_down = buttons_down; buttons_down = (REG_KEYINPUT ^ 0xFFFF); } int button_pressed(int which) { return (buttons_down & which) && !(previous_buttons_down & which); } int button_released(int which) { return !(buttons_down & which) && (previous_buttons_down & which); } int button_held(int which) { return (buttons_down & which) != 0; } // **************************************************************************************************** // Drawing static unsigned short display_control = 0x0000; static int free_tile; char shroom[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0xAD, 0xAD, 0xAD, 0x00, 0x00, 0x00, 0xAD, 0xAD, 0x01, 0x01, 0x6C, 0x00, 0x00, 0xAD, 0x01, 0x01, 0x01, 0x24, 0x24, 0x00, 0xAD, 0x6C, 0x6C, 0x24, 0x24, 0x16, 0x16, 0x00, 0xAD, 0x6C, 0x24, 0x24, 0x16, 0x16, 0x16, 0xAD, 0x01, 0x24, 0x24, 0x16, 0x16, 0x01, 0x01, 0xAD, 0x01, 0x01, 0x24, 0x16, 0x01, 0x01, 0x01, 0xAD, 0x01, 0x01, 0x24, 0x16, 0x01, 0x01, 0x01, 0xAD, 0xAD, 0xAD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6C, 0x01, 0x01, 0xAD, 0xAD, 0x00, 0x00, 0x00, 0x24, 0x24, 0x01, 0x01, 0x01, 0xAD, 0x00, 0x00, 0x16, 0x16, 0x24, 0x24, 0x6C, 0x6C, 0xAD, 0x00, 0x16, 0x16, 0x16, 0x24, 0x24, 0x6C, 0xAD, 0x00, 0x01, 0x01, 0x16, 0x16, 0x24, 0x24, 0x01, 0xAD, 0x01, 0x01, 0x01, 0x16, 0x24, 0x01, 0x01, 0xAD, 0x01, 0x01, 0x01, 0x16, 0x24, 0x01, 0x01, 0xAD, 0xAD, 0x01, 0x24, 0x24, 0x24, 0x01, 0x01, 0x01, 0xAD, 0x6C, 0x24, 0x24, 0x6C, 0x6C, 0x01, 0x01, 0xAD, 0x6C, 0x6C, 0x6C, 0xAD, 0xAD, 0xAD, 0xAD, 0x00, 0xAD, 0xAD, 0xAD, 0x0F, 0x0F, 0xAD, 0x0F, 0x00, 0x00, 0xAD, 0x0F, 0x01, 0x01, 0xAD, 0x01, 0x00, 0x00, 0xAD, 0x0F, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0xAD, 0x0F, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0xAD, 0xAD, 0xAD, 0xAD, 0x01, 0x01, 0x01, 0x24, 0x24, 0x24, 0x01, 0xAD, 0x01, 0x01, 0x6C, 0x6C, 0x24, 0x24, 0x6C, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0x6C, 0x6C, 0x6C, 0xAD, 0x0F, 0xAD, 0x0F, 0x0F, 0xAD, 0xAD, 0xAD, 0x00, 0x01, 0xAD, 0x01, 0x01, 0x0F, 0xAD, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x0F, 0xAD, 0x00, 0x00, 0x01, 0x01, 0x01, 0x0F, 0xAD, 0x00, 0x00, 0x00, 0xAD, 0xAD, 0xAD, 0xAD, 0x00, 0x00, 0x00, 0x00 }; static void init_sprites(void) { int sprite; load_web_palette(OBJ_COLORS); load_image(511, shroom, IMAGE_16x16); for (sprite = 0; sprite < 128; ++sprite) { set_sprite_image(sprite, 511); draw_sprite(sprite, 240, 160); // off screen } display_control |= OBJ_1D_MAP | OBJ_ENABLE; REG_DISPCNT = display_control; } void start_drawing(void) { while ((REG_DISPSTAT & LCDC_VBL_FLAG)) ; while (!(REG_DISPSTAT & LCDC_VBL_FLAG)) ; } const static unsigned char num_tiles_table[] = { 2, // IMAGE_8x8 8, // IMAGE_16x16 32, // IMAGE_32x32 128, // IMAGE_64x64 4, // IMAGE_16x8 8, // IMAGE_32x8 16, // IMAGE_32x16 64, // IMAGE_64x32 4, // IMAGE_8x16 8, // IMAGE_8x32 16, // IMAGE_16x32 64 // IMAGE_32x64 }; const static unsigned char size0_table[] = { 0, // IMAGE_8x8 0, // IMAGE_16x16 0, // IMAGE_32x32 0, // IMAGE_64x64 1, // IMAGE_16x8 1, // IMAGE_32x8 1, // IMAGE_32x16 1, // IMAGE_64x32 2, // IMAGE_8x16 2, // IMAGE_8x32 2, // IMAGE_16x32 2 // IMAGE_32x64 }; const static unsigned char size1_table[] = { 0, // IMAGE_8x8 1, // IMAGE_16x16 2, // IMAGE_32x32 3, // IMAGE_64x64 0, // IMAGE_16x8 1, // IMAGE_32x8 2, // IMAGE_32x16 3, // IMAGE_64x32 0, // IMAGE_8x16 1, // IMAGE_8x32 2, // IMAGE_16x32 3 // IMAGE_32x64 }; static unsigned int image_tile[512]; static unsigned char image_size[512]; void load_image(int image_number, char *image, int size) { int tile, num_tiles; void *dest; tile = free_tile; num_tiles = num_tiles_table[size]; dest = OBJ_BASE_ADR + (tile * 32); CpuFastSet(image, dest, num_tiles * 32); free_tile += num_tiles; image_tile[image_number] = tile; image_size[image_number] = size; } void set_sprite_image(int sprite_number, int image_number) { OBJATTR *s; unsigned int tile, size; tile = image_tile[image_number]; size = image_size[image_number]; s = &OAM[sprite_number]; s->attr0 = (s->attr0 & 0x1FFF) | OBJ_256_COLOR | OBJ_SHAPE((unsigned int)size0_table[size]); s->attr1 = (s->attr1 & 0x3FFF) | OBJ_SIZE((unsigned int)size1_table[size]); s->attr2 = (s->attr2 & 0xFC00) | tile; } void draw_sprite(int sprite_number, int x, int y) { OBJATTR *s; s = &OAM[sprite_number]; s->attr0 = (s->attr0 & 0xFF00) | (y & 0xFF); s->attr1 = (s->attr1 & 0xFE00) | (x & 0x1FF); } static void load_web_palette(unsigned short *palette) { static unsigned char factor[] = {0, 7, 13, 19, 25, 31}; int r, g, b; *palette++ = 0x0000; // transparent color placeholder for (r = 5; r >=0; --r) for (g = 5; g >= 0; --g) for (b = 5; b >= 0; --b) *palette++ = rgb_color(factor[r], factor[g], factor[b]); } void set_color(int color_number, int red, int green, int blue) { OBJ_COLORS[color_number] = rgb_color(red, green, blue); } unsigned short rgb_color(int red, int green, int blue) { return (blue<<10) | (green<<5) | red; } #define BG_MEM ((u16*)0x06000000) #define BG_WIDTH 240 void draw_dot( int x, int y, int r, int g, int b ){ int color = RGB5(r, g, b); BG_MEM[x+y*BG_WIDTH] = color; } void video_mode(int mode) { display_control = (display_control & 0xFFF8) | mode; if (mode == 3) { display_control |= BG2_ENABLE; free_tile = 512; } REG_DISPCNT = display_control; } // **************************************************************************************************** // Utility functions static int nxti, nxtp; static unsigned long ma[56]; static int seeded = 0; #define INITIAL_SEED 161803398L int rand(int min, int max) { unsigned long mj; if (!seeded) srand(); if (++nxti == 56) nxti = 1; if (++nxtp == 56) nxtp = 1; mj = ma[nxti] - ma[nxtp]; ma[nxti] = mj; mj = ((mj / 10000) % (max - min + 1)) + min; return (int) mj; } static void srand(void) { unsigned long mj, mk; int i, k; mj = INITIAL_SEED; ma[55] = mj; mk = 1; for (i = 1; i <= 54; ++i) { int ii = (21 * i) % 55; ma[ii] = mk; mk = mj - mk; mj = ma[ii]; } for (k = 1; k <= 4; ++k) for (i = 1; i <= 55; ++i) ma[i] -= ma[1 + (i + 30) % 55]; nxti = 0; nxtp = 31; seeded = 1; }