static void switch_font_render_line( video_frame_info_t *video_info, switch_font_t *font, const char *msg, unsigned msg_len, float scale, const unsigned int color, float pos_x, float pos_y, unsigned text_align) { int delta_x = 0; int delta_y = 0; unsigned fbWidth = 0; unsigned fbHeight = 0; uint32_t *out_buffer = (uint32_t *)gfxGetFramebuffer(&fbWidth, &fbHeight); if (out_buffer) { int x = roundf(pos_x * fbWidth); int y = roundf((1.0f - pos_y) * fbHeight); switch (text_align) { case TEXT_ALIGN_RIGHT: x -= switch_font_get_message_width(font, msg, msg_len, scale); break; case TEXT_ALIGN_CENTER: x -= switch_font_get_message_width(font, msg, msg_len, scale) / 2; break; } for (int i = 0; i < msg_len; i++) { int off_x, off_y, tex_x, tex_y, width, height; const char *msg_tmp = &msg[i]; unsigned code = utf8_walk(&msg_tmp); unsigned skip = msg_tmp - &msg[i]; if (skip > 1) i += skip - 1; const struct font_glyph *glyph = font->font_driver->get_glyph(font->font_data, code); if (!glyph) /* Do something smarter here ... */ glyph = font->font_driver->get_glyph(font->font_data, '?'); if (!glyph) continue; off_x = x + glyph->draw_offset_x + delta_x; off_y = y + glyph->draw_offset_y + delta_y; width = glyph->width; height = glyph->height; tex_x = glyph->atlas_offset_x; tex_y = glyph->atlas_offset_y; for (int y = tex_y; y < tex_y + height; y++) { uint8_t *row = &font->atlas->buffer[y * font->atlas->width]; for (int x = tex_x; x < tex_x + width; x++) { if (!row[x]) continue; int x1 = off_x + (x - tex_x); int y1 = off_y + (y - tex_y); if (x1 < fbWidth && y1 < fbHeight) out_buffer[gfxGetFramebufferDisplayOffset(x1, y1)] = color; } } delta_x += glyph->advance_x; delta_y += glyph->advance_y; } } }
int main (int argc, char *argv[]) { (void) argc; (void) argv; // init gfxInitDefault(); gfxSetMode(GfxMode_TiledDouble); // wide screen, keep aspect ratio gfxConfigureResolution(SCR_WIDTH + 136, SCR_HEIGHT); u32* gamebuf = (u32*) malloc(SCR_HEIGHT * SCR_WIDTH * sizeof(u32)); Game.InitSoundDriver(); Game.InitGame(); Game.LoadScores(); Game.StartGame(); int game_paused = 0; while(appletMainLoop()) { hidScanInput(); //1 Player input loop // Get Controller state JOYSTICK *jptr = &Game.m_GameTarget.m_Joy1; u32 keys_down = hidKeysDown(CONTROLLER_P1_AUTO); u32 keys_up = hidKeysUp(CONTROLLER_P1_AUTO); if (keys_down & KEY_PLUS) break; if (keys_down & KEY_LEFT) jptr->left = 1; if (keys_down & KEY_RIGHT) jptr->right = 1; if (keys_down & KEY_A) jptr->up = 1; if (keys_down & KEY_DOWN) jptr->down = 1; if (keys_down & KEY_B) jptr->fire = 1; if (keys_down & KEY_X) Game.m_GameTarget.m_Game.TogglePuffBlow(); if (keys_down & KEY_MINUS) game_paused ^= 1; if (keys_up & KEY_LEFT) jptr->left = 0; if (keys_up & KEY_RIGHT) jptr->right = 0; if (keys_up & KEY_A) jptr->up = 0; if (keys_up & KEY_DOWN) jptr->down = 0; if (keys_up & KEY_B) jptr->fire = 0; // Fake a key press (to pass getPlayerName screen) jptr->key = 13; // Execute game logic Game.MainLoop(gamebuf, game_paused); // Draw to screen, upscaling in hardware u32 *framebuf = (u32*) gfxGetFramebuffer(NULL, NULL); for (int y = 0; y < SCR_HEIGHT; y++) for (int x = 0; x < SCR_WIDTH; x++) framebuf[gfxGetFramebufferDisplayOffset(x + 68, y)] = gamebuf[y * SCR_WIDTH + x]; gfxFlushBuffers(); gfxSwapBuffers(); gfxWaitForVsync(); // Add a delay, FIXME: calculate this with: //u64 time_now = svcGetSystemTick(); svcSleepThread(40000000); } Game.SaveScores(); // save config here :) Game.RemoveSoundDriver(); // deinit free(gamebuf); gfxExit(); return 0; }