diff --git a/nes/nescoundrel.c b/nes/nescoundrel.c index 477c8c9..61d4651 100644 --- a/nes/nescoundrel.c +++ b/nes/nescoundrel.c @@ -25,6 +25,11 @@ #define KEY_SL 7 #define KEY_ST 8 +#define GAME_WHITE 0 +#define GAME_RED 1 +#define GAME_YELLOW 2 +#define GAME_GREEN 3 + int joy_input_wait() { unsigned char last_joy = 0, joy, pressed; /* wait until the previous key is released */ @@ -46,19 +51,47 @@ int joy_input_wait() { } } +/* palette loader */ +void init_palette() { + unsigned char i; + const unsigned char my_palette[16] = { + 0x0f, 0, 0, 0x30, /* white */ + 0x0f, 0, 0, 0x15, /* red */ + 0x0f, 0, 0, 0x28, /* yellow */ + 0x0f, 0, 0, 0x2A /* green */ + }; + PPU.vram.address = 0x3F; + PPU.vram.address = 0; + for(i=0; i<16; i++) PPU.vram.data = my_palette[i]; +} + +/* 4x4 char block colorization method (palette is 0 to 3) */ +void colorxy(unsigned char x, unsigned char y, unsigned char palette) { + unsigned int addr; + unsigned char attr_byte; + addr = 0x23C0 + ((y >> 2) << 3) + (x >> 2); + attr_byte = palette | (palette << 2) | (palette << 4) | (palette << 6); + waitvsync(); + PPU.vram.address = (unsigned char) (addr >> 8); + PPU.vram.address = (unsigned char) (addr & 255); + PPU.vram.data = attr_byte; +} + void game_startup() { - unsigned int entropy; + unsigned int entropy, i, j; unsigned char joy; #ifdef _randomize _randomize(); #endif entropy = rand(); - clrscr(); bgcolor(COLOR_BLACK); textcolor(0); - gotoxy(7, 2); - cputs("Luxferre presents"); - gotoxy(0, 3); + init_palette(); + clrscr(); + for(j=0;j<24;j+=4) + for(i=3;i<32;i+=4) + colorxy(i, j, 1 + ((++entropy) % 3)); + gotoxy(0, 2); cputs( \ " _______ _______ _______ \r\n" \ " | _ | _ | _ |\r\n" \ @@ -83,13 +116,12 @@ void game_startup() { " |: | |: 1 |: 1 |\r\n" \ " |::.|:. |::.. . |::.. . |\r\n" \ " `--- ---`-------`-------'"); - gotoxy(SCREEN_CENTER_X - 6, SCREEN_HEIGHT - 3); - cputs("Press Start"); - gotoxy(SCREEN_WIDTH-5, SCREEN_HEIGHT - 2); - cputs("2026"); + cputsxy(SCREEN_CENTER_X - 6, SCREEN_HEIGHT - 4, "Press Start"); + cputsxy(1, SCREEN_HEIGHT - 2, "Luxferre"); + cputsxy(SCREEN_WIDTH-5, SCREEN_HEIGHT - 2, "2026"); joy_install(joy_static_stddrv); while(1) { - entropy++; + ++entropy; joy = joy_read(JOY_1); if(JOY_START(joy)) break; waitvsync(); @@ -100,7 +132,11 @@ void game_startup() { /* Win screen display */ void win_screen(int score) { + unsigned char i, j; clrscr(); + for(j=0;j<12;j+=4) + for(i=3;i<32;i+=4) + colorxy(i, j, 1 + (rand() % 3)); gotoxy(0, 3); cputs(" ___ ___ ___ ______ \r\n" \ " | Y | | _ \\ \r\n" \ @@ -169,22 +205,23 @@ char get_choice() { /* Draw a room character according to the index and value */ void render_room_item(short i, short v) { - short topleft_x, topleft_y, + unsigned char color, + topleft_x, topleft_y, topright_x, bottomleft_y, text_x, text_y, cheight=7, cwidth=8, left_offset = 9; if(i == 0) { topleft_x = 8; - topleft_y = 3; + topleft_y = 0; } else if(i == 1) { - topleft_x = 1; - topleft_y = 9; + topleft_x = 0; + topleft_y = 8; } else if(i == 2) { - topleft_x = 15; - topleft_y = 9; + topleft_x = 16; + topleft_y = 8; } else if(i == 3) { topleft_x = 8; - topleft_y = 15; + topleft_y = 16; } topright_x = topleft_x + cwidth - 1; bottomleft_y = topleft_y + cheight - 1; @@ -192,6 +229,17 @@ void render_room_item(short i, short v) { text_y = topleft_y + 2; if(v == 0) {} /* don't render anything */ else { + if(v < 14) { + color = GAME_RED; + } else if(v < 23) { + color = GAME_YELLOW; + } else { + color = GAME_GREEN; + } + colorxy(topleft_x, topleft_y, color); + colorxy(topleft_x+4, topleft_y, color); + colorxy(topleft_x, topleft_y+4, color); + colorxy(topleft_x+4, topleft_y+4, color); /* draw the rectangle */ chlinexy(topleft_x + 1, topleft_y, cwidth - 2); chlinexy(topleft_x + 1, bottomleft_y, cwidth - 2); @@ -199,9 +247,13 @@ void render_room_item(short i, short v) { cvlinexy(topright_x, topleft_y + 1, cheight - 2); /* draw text */ gotoxy(text_x, text_y); - if(v < 14) cputs("ENEMY "); - else if(v < 23) cputs("WEAPON"); - else cputs("POTION"); + if(v < 14) { + cputs("ENEMY "); + } else if(v < 23) { + cputs("WEAPON"); + } else { + cputs("POTION"); + } gotoxy(text_x, text_y+2); if(v < 14) cprintf("LVL %02d", v + 1); else if(v < 23) cprintf("LVL %02d", v - 12); @@ -222,37 +274,28 @@ void render_main_scene() { if(deck[i]) deck_count++; clrscr(); /* render the frames */ - cvlinexy(0,0,SCREEN_HEIGHT); - cvlinexy(SCREEN_WIDTH-1,0,SCREEN_HEIGHT); - chlinexy(1,0,SCREEN_WIDTH-2); - chlinexy(1,SCREEN_HEIGHT-1,SCREEN_WIDTH-2); - chlinexy(1,SCREEN_HEIGHT-3,SCREEN_WIDTH-2); - cputsxy(9, 0, "SCOUNDREL-2026"); - cputsxy(2, SCREEN_HEIGHT-5,"D-Pad to select item"); + chlinexy(0,SCREEN_HEIGHT-1,SCREEN_WIDTH); + chlinexy(0,SCREEN_HEIGHT-3,SCREEN_WIDTH); /* render the room */ for(i=0;i<4;i++) render_room_item(i, room[i]); - cputsxy(10, 12, "ROOM"); + cputsxy(10, 10, "DECK"); + gotoxy(11, 12); + cprintf("%02d", deck_count); + cvlinexy(9, 10, 3); + cvlinexy(14, 10, 3); + chlinexy(10, 9, 4); + chlinexy(10, 13, 4); /* render stats */ - gotoxy(statbase, 5); + gotoxy(statbase, 1); cprintf("Health %02d", hp); - gotoxy(statbase, 6); + gotoxy(statbase, 3); cprintf("Weapon %02d", weapon); - gotoxy(statbase, 7); + gotoxy(statbase, 5); cprintf("Durability %02d", durability); - gotoxy(statbase, 17); - cprintf("Deck cards %02d", deck_count); - gotoxy(statbase, 19); + cputsxy(statbase, 17, "Choose: D-Pad"); + cputsxy(statbase, 19, can_run ? "Run: A/B/SELECT" : "Cannot run!"); + gotoxy(statbase, 21); cprintf("Rooms clrd %02d", rooms_cleared); - - /* render controls info */ - if(can_run) { - cputsxy(24, 10, "Run:"); - cputsxy(24, 12, "A/B or"); - cputsxy(24, 14, "SELECT"); - } else { - cputsxy(24, 11, "Cannot"); - cputsxy(24, 13, " run!"); - } /* render status message */ gotoxy(1, SCREEN_HEIGHT-2); cprintf("%s", status_msg);