/*---------------------------------------------------------------------------* Project: TwlSDK - MB - demos - multiboot File: dispfunc.c Copyright 2006-2008 Nintendo. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Date:: 2008-09-18#$ $Rev: 8573 $ $Author: okubata_ryoma $ *---------------------------------------------------------------------------*/ #include #include #include "dispfunc.h" /* ================================================================================= OBJ character drawing ================================================================================= */ // --- global value GXOamAttr oamBak[128]; // --- constant value static const char NumString[] = "0123456789ABCDEF"; // Set OBJ void ObjSet(int objNo, int x, int y, int charNo, int paletteNo) { G2_SetOBJAttr((GXOamAttr *)&oamBak[objNo], x, y, 0, GX_OAM_MODE_NORMAL, FALSE, GX_OAM_EFFECT_NONE, GX_OAM_SHAPE_8x8, GX_OAM_COLOR_16, charNo, paletteNo, 0); } // Set OBJ character string void ObjSetString(int startobjNo, int x, int y, char *string, int paletteNo) { int i; for (i = 0; string[i] != 0 && i < 24; i++) { ObjSet(startobjNo + i, x + i * 8, y, (int)string[i], paletteNo); } } // Clears OBJ void ObjClear(int objNo) { ObjSet(objNo, 256 * 8, 192 * 8, 0, 0); } // Clears OBJ (specified range) void ObjClearRange(int start, int end) { int i; for (i = start; i <= end; i++) ObjClear(i); } // Set message void ObjSetMessage(int objNo, char *message) { ObjSetString(objNo, 4 * 8, 22 * 8, message, WHITE); } /* ================================================================================= BG character drawing (BG0 fixed) ================================================================================= */ #define BG_LINES (24) #define PROMPT ">" // --- static value static u16 vscr[32 * 32] ATTRIBUTE_ALIGN(32); // Virtual screen static u16 vscr_sub[32 * 32] ATTRIBUTE_ALIGN(32); // Virtual screen (sub) static u16 cur_line = 0; // --- static functions static void BgiPutChar(s16 x, s16 y, u8 palette, char c, u8 lcd); static void BgiPutStringN(s16 x, s16 y, u8 palette, char *text, u32 num, u8 lcd); static void BgiPutChar(s16 x, s16 y, u8 palette, char c, u8 lcd) { if (lcd) { vscr[((y * 32) + x) % (32 * 32)] = (u16)((palette << 12) | c); } else { vscr_sub[((y * 32) + x) % (32 * 32)] = (u16)((palette << 12) | c); } } static void BgiPutStringN(s16 x, s16 y, u8 palette, char *text, u32 num, u8 lcd) { s32 i; for (i = 0; i < num; i++) { if (text[i] == 0x00) { break; } BgiPutChar((s16)(x + i), y, palette, text[i], lcd); } } /* --- initialize */ void BgInitForPrintStr(void) { // Main lcd GX_SetBankForBG(GX_VRAM_BG_64_E); G2_SetBG0Control(GX_BG_SCRSIZE_TEXT_256x256, GX_BG_COLORMODE_16, GX_BG_SCRBASE_0xf000, // SCR base block 31 GX_BG_CHARBASE_0x00000, // CHR base block 0 GX_BG_EXTPLTT_01); G2_SetBG0Priority(0); G2_BG0Mosaic(FALSE); GX_SetGraphicsMode(GX_DISPMODE_GRAPHICS, GX_BGMODE_0, GX_BG0_AS_2D); GX_LoadBG0Char(sampleCharData, 0, sizeof(sampleCharData)); GX_LoadBGPltt(samplePlttData, 0, sizeof(samplePlttData)); MI_CpuFillFast((void *)vscr, 0, sizeof(vscr)); DC_FlushRange(vscr, sizeof(vscr)); /* I/O register is accessed using DMA operation, so cache wait is not needed */ // DC_WaitWriteBufferEmpty(); GX_LoadBG0Scr(vscr, 0, sizeof(vscr)); // Sub lcd GX_SetBankForSubBG(GX_VRAM_SUB_BG_128_C); G2S_SetBG0Control(GX_BG_SCRSIZE_TEXT_256x256, GX_BG_COLORMODE_16, GX_BG_SCRBASE_0xf800, // SCR base block 31 GX_BG_CHARBASE_0x10000, // CHR base block 0 GX_BG_EXTPLTT_01); G2S_SetBG0Priority(0); G2S_BG0Mosaic(FALSE); GXS_SetGraphicsMode(GX_BGMODE_0); GXS_LoadBG0Char(sampleCharData, 0, sizeof(sampleCharData)); GXS_LoadBGPltt(samplePlttData, 0, sizeof(samplePlttData)); MI_CpuFillFast((void *)vscr_sub, 0, sizeof(vscr_sub)); DC_FlushRange(vscr_sub, sizeof(vscr_sub)); /* I/O register is accessed using DMA operation, so cache wait is not needed */ // DC_WaitWriteBufferEmpty(); GXS_LoadBG0Scr(vscr_sub, 0, sizeof(vscr_sub)); cur_line = 0; } /* --- for main LCD */ // Formatted character string output void BgPrintf(s16 x, s16 y, u8 palette, char *text, ...) { va_list vlist; char temp[32 * 2 + 2]; MI_CpuClear8(&temp[0], sizeof(temp)); va_start(vlist, text); (void)OS_VSNPrintf(temp, 32 * 2 + 2, text, vlist); va_end(vlist); BgPutString(x, y, palette, temp); } // String output void BgPutString(s16 x, s16 y, u8 palette, char *text) { BgPutStringN(x, y, palette, text, 32); } // Character string output with the character number restriction void BgPutStringN(s16 x, s16 y, u8 palette, char *text, u32 num) { BgiPutStringN(x, y, palette, text, num, 1); } // 1 character output void BgPutChar(s16 x, s16 y, u8 palette, char c) { BgiPutChar(x, y, palette, c, 1); } // Clear BG void BgClear(void) { MI_CpuClearFast((void *)vscr, sizeof(vscr)); } /* --- for sub LCD */ // Formatted character string output void BgPrintfSub(s16 x, s16 y, u8 palette, char *text, ...) { va_list vlist; char temp[32 + 2]; MI_CpuClear8(&temp[0], sizeof(temp)); va_start(vlist, text); (void)OS_VSNPrintf(temp, 33, text, vlist); va_end(vlist); BgPutStringSub(x, y, palette, temp); } // String output void BgPutStringSub(s16 x, s16 y, u8 palette, char *text) { BgPutStringNSub(x, y, palette, text, 32); } // Character string output with the character number restriction void BgPutStringNSub(s16 x, s16 y, u8 palette, char *text, u32 num) { BgiPutStringN(x, y, palette, text, num, 0); } // 1 character output void BgPutCharSub(s16 x, s16 y, u8 palette, char c) { BgiPutChar(x, y, palette, c, 0); } // Clear BG void BgClearSub(void) { MI_CpuClearFast((void *)vscr_sub, sizeof(vscr_sub)); } /* --- v blank process */ void BgScrSetVblank(void) { // Reflect virtual screen in VRAM DC_FlushRange(vscr, sizeof(vscr)); /* I/O register is accessed using DMA operation, so cache wait is not needed */ // DC_WaitWriteBufferEmpty(); GX_LoadBG0Scr(vscr, 0, sizeof(vscr)); DC_FlushRange(vscr_sub, sizeof(vscr_sub)); /* I/O register is accessed using DMA operation, so cache wait is not needed */ // DC_WaitWriteBufferEmpty(); GXS_LoadBG0Scr(vscr_sub, 0, sizeof(vscr_sub)); } /* --- message print */ // Output message void BgSetMessage(u8 palette, char *message, ...) { va_list vlist; char temp[32 * 2 + 2]; MI_CpuClear8(&temp[0], sizeof(temp)); va_start(vlist, message); (void)OS_VSNPrintf(temp, 32 * 2 + 2, message, vlist); va_end(vlist); BgPutString(4, 22, palette, " "); BgPutString(4, 22, palette, temp); BgSetMessageLogSub(palette, temp); } void BgSetMessageSub(u8 palette, char *message, ...) { va_list vlist; char temp[32 + 2]; MI_CpuClear8(&temp[0], sizeof(temp)); va_start(vlist, message); (void)OS_VSNPrintf(temp, 33, message, vlist); va_end(vlist); BgSetMessageLogSub(palette, temp); } // Output message log on sub LCD void BgSetMessageLogSub(u8 palette, char *text) { if (cur_line == BG_LINES) { MI_CpuCopy16((void *)&vscr_sub[1 * 32], (void *)vscr_sub, sizeof(u16) * 32 * (BG_LINES - 1)); cur_line--; } BgPutStringSub(0, (s16)cur_line, palette, " "); BgPutStringSub(0, (s16)cur_line, palette, PROMPT); BgPutStringSub((s16)(1 + strlen(PROMPT)), (s16)cur_line, palette, text); if (cur_line < BG_LINES) cur_line++; } // Get main LCD screen buffer u16 *BgGetScreenBuf(void) { return (u16 *)vscr; } // Get sub LCD screen buffer u16 *BgGetScreenBufSub(void) { return (u16 *)vscr_sub; }