diff --git a/Makefile b/Makefile index ee9116f..fa9a0c3 100644 --- a/Makefile +++ b/Makefile @@ -45,7 +45,7 @@ vdp1/normal_sprite_animated.elf: vdp1/normal_sprite_animated.o res/mai.data.o re smpc/input_intback.elf: smpc/input_intback.o sh/lib1funcs.o res/dejavusansmono.font.bin: tools/ttf-convert - ./tools/ttf-convert 20 7f 32 $(shell fc-match -f '%{file}' 'DejaVu Sans Mono') $@ + ./tools/ttf-convert 20 7f 22 $(shell fc-match -f '%{file}' 'DejaVu Sans Mono') $@ res/ipapgothic.font.bin: tools/ttf-convert ./tools/ttf-convert 3000 30ff 28 $(shell fc-match -f '%{file}' 'IPAPGothic') $@ diff --git a/common/draw_font.hpp b/common/draw_font.hpp index 0c790f1..899a07a 100644 --- a/common/draw_font.hpp +++ b/common/draw_font.hpp @@ -50,11 +50,13 @@ uint32_t horizontal_string(state const& s, } template -void single_character(state const& s, - const uint32_t cmd_ix, - const T c, - const int32_t x, // in 26.6 fixed point - const int32_t y) // in 26.6 fixed point +uint32_t single_character_centered(state const& s, + uint32_t cmd_ix, + const T c, + const int32_t x1, // in 26.6 fixed point + const int32_t y1, + const int32_t x2, + const int32_t y2) { //assert(c <= s.char_code_offset); const T c_offset = c - s._font->char_code_offset; @@ -62,6 +64,25 @@ void single_character(state const& s, glyph_bitmap const& bitmap = s._glyphs[c_offset].bitmap; glyph_metrics const& metrics = s._glyphs[c_offset].metrics; + constexpr uint16_t magenta = (0x31 << 10) | (0x31 << 0); + + vdp1.vram.cmd[cmd_ix].CTRL = CTRL__JP__JUMP_NEXT | CTRL__COMM__POLYLINE; + vdp1.vram.cmd[cmd_ix].LINK = 0; + vdp1.vram.cmd[cmd_ix].PMOD = PMOD__ECD | PMOD__SPD; + vdp1.vram.cmd[cmd_ix].COLR = COLR__RGB | magenta; // non-palettized (rgb15) color data + vdp1.vram.cmd[cmd_ix].XA = x1; + vdp1.vram.cmd[cmd_ix].YA = y1; + vdp1.vram.cmd[cmd_ix].XB = x2; + vdp1.vram.cmd[cmd_ix].YB = y1; + vdp1.vram.cmd[cmd_ix].XC = x2; + vdp1.vram.cmd[cmd_ix].YC = y2; + vdp1.vram.cmd[cmd_ix].XD = x1; + vdp1.vram.cmd[cmd_ix].YD = y2; + cmd_ix++; + + int32_t x_gap = (((x2 - x1 + 1) << 6) - s._font->max_advance) >> 1; + int32_t y_gap = (((y2 - y1) << 6) - s._font->height) >> 2; + if (bitmap.pitch != 0) { vdp1.vram.cmd[cmd_ix].CTRL = CTRL__JP__JUMP_NEXT | CTRL__COMM__NORMAL_SPRITE; vdp1.vram.cmd[cmd_ix].LINK = 0; @@ -69,9 +90,12 @@ void single_character(state const& s, vdp1.vram.cmd[cmd_ix].COLR = s.color_address; vdp1.vram.cmd[cmd_ix].SRCA = SRCA(s.character_address + bitmap.offset); vdp1.vram.cmd[cmd_ix].SIZE = SIZE__X(bitmap.pitch) | SIZE__Y(bitmap.rows); - vdp1.vram.cmd[cmd_ix].XA = (x + metrics.horiBearingX) >> 6; - vdp1.vram.cmd[cmd_ix].YA = (y - metrics.horiBearingY) >> 6; + vdp1.vram.cmd[cmd_ix].XA = ((x1 << 6) + x_gap + metrics.horiBearingX) >> 6; + vdp1.vram.cmd[cmd_ix].YA = ((y2 << 6) + y_gap - metrics.horiBearingY) >> 6; + cmd_ix++; } + + return cmd_ix; } } diff --git a/tools/ttf-convert.cpp b/tools/ttf-convert.cpp index e423e83..df9d57a 100644 --- a/tools/ttf-convert.cpp +++ b/tools/ttf-convert.cpp @@ -160,6 +160,7 @@ int main(int argc, char *argv[]) int font_size; ss3 << std::dec << argv[3]; ss3 >> font_size; + std::cerr << "font_size: " << font_size << '\n'; error = FT_Set_Pixel_Sizes (face, 0, font_size); if (error) { diff --git a/wordle/draw.cpp b/wordle/draw.cpp index 7ed25de..928bfd3 100644 --- a/wordle/draw.cpp +++ b/wordle/draw.cpp @@ -3,24 +3,61 @@ namespace wordle { namespace draw { -void keyboard() +constexpr int32_t box_dim = 21; +constexpr int32_t grid_space = box_dim + 2; + +const static uint8_t layout[3][10] = { + {'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P'}, + {'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L'}, + {'Z', 'X', 'C', 'V', 'B', 'N', 'M'}, +}; + + +void keyboard(struct screen const& s, void (*draw_char)(uint8_t, int32_t, int32_t, int32_t, int32_t)) { -} + constexpr int32_t origin_x[3] = {46, 57, 69}; + constexpr int32_t origin_y = 170; + constexpr uint32_t rows = 3; + constexpr uint32_t cols[3] = {10, 9, 7}; -static inline void guess(struct row const& r, void (*draw_char)(uint8_t, int32_t, int32_t)) -{ - for (uint32_t i = 0; i < word_length; i++) { - uint8_t l = r.letters[i]; + for (uint32_t row = 0; row < rows; row++) { + for (uint32_t col = 0; col < cols[row]; col++) { + uint8_t l = layout[row][col]; - draw_char(l, 0, 0); + int32_t x1 = origin_x[row] + (col * grid_space); + int32_t y1 = origin_y + (row * grid_space); + int32_t x2 = x1 + box_dim; + int32_t y2 = y1 + box_dim; - break; + draw_char(l, x1, y1, x2, y2); + } } } -void guesses(struct screen& s, void (*draw_char)(uint8_t, int32_t, int32_t)) +void guesses(struct screen const& s, void (*draw_char)(uint8_t, int32_t, int32_t, int32_t, int32_t)) { - guess(s.rows[0], draw_char); + // first row is at (104,23). + // midpoint is +(10,10) + // grid is +(13,13) + + constexpr int32_t origin_x = 103; + constexpr int32_t origin_y = 17; + + for (uint32_t row = 0; row < wordle::guesses; row++) { + + struct row const& r = s.rows[row]; + + for (uint32_t col = 0; col < word_length; col++) { + uint8_t l = r.letters[col]; + + int32_t x1 = origin_x + (col * grid_space); + int32_t y1 = origin_y + (row * grid_space); + int32_t x2 = x1 + box_dim; + int32_t y2 = y1 + box_dim; + + draw_char(l, x1, y1, x2, y2); + } + } } // end namespace diff --git a/wordle/draw.hpp b/wordle/draw.hpp index 734878b..ddefbf2 100644 --- a/wordle/draw.hpp +++ b/wordle/draw.hpp @@ -1,5 +1,6 @@ namespace wordle { namespace draw { - void guesses(struct screen& s, void (*draw_char)(uint8_t, int32_t, int32_t)); + void keyboard(struct screen const& s, void (*draw_char)(uint8_t, int32_t, int32_t, int32_t, int32_t)); + void guesses(struct screen const& s, void (*draw_char)(uint8_t, int32_t, int32_t, int32_t, int32_t)); } } diff --git a/wordle/main_saturn.cpp b/wordle/main_saturn.cpp index a794195..da4c4d7 100644 --- a/wordle/main_saturn.cpp +++ b/wordle/main_saturn.cpp @@ -135,25 +135,26 @@ void smpc_int(void) { // rendering -void draw_char(uint8_t c, int32_t x, int32_t y) +void draw_char(uint8_t c, int32_t x1, int32_t y1, int32_t x2, int32_t y2) { - draw_font::single_character(draw_state.font, - draw_state.cmd_ix++, - c, - (x) << 6, - (y + 30) << 6); - - vdp1.vram.cmd[draw_state.cmd_ix].CTRL = CTRL__END; + draw_state.cmd_ix = + draw_font::single_character_centered(draw_state.font, + draw_state.cmd_ix, + c, + x1, + y1, + x2, + y2); } void render() { draw_state.cmd_ix = 2; - - wordle_state.rows[0].letters[0] = 't'; - wordle::draw::guesses(wordle_state, &draw_char); + wordle::draw::keyboard(wordle_state, &draw_char); + + vdp1.vram.cmd[draw_state.cmd_ix].CTRL = CTRL__END; } void v_blank_in_int(void) __attribute__ ((interrupt_handler)); @@ -217,6 +218,11 @@ void main() // wait for the beginning of a V blank v_blank_in(); + // wordle init + const uint8_t word[] = "67890"; + wordle::init_screen(wordle_state, word); + // end wordle init + // DISP: Please make sure to change this bit from 0 to 1 during V blank. vdp2.reg.TVMD = ( TVMD__DISP | TVMD__LSMD__NON_INTERLACE | TVMD__VRESO__240 | TVMD__HRESO__NORMAL_320); diff --git a/wordle/wordle.cpp b/wordle/wordle.cpp index 2f01e40..8c7f79d 100644 --- a/wordle/wordle.cpp +++ b/wordle/wordle.cpp @@ -5,7 +5,7 @@ namespace wordle { -void init_game(struct screen& s, const uint8_t * word) +void init_screen(struct screen& s, const uint8_t * word) { s.edit.row = 0; s.edit.index = 0; @@ -18,6 +18,42 @@ void init_game(struct screen& s, const uint8_t * word) s.word[j] = word[j]; } + s.rows[0].letters[0] = 'A'; + s.rows[0].letters[1] = 'B'; + s.rows[0].letters[2] = 'C'; + s.rows[0].letters[3] = 'D'; + s.rows[0].letters[4] = 'E'; + + s.rows[1].letters[0] = 'F'; + s.rows[1].letters[1] = 'G'; + s.rows[1].letters[2] = 'H'; + s.rows[1].letters[3] = 'I'; + s.rows[1].letters[4] = 'J'; + + s.rows[2].letters[0] = 'K'; + s.rows[2].letters[1] = 'L'; + s.rows[2].letters[2] = 'M'; + s.rows[2].letters[3] = 'N'; + s.rows[2].letters[4] = 'O'; + + s.rows[3].letters[0] = 'P'; + s.rows[3].letters[1] = 'Q'; + s.rows[3].letters[2] = 'R'; + s.rows[3].letters[3] = 'S'; + s.rows[3].letters[4] = 'T'; + + s.rows[4].letters[0] = 'U'; + s.rows[4].letters[1] = 'V'; + s.rows[4].letters[2] = 'W'; + s.rows[4].letters[3] = 'X'; + s.rows[4].letters[4] = 'Y'; + + s.rows[5].letters[0] = 'Z'; + s.rows[5].letters[1] = '1'; + s.rows[5].letters[2] = '2'; + s.rows[5].letters[3] = '3'; + s.rows[5].letters[4] = '4'; + s.all_letters = 0; } diff --git a/wordle/wordle.hpp b/wordle/wordle.hpp index 2e6d777..ee9987c 100644 --- a/wordle/wordle.hpp +++ b/wordle/wordle.hpp @@ -28,4 +28,6 @@ struct screen { uint32_t all_letters; }; +void init_screen(struct screen& s, const uint8_t * word); + }