NitroSystem の textdemolib をごくごく一部改造して使っていたので、その周辺のソースも含める(たいしたサイズでもないので)

git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlToolsRED@275 7061adef-622a-194b-ae81-725974e89856
This commit is contained in:
yoshida_teruhisa 2009-05-20 02:45:18 +00:00
parent c1c52407cb
commit e69bf8e098
13 changed files with 1909 additions and 2 deletions

View File

@ -14,11 +14,11 @@
# $Revision$
#----------------------------------------------------------------------------
SUBDIRS = banner
SUBDIRS = banner textdemolib
NNS_USELIBS = g2d gfd fnd
G2D_TEXTDEMOLIB = $(NITROSYSTEM_ROOT)/build/demos/g2d/Text/textdemolib
G2D_TEXTDEMOLIB = ./textdemolib
LINCLUDES = $(G2D_TEXTDEMOLIB)/include
LLIBRARY_DIRS = $(G2D_TEXTDEMOLIB)/lib/$(NITRO_BUILDTYPE)

View File

@ -0,0 +1,43 @@
#! make -f
#----------------------------------------------------------------------------
# Project: NITRO-System - demos - g2d - Text - textdemolib
# File: Makefile
#
# Copyright 2004-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.
#
# $Revision$
#----------------------------------------------------------------------------
#----------------------------------------------------------------------------
SUBDIRS =
SRCS = cmn.c \
loader.c \
wprintf.c \
txt.c \
debug_txt.c \
TARGET_LIB = libg2d_textdemo.a
#SRCDIR = # using default
#LCFILE = # using default
#----------------------------------------------------------------------------
include $(NITROSYSTEM_ROOT)/build/buildtools/commondefs
do-build: $(TARGETS)
include $(NITROSYSTEM_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====

View File

@ -0,0 +1,34 @@
/*---------------------------------------------------------------------------*
Project: NITRO-System - demos - g2d - Text - textdemolib
File: g2d_textdemolib.h
Copyright 2004-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.
$Revision$
*---------------------------------------------------------------------------*/
#ifndef G2D_TEXTDEMOLIB_H_
#define G2D_TEXTDEMOLIB_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <nitro.h>
#include "g2d_textdemolib/cmn.h"
#include "g2d_textdemolib/txt.h"
#include "g2d_textdemolib/debug_txt.h"
#include "g2d_textdemolib/loader.h"
#include "g2d_textdemolib/wprintf.h"
#ifdef __cplusplus
}/* extern "C" */
#endif
// G2D_TEXTDEMOLIB_H_
#endif

View File

@ -0,0 +1,102 @@
/*---------------------------------------------------------------------------*
Project: NITRO-System - demos - g2d - Text - textdemolib - include - g2d_textdemolib
File: cmn.h
Copyright 2004-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.
$Revision$
*---------------------------------------------------------------------------*/
#ifndef CMN_H_
#define CMN_H_
#include <nitro/types.h>
#include <nitro/os/common/interrupt.h>
#include <nitro/os/common/arena.h>
#include <nitro/os/common/alloc.h>
#include <nnsys/fnd/allocator.h>
#include <nnsys/fnd/archive.h>
#ifdef __cplusplus
extern "C" {
#endif
#define ARY_SIZEOF(ary) ( sizeof(ary) / sizeof( (ary)[0] ) )
#define ROUNDUP_DIV(a, b) (( (a) + ((b) - 1) ) / (b))
const static float ONE_FRAME_US = 16715.1; // 1フレームは 16715.1 us
const static float ONE_VBLANK_US = 4512.4; // Vブランク期間は 4512.4 us
typedef struct CMNGamePad
{
u16 trigger;
u16 release;
u16 button;
}
CMNGamePad;
extern CMNGamePad CMNGamePadState;
void CMN_InitInterrupt( void );
void CMN_BeginVBlankIntr( OSIrqFunction vBlankFunc );
void CMN_InitAllocator( NNSFndAllocator* pAllocator );
void CMN_InitFileSystem( NNSFndAllocator* pAllocator );
void CMN_ClearVram( void );
void CMN_ReadGamePad(void);
u32 CMN_LoadFile(void** ppFile, const char* fpath, NNSFndAllocator* pAlloc);
void CMN_UnloadFile(void* pFile, NNSFndAllocator* pAlloc);
NNSFndArchive* CMN_LoadArchive(const char* name, const char* path, NNSFndAllocator* pAllocator);
void CMN_RemoveArchive(NNSFndArchive* archive, NNSFndAllocator* pAllocator);
static inline u16 CMN_IsTrigger(u16 key)
{
return (u16)(CMNGamePadState.trigger & key);
}
static inline u16 CMN_IsRelease(u16 key)
{
return (u16)(CMNGamePadState.release & key);
}
static inline u16 CMN_IsPress(u16 key)
{
return (u16)(CMNGamePadState.button & key);
}
static inline void CMN_WaitVBlankIntr(void)
{
OS_WaitIrq(TRUE, OS_IE_V_BLANK);
}
static inline void CMN_SetPlaneVisible(GXPlaneMask plane)
{
GX_SetVisiblePlane(GX_GetVisiblePlane() | plane);
}
static inline void CMN_SetPlaneInvisible(GXPlaneMask plane)
{
GX_SetVisiblePlane(GX_GetVisiblePlane() & ~plane);
}
#ifdef __cplusplus
}/* extern "C" */
#endif
#endif // CMN_H_

View File

@ -0,0 +1,37 @@
/*---------------------------------------------------------------------------*
Project: NITRO-System - demos - g2d - Text - textdemolib - include - g2d_textdemolib
File: debug_txt.h
Copyright 2004-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.
$Revision$
*---------------------------------------------------------------------------*/
#ifndef DEBUG_TXT_H_
#define DEBUG_TXT_H_
#include <nnsys/g2d/g2d_Font.h>
#ifdef __cplusplus
extern "C" {
#endif
#define DEBUG_FONTRESOURCE_NAME "/data/fontd.NFTR"
void DTX_Init(void);
void DTX_Reflect(void);
void DTX_Print( int x, int y, const char* str );
void DTX_PrintLine( const char* fmt, ... );
#ifdef __cplusplus
}/* extern "C" */
#endif
#endif // DEBUG_TXT_H_

View File

@ -0,0 +1,47 @@
/*---------------------------------------------------------------------------*
Project: NITRO-System - demos - g2d - Text - textdemolib - include - g2d_textdemolib
File: loader.h
Copyright 2004-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.
$Revision$
*---------------------------------------------------------------------------*/
#ifndef LOAD_H_
#define LOAD_H_
#include <nnsys/fnd.h>
#include <nnsys/g2d.h>
#include <nnsys/g2d/g2d_Font.h>
#include <nnsys/g2d/load/g2d_NFT_load.h>
#ifdef __cplusplus
extern "C" {
#endif
void* LoadNCER( NNSG2dCellDataBank** ppCellBank, const char* pFname, NNSFndAllocator* pAllocator );
void* LoadNANR( NNSG2dAnimBankData** ppAnimBank, const char* pFname, NNSFndAllocator* pAllocator );
void* LoadNMCR( NNSG2dMultiCellDataBank** ppMCBank, const char* pFname, NNSFndAllocator* pAllocator );
void* LoadNMAR( NNSG2dMultiCellAnimBankData** ppMCABank, const char* pFname, NNSFndAllocator* pAllocator );
void* LoadNCGR( NNSG2dCharacterData** ppCharData, const char* pFname, NNSFndAllocator* pAllocator );
void* LoadNCLR( NNSG2dPaletteData** ppPltData, const char* pFname, NNSFndAllocator* pAllocator );
void* LoadNENR( NNSG2dEntityDataBank** ppEntityBank, const char* pFname, NNSFndAllocator* pAllocator );
void* LoadNCBR( NNSG2dCharacterData** ppCharData, const char* pFname, NNSFndAllocator* pAllocator );
void* LoadNSCR( NNSG2dScreenData** ppScrData, const char* pFname, NNSFndAllocator* pAllocator );
void* LoadNCGRforBG( NNSG2dCharacterData** ppCharData, const char* pFname, NNSFndAllocator* pAllocator );
void* LoadNFTR( NNSG2dFont* pFont, const char* pFname, NNSFndAllocator* pAllocator );
#ifdef __cplusplus
}/* extern "C" */
#endif
#endif // LOAD_H_

View File

@ -0,0 +1,211 @@
/*---------------------------------------------------------------------------*
Project: NITRO-System - demos - g2d - Text - textdemolib - include - g2d_textdemolib
File: txt.h
Copyright 2004-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.
$Revision$
*---------------------------------------------------------------------------*/
#ifndef TEXT_H_
#define TEXT_H_
#include <nnsys/g2d/g2d_Font.h>
#ifdef __cplusplus
extern "C" {
#endif
// DrawText での左上寄せ
#define TXT_DRAWTEXT_FLAG_DEFAULT (NNS_G2D_VERTICALORIGIN_TOP | NNS_G2D_HORIZONTALORIGIN_LEFT | NNS_G2D_HORIZONTALALIGN_LEFT)
// デモ用フォントリソース名
#define TXT_FONTRESOURCE_NAME "/data/fonts.NFTR"
#define TXT_SJIS_FONTRESOURCE_NAME "/data/fonts.NFTR"
#define TXT_UTF8_FONTRESOURCE_NAME "/data/fontu8.NFTR"
#define TXT_UTF16_FONTRESOURCE_NAME "/data/fontu16.NFTR"
#define TXT_CP1252_FONTRESOURCE_NAME "/data/font1252.NFTR"
// TXTColorPalette の色名 16色パレットへのロードを想定
enum
{
// パレット0 TXT_CPALETTE_MAIN
TXT_COLOR_NULL=0,
TXT_COLOR_WHITE,
TXT_COLOR_BLACK,
TXT_COLOR_RED,
TXT_COLOR_GREEN,
TXT_COLOR_BLUE,
TXT_COLOR_CYAN,
TXT_COLOR_MAGENTA,
TXT_COLOR_YELLOW,
// パレット1 TXT_CPALETTE_USERCOLOR
TXT_UCOLOR_NULL=0,
TXT_UCOLOR_GRAY,
TXT_UCOLOR_BROWN,
TXT_UCOLOR_RED,
TXT_UCOLOR_PINK,
TXT_UCOLOR_ORANGE,
TXT_UCOLOR_YELLOW,
TXT_UCOLOR_LIMEGREEN,
TXT_UCOLOR_DARKGREEN,
TXT_UCOLOR_SEAGREEN,
TXT_UCOLOR_TURQUOISE,
TXT_UCOLOR_BLUE,
TXT_UCOLOR_DARKBLUE,
TXT_UCOLOR_PURPLE,
TXT_UCOLOR_VIOLET,
TXT_UCOLOR_MAGENTA,
// パレット TXT_CPALETTE_4BPP
TXT_COLOR_4BPP_NULL=0,
TXT_COLOR_4BPP_BG=1,
TXT_COLOR_4BPP_TEXT=1
};
// TXTColorPalette のパレット名 16色パレットへのロードを想定
enum
{
TXT_CPALETTE_MAIN,
TXT_CPALETTE_USERCOLOR,
TXT_CPALETTE_4BPP,
TXT_NUM_CPALEETE
};
// 共通カラーパレットデータ
extern GXRgb TXTColorPalette[TXT_NUM_CPALEETE * 16];
//****************************************************************************
//
//****************************************************************************
/*---------------------------------------------------------------------------*
Name: TXT_Init
Description:
Arguments:
Returns:
*---------------------------------------------------------------------------*/
void TXT_Init(void);
/*---------------------------------------------------------------------------*
Name: TXT_SetupBackground
Description: BG0に背景画像をロード
Arguments:
Returns:
*---------------------------------------------------------------------------*/
void TXT_SetupBackground( void );
/*---------------------------------------------------------------------------*
Name: TXT_Alloc
Description:
Arguments: size:
Returns:
*---------------------------------------------------------------------------*/
void* TXT_Alloc(u32 size);
/*---------------------------------------------------------------------------*
Name: TXT_Free
Description: TXT_Alloc()
Arguments: ptr:
Returns:
*---------------------------------------------------------------------------*/
void TXT_Free(void* ptr);
/*---------------------------------------------------------------------------*
Name: TXT_SetCharCanvasOBJAttrs
Description: OAMのNNS_G2dArrangeOBJ*
Arguments: oam: OAM
num: OAM
priority: (03)
mode: OBJモード
mosaic:
effect:
cParam:
rsParam:
Returns:
*---------------------------------------------------------------------------*/
void TXT_SetCharCanvasOBJAttrs(
GXOamAttr * oam,
int num,
int priority,
GXOamMode mode,
BOOL mosaic,
GXOamEffect effect,
int cParam,
int rsParam
);
/*---------------------------------------------------------------------------*
Name: TXT_LoadFont
Description:
Arguments: pFname:
Returns:
*---------------------------------------------------------------------------*/
void* TXT_LoadFont( NNSG2dFont* pFont, const char* pFname );
void TXT_UnloadFont( void* pFile );
/*---------------------------------------------------------------------------*
Name: TXT_LoadFile
Description:
Arguments: ppFile:
fpath:
Returns:
0
*ppFile
*---------------------------------------------------------------------------*/
u32 TXT_LoadFile(void** ppFile, const char* fpath);
#ifdef __cplusplus
}/* extern "C" */
#endif
#endif // TEXT_H_

View File

@ -0,0 +1,98 @@
/*---------------------------------------------------------------------------*
Project: NITRO-System - demos - g2d - Text - textdemolib - include - g2d_textdemolib
File: wprintf.h
Copyright 2004-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.
$Revision$
*---------------------------------------------------------------------------*/
#ifndef WPRINTF_H_
#define WPRINTF_H_
#ifdef __cplusplus
extern "C" {
#endif
int NNSi_G2dVSNWPrintf(wchar_t *dst, size_t len, const wchar_t *fmt, va_list vlist);
/*---------------------------------------------------------------------------*
Name: OS_SNPrintf
Description: equal to 'OS_VSNPrintf' except argument style.
Arguments: dst : destination buffer.
len : destination buffer size.
fmt : format string.
Returns: length of the generated string. (except '\0')
if(result < len),
put NUL in dst[result].
else if(len > 0),
put NUL in dst[len - 1].
else,
do nothing.
*---------------------------------------------------------------------------*/
static inline int NNSi_G2dSNWPrintf(wchar_t *dst, size_t len, const wchar_t *fmt, ...)
{
int ret;
va_list va;
va_start(va, fmt);
ret = NNSi_G2dVSNWPrintf(dst, len, fmt, va);
va_end(va);
return ret;
}
/*---------------------------------------------------------------------------*
Name: OS_VSPrintf
Description: equal to 'OS_VSNPrintf' except buffer size argument.
Arguments: dst : destination buffer.
fmt : format string.
vlist : parameters.
Returns: length of the generated string.
*---------------------------------------------------------------------------*/
static inline int NNSi_G2dVSWPrintf(wchar_t *dst, const wchar_t *fmt, va_list vlist)
{
return NNSi_G2dVSNWPrintf(dst, 0x7FFFFFFF, fmt, vlist);
}
/*---------------------------------------------------------------------------*
Name: OS_SPrintf
Description: equal to 'OS_VSPrintf' except argument style.
Arguments: dst : destination buffer.
fmt : format string.
Returns: length of the generated string.
*---------------------------------------------------------------------------*/
static inline int NNSi_G2dSWPrintf(wchar_t *dst, const wchar_t *fmt, ...)
{
int ret;
va_list va;
va_start(va, fmt);
ret = NNSi_G2dVSWPrintf(dst, fmt, va);
va_end(va);
return ret;
}
#ifdef __cplusplus
}/* extern "C" */
#endif
#endif // WPRINTF_H_

View File

@ -0,0 +1,340 @@
/*---------------------------------------------------------------------------*
Project: NITRO-System - demos - g2d - Text - textdemolib
File: cmn.c
Copyright 2004-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.
$Revision$
*---------------------------------------------------------------------------*/
#include <nitro.h>
#include "g2d_textdemolib.h"
// ゲームパッド
CMNGamePad CMNGamePadState;
/*---------------------------------------------------------------------------*
Name: CMN_InitInterrupt
Description:
Arguments:
Returns:
*---------------------------------------------------------------------------*/
void CMN_InitInterrupt( void )
{
// 個別割り込みフラグを全て不許可に
(void)OS_SetIrqMask(0);
// マスター割り込みフラグを許可に
(void)OS_EnableIrq();
}
/*---------------------------------------------------------------------------*
Name: CMN_BeginVBlankIntr
Description: Vブランク割り込みの発生を開始します
Arguments: vBlankFunc: Vブランク割り込みハンドラへのポインタ
Returns:
*---------------------------------------------------------------------------*/
void CMN_BeginVBlankIntr( OSIrqFunction vBlankFunc )
{
// 割り込みハンドラ登録
OS_SetIrqFunction(OS_IE_V_BLANK, vBlankFunc);
// VBlank割り込み許可
(void)OS_EnableIrqMask( OS_IE_V_BLANK );
// VBlank割り込み生成開始
(void)GX_VBlankIntr(TRUE);
}
/*---------------------------------------------------------------------------*
Name: CMN_InitAllocator
Description:
Arguments: pAllocator:
Returns:
*---------------------------------------------------------------------------*/
void CMN_InitAllocator( NNSFndAllocator* pAllocator )
{
u32 arenaLow = MATH_ROUNDUP ((u32)OS_GetMainArenaLo(), 16);
u32 arenaHigh = MATH_ROUNDDOWN((u32)OS_GetMainArenaHi(), 16);
u32 heapSize = arenaHigh - arenaLow;
void* heapMemory = OS_AllocFromMainArenaLo(heapSize, 16);
NNSFndHeapHandle heapHandle;
SDK_NULL_ASSERT( pAllocator );
heapHandle = NNS_FndCreateExpHeap(heapMemory, heapSize);
SDK_ASSERT( heapHandle != NNS_FND_HEAP_INVALID_HANDLE );
NNS_FndInitAllocatorForExpHeap(pAllocator, heapHandle, 4);
}
/*---------------------------------------------------------------------------*
Name: CMN_InitFileSystem
Description:
Arguments: pAllocator:
Returns:
*---------------------------------------------------------------------------*/
// ファイルシステム準備
void CMN_InitFileSystem( NNSFndAllocator* pAllocator )
{
SDK_NULL_ASSERT( pAllocator );
// ARM7との通信FIFO割り込み許可
(void)OS_EnableIrqMask(OS_IE_SPFIFO_RECV);
// ファイルシステム初期化
FS_Init( FS_DMA_NOT_USE );
// ファイルテーブルキャッシュ
if( pAllocator != NULL )
{
const u32 need_size = FS_GetTableSize();
void *p_table = NNS_FndAllocFromAllocator( pAllocator, need_size );
SDK_ASSERT(p_table != NULL);
(void)FS_LoadTable(p_table, need_size);
}
}
/*---------------------------------------------------------------------------*
Name: CMN_ClearVram
Description: VRAM
VRAM
Arguments:
Returns:
*---------------------------------------------------------------------------*/
// VRAMクリア
void CMN_ClearVram( void )
{
//---------------------------------------------------------------------------
// All VRAM banks to LCDC
//---------------------------------------------------------------------------
GX_SetBankForLCDC(GX_VRAM_LCDC_ALL);
//---------------------------------------------------------------------------
// Clear all LCDC space
//---------------------------------------------------------------------------
MI_CpuClearFast((void *)HW_LCDC_VRAM, HW_LCDC_VRAM_SIZE);
//---------------------------------------------------------------------------
// Disable the banks on LCDC
//---------------------------------------------------------------------------
(void)GX_DisableBankForLCDC();
MI_CpuFillFast((void *)HW_OAM, 192, HW_OAM_SIZE); // clear OAM
MI_CpuClearFast((void *)HW_PLTT, HW_PLTT_SIZE); // clear the standard palette
MI_CpuFillFast((void*)HW_DB_OAM, 192, HW_DB_OAM_SIZE); // clear OAM
MI_CpuClearFast((void *)HW_DB_PLTT, HW_DB_PLTT_SIZE); // clear the standard palette
}
/*---------------------------------------------------------------------------*
Name: CMN_ReadGamePad
Description:
Arguments:
Returns:
*---------------------------------------------------------------------------*/
void CMN_ReadGamePad(void)
{
u16 status = PAD_Read();
CMNGamePadState.trigger = (u16)(status & (status ^ CMNGamePadState.button));
CMNGamePadState.release = (u16)(CMNGamePadState.button & (status ^ CMNGamePadState.button));
CMNGamePadState.button = status;
}
/*---------------------------------------------------------------------------*
Name: CMN_LoadFile
Description:
CMN_UnloadFile( *ppFile, pAlloc )
Arguments: ppFile:
fpath:
pAlloc:
Returns:
0
*ppFile
*---------------------------------------------------------------------------*/
u32 CMN_LoadFile(void** ppFile, const char* fpath, NNSFndAllocator* pAlloc)
{
BOOL bSuccess;
FSFile f;
u32 length;
u32 read;
SDK_NULL_ASSERT( ppFile );
SDK_NULL_ASSERT( fpath );
SDK_NULL_ASSERT( pAlloc );
FS_InitFile(&f);
bSuccess = FS_OpenFile(&f, fpath);
if( ! bSuccess )
{
OS_Warning("file (%s) not found", fpath);
return 0;
}
length = FS_GetLength(&f);
*ppFile = NNS_FndAllocFromAllocator(pAlloc, length);
if( *ppFile == NULL )
{
OS_Warning("cant allocate memory for file: %s", fpath);
return 0;
}
read = (u32)FS_ReadFile(&f, *ppFile, (s32)length);
if( read != length )
{
OS_Warning("fail to load file: %s", fpath);
NNS_FndFreeToAllocator(pAlloc, *ppFile);
return 0;
}
bSuccess = FS_CloseFile(&f);
if( ! bSuccess )
{
OS_Warning("fail to close file: %s", fpath);
}
return length;
}
/*---------------------------------------------------------------------------*
Name: CMN_UnloadFile
Description:
Arguments: pFile:
pAlloc:
Returns:
*---------------------------------------------------------------------------*/
void CMN_UnloadFile(void* pFile, NNSFndAllocator* pAlloc)
{
NNS_FndFreeToAllocator(pAlloc, pFile);
}
/*---------------------------------------------------------------------------*
Name: CMN_LoadArchive
Description:
CMN_RemoveArchive( , pAllocator )
Arguments: name:
path:
pAllocator:
Returns: NNSFndArchive
NULLを返します
*---------------------------------------------------------------------------*/
NNSFndArchive*
CMN_LoadArchive(const char* name, const char* path, NNSFndAllocator* pAllocator)
{
FSFile file;
NNSFndArchive* archive = NULL;
SDK_NULL_ASSERT(name);
SDK_NULL_ASSERT(path);
SDK_NULL_ASSERT(pAllocator);
FS_InitFile(&file);
if (FS_OpenFile(&file, path))
{
u32 binarySize = FS_GetLength(&file);
u32 memorySize = MATH_ROUNDUP(sizeof(NNSFndArchive), 16) + MATH_ROUNDUP(binarySize, 16);
u8* memory = (u8*)NNS_FndAllocFromAllocator(pAllocator, memorySize);
if (memory != NULL)
{
u8* binary = memory + MATH_ROUNDUP(sizeof(NNSFndArchive), 16);
if ((u32)FS_ReadFile(&file, binary, (s32)binarySize) == binarySize)
{
if (NNS_FndMountArchive((NNSFndArchive*)memory, name, binary))
{
archive = (NNSFndArchive*)memory;
}
}
}
(void)FS_CloseFile(&file);
}
return archive;
}
/*---------------------------------------------------------------------------*
Name: CMN_RemoveArchive
Description:
Arguments: archive: NNSアーカイブ構造体へのポインタ
pAllocator:
Returns:
*---------------------------------------------------------------------------*/
void
CMN_RemoveArchive(NNSFndArchive* archive, NNSFndAllocator* pAllocator)
{
SDK_NULL_ASSERT(archive);
SDK_NULL_ASSERT(pAllocator);
(void)NNS_FndUnmountArchive(archive);
NNS_FndFreeToAllocator(pAllocator, archive);
}

View File

@ -0,0 +1,163 @@
/*---------------------------------------------------------------------------*
Project: NITRO-System - demos - g2d - Text - textdemolib
File: debug_txt.c
Copyright 2004-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.
$Revision$
*---------------------------------------------------------------------------*/
#include "g2d_textdemolib.h"
#include <nnsys/g2d/g2d_TextCanvas.h>
#define DEBUG_CANVAS_WIDTH 32
#define DEBUG_CANVAS_HEIGHT 24
#define DEBUG_CANVAS_LEFT 0
#define DEBUG_CANVAS_TOP 0
#define DEBUG_CANVAS_HSPACE 1
#define DEBUG_CANVAS_VSPACE 1
#define LINEOFFSET_X 1
#define LINEOFFSET_Y 1
#define DEBUG_CHARACTER_OFFSET 0
static NNSG2dTextCanvas sDebugTextCanvas;
static NNSG2dCharCanvas sDebugCanvas;
static GXCharFmt16 sDebugOffBuffer[DEBUG_CANVAS_HEIGHT][DEBUG_CANVAS_WIDTH];
static NNSG2dFont sDebugFont;
static int sCurrentLine = 0;
static BOOL sbUpdated = FALSE;
//****************************************************************************
//
//****************************************************************************
static void ResetOffScreen(void)
{
NNS_G2dCharCanvasClear(&sDebugCanvas, 0);
sCurrentLine = 0;
sbUpdated = FALSE;
}
//****************************************************************************
//
//****************************************************************************
void DTX_Init(void)
{
static GXRgb bgColorPlt[] =
{
GX_RGB(31, 31, 31), GX_RGB(0, 0, 0)
};
TXT_LoadFont( &sDebugFont, DEBUG_FONTRESOURCE_NAME );
GXS_SetGraphicsMode(GX_BGMODE_0);
GXS_SetVisiblePlane(GX_PLANEMASK_BG0);
G2S_SetBG0Control(
GX_BG_SCRSIZE_TEXT_256x256,
GX_BG_COLORMODE_16,
GX_BG_SCRBASE_0x7800,
GX_BG_CHARBASE_0x00000,
GX_BG_EXTPLTT_01
);
GXS_LoadBGPltt(bgColorPlt, 0, sizeof(bgColorPlt));
NNS_G2dCharCanvasInitForBG(
&sDebugCanvas,
*sDebugOffBuffer,
DEBUG_CANVAS_WIDTH,
DEBUG_CANVAS_HEIGHT,
NNS_G2D_CHARA_COLORMODE_16
);
NNS_G2dTextCanvasInit(
&sDebugTextCanvas,
&sDebugCanvas,
&sDebugFont,
DEBUG_CANVAS_HSPACE,
DEBUG_CANVAS_VSPACE
);
NNS_G2dMapScrToCharText(
G2S_GetBG0ScrPtr(),
DEBUG_CANVAS_WIDTH,
DEBUG_CANVAS_HEIGHT,
DEBUG_CANVAS_LEFT,
DEBUG_CANVAS_TOP,
NNS_G2D_TEXT_BG_WIDTH_256,
DEBUG_CHARACTER_OFFSET,
0
);
ResetOffScreen();
}
//****************************************************************************
//
//****************************************************************************
void DTX_Reflect(void)
{
if( sbUpdated )
{
DC_StoreRange(sDebugOffBuffer, sizeof(sDebugOffBuffer));
GXS_LoadBG0Char(
sDebugOffBuffer,
sizeof(GXCharFmt16) * DEBUG_CHARACTER_OFFSET,
sizeof(sDebugOffBuffer)
);
ResetOffScreen();
}
}
void DTX_Print( int x, int y, const char* str )
{
NNS_G2dTextCanvasDrawText(
&sDebugTextCanvas,
x, y, 1,
NNS_G2D_VERTICALORIGIN_TOP | NNS_G2D_HORIZONTALORIGIN_LEFT | NNS_G2D_HORIZONTALALIGN_LEFT,
str
);
sbUpdated = TRUE;
}
void DTX_PrintLine( const char* fmt, ... )
{
const int y = sCurrentLine * (NNS_G2dFontGetHeight(&sDebugFont) + NNS_G2dTextCanvasGetVSpace(&sDebugTextCanvas)) + LINEOFFSET_Y;
char buf[1024];
const char* pos;
va_list vlist;
va_start( vlist, fmt );
(void)OS_VSNPrintf(buf, sizeof(buf), fmt, vlist);
va_end( vlist );
DTX_Print( LINEOFFSET_X, y, buf );
for( pos = buf; *pos != '\0'; pos++ )
{
if( *pos == '\n' )
{
sCurrentLine++;
}
}
sCurrentLine++;
sbUpdated = TRUE;
}

View File

@ -0,0 +1,142 @@
/*---------------------------------------------------------------------------*
Project: NITRO-System - demos - g2d - Text - textdemolib
File: loader.c
Copyright 2004-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.
$Revision$
*---------------------------------------------------------------------------*/
#include <nitro.h>
#include <nnsys/g2d/g2d_Font.h>
#include "g2d_textdemolib.h"
#define LoadXXXX(ppData, pFname, pAlloc, unpack, print) \
void* pFile = NULL; \
\
SDK_NULL_ASSERT( ppData ); \
SDK_NULL_ASSERT( pFname ); \
\
pFile = LoadFileToMainMem_( pFname, pAlloc ); \
if( pFile != NULL ) \
{ \
if( unpack( pFile, ppData ) ) \
{ \
print( *ppData ); \
return pFile; \
} \
\
NNS_FndFreeToAllocator( pAlloc, pFile ); \
} \
\
return NULL; \
static void* LoadFileToMainMem_( const char* pFname, NNSFndAllocator* pAllocator )
{
FSFile file;
void* pFile = NULL;
BOOL bSuccess;
SDK_NULL_ASSERT( pFname );
FS_InitFile( &file );
bSuccess = FS_OpenFile( &file, pFname );
if( bSuccess )
{
const u32 szFile = FS_GetLength( &file );
pFile = NNS_FndAllocFromAllocator( pAllocator, szFile );
SDK_NULL_ASSERT( pFile );
if( szFile != (u32)FS_ReadFile( &file, pFile, (s32)szFile ) )
{
NNS_FndFreeToAllocator( pAllocator, pFile );
pFile = NULL;
}
bSuccess = FS_CloseFile( &file );
SDK_ASSERT( bSuccess );
}else{
OS_Warning(" Can't find the file : %s ", pFname );
}
return pFile;
}
void* LoadNCER( NNSG2dCellDataBank** ppData, const char* pFname, NNSFndAllocator* pAllocator )
{
LoadXXXX(ppData, pFname, pAllocator, NNS_G2dGetUnpackedCellBank, NNS_G2dPrintCellBank );
}
void* LoadNANR( NNSG2dAnimBankData** ppData, const char* pFname, NNSFndAllocator* pAllocator )
{
LoadXXXX(ppData, pFname, pAllocator, NNS_G2dGetUnpackedAnimBank, NNS_G2dPrintAnimBank);
}
void* LoadNMCR( NNSG2dMultiCellDataBank** ppData, const char* pFname, NNSFndAllocator* pAllocator )
{
LoadXXXX(ppData, pFname, pAllocator, NNS_G2dGetUnpackedMultiCellBank, NNS_G2dPrintMultiCellBank );
}
void* LoadNMAR( NNSG2dMultiCellAnimBankData** ppData, const char* pFname, NNSFndAllocator* pAllocator )
{
LoadXXXX(ppData, pFname, pAllocator, NNS_G2dGetUnpackedMCAnimBank, NNS_G2dPrintAnimBank);
}
void* LoadNCGR( NNSG2dCharacterData** ppData, const char* pFname, NNSFndAllocator* pAllocator )
{
LoadXXXX(ppData, pFname, pAllocator, NNS_G2dGetUnpackedCharacterData, NNS_G2dPrintCharacterData );
}
void* LoadNCLR( NNSG2dPaletteData** ppData, const char* pFname, NNSFndAllocator* pAllocator )
{
LoadXXXX(ppData, pFname, pAllocator, NNS_G2dGetUnpackedPaletteData, NNS_G2dPrintPaletteData );
}
void* LoadNENR( NNSG2dEntityDataBank** ppData, const char* pFname, NNSFndAllocator* pAllocator )
{
LoadXXXX(ppData, pFname, pAllocator, NNS_G2dGetUnpackedEntityBank, NNS_G2dPrintEntityDataBank );
}
void* LoadNCBR( NNSG2dCharacterData** ppData, const char* pFname, NNSFndAllocator* pAllocator )
{
LoadXXXX(ppData, pFname, pAllocator, NNS_G2dGetUnpackedCharacterData, NNS_G2dPrintCharacterData );
}
void* LoadNSCR( NNSG2dScreenData** ppScrData, const char* pFname, NNSFndAllocator* pAllocator )
{
LoadXXXX(ppScrData, pFname, pAllocator, NNS_G2dGetUnpackedScreenData, NNS_G2dPrintScreenData);
}
void* LoadNCGRforBG( NNSG2dCharacterData** ppCharData, const char* pFname, NNSFndAllocator* pAllocator )
{
LoadXXXX(ppCharData, pFname, pAllocator, NNS_G2dGetUnpackedBGCharacterData, NNS_G2dPrintCharacterData);
}
void* LoadNFTR( NNSG2dFont* pFont, const char* pFname, NNSFndAllocator* pAllocator )
{
void* pFile = NULL;
SDK_NULL_ASSERT( pFont );
SDK_NULL_ASSERT( pFname );
pFile = LoadFileToMainMem_( pFname, pAllocator );
if( pFile != NULL )
{
NNS_G2dFontInitAuto(pFont, pFile);
NNS_G2dPrintFont(pFont);
return pFile;
}
return NULL;
}

View File

@ -0,0 +1,320 @@
/*---------------------------------------------------------------------------*
Project: NITRO-System - demos - g2d - Text - textdemolib
File: txt.c
Copyright 2004-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.
$Revision$
*---------------------------------------------------------------------------*/
#include "g2d_textdemolib.h"
static NNSFndAllocator sAllocator;
#define GRAY(x) GX_RGB(x, x, x)
// デモ共通のカラーパレット
GXRgb TXTColorPalette[TXT_NUM_CPALEETE * 16] =
{
GX_RGB( 0, 0, 0), GX_RGB(31, 31, 31), GX_RGB( 0, 0, 0), GX_RGB(31, 0, 0),
GX_RGB( 0, 31, 0), GX_RGB( 0, 0, 31), GX_RGB( 0, 31, 31), GX_RGB(31, 0, 31),
GX_RGB(31, 31, 0), GX_RGB( 0, 0, 0), GX_RGB( 0, 0, 0), GX_RGB( 0, 0, 0),
GX_RGB( 0, 0, 0), GX_RGB( 0, 0, 0), GX_RGB( 0, 0, 0), GX_RGB( 0, 0, 0),
GX_RGB( 0, 0, 0), GX_RGB(12, 16, 19), GX_RGB(23, 9, 0), GX_RGB(31, 0, 3),
GX_RGB(31, 17, 31), GX_RGB(31, 18, 0), GX_RGB(30, 28, 0), GX_RGB(21, 31, 0),
GX_RGB( 0, 20, 7), GX_RGB( 9, 27, 17), GX_RGB( 6, 23, 30), GX_RGB( 0, 11, 30),
GX_RGB( 0, 0, 18), GX_RGB(17, 0, 26), GX_RGB(26, 0, 29), GX_RGB(31, 0, 18),
GRAY(31), GRAY(29), GRAY(27), GRAY(25),
GRAY(23), GRAY(21), GRAY(19), GRAY(17),
GRAY(15), GRAY(14), GRAY(12), GRAY(10),
GRAY( 8), GRAY( 6), GRAY( 3), GRAY( 0),
};
//****************************************************************************
//
//****************************************************************************
/*---------------------------------------------------------------------------*
Name: AssignVramBanks
Description: VRAMの割り当てを行います
A B C D E F G H I
2DA BG o o 256 KB
OBJ o o 256 KB
2DB BG o 32 KB
OBJ
使 o o o o 112 KB
Arguments:
Returns:
*---------------------------------------------------------------------------*/
static void AssignVramBanks( void )
{
GX_SetBankForBG(GX_VRAM_BG_256_CD);
GX_SetBankForOBJ(GX_VRAM_OBJ_256_AB);
GX_SetBankForSubBG(GX_VRAM_SUB_BG_32_H);
}
/*---------------------------------------------------------------------------*
Name: VBlankIntr
Description: Vブランク割り込みを処理します
Arguments:
Returns:
*---------------------------------------------------------------------------*/
static void VBlankIntr(void)
{
OS_SetIrqCheckFlag( OS_IE_V_BLANK ); // checking VBlank interrupt
}
//****************************************************************************
//
//****************************************************************************
/*---------------------------------------------------------------------------*
Name: TXT_Init
Description:
VRAM初期化
VRAM割り当て
BGメモリオフセット設定
BG
BGモード4
BG0
BG1
BG2
BG3
OBJ
BG VRAM 256 KB
00000- 192 KB
30000- 30 KB
37800- 2 KB
38000- 32 KB
OBJ VRAM 256 KB
00000- 256 KB
BGモード0
BG0
BG1 使
BG2 使
BG3 使
Arguments:
Returns:
*---------------------------------------------------------------------------*/
void TXT_Init(void)
{
// Common initialization.
{
OS_Init();
FX_Init();
GX_Init();
GX_DispOff();
GXS_DispOff();
}
{
CMN_InitInterrupt();
CMN_BeginVBlankIntr(VBlankIntr);
CMN_ClearVram();
CMN_InitAllocator( &sAllocator );
CMN_InitFileSystem( &sAllocator );
}
AssignVramBanks();
GX_SetGraphicsMode(GX_DISPMODE_GRAPHICS, GX_BGMODE_4, GX_BG0_AS_2D);
GX_SetBGScrOffset(GX_BGSCROFFSET_0x30000);
GX_SetBGCharOffset(GX_BGCHAROFFSET_0x00000);
DTX_Init();
}
/*---------------------------------------------------------------------------*
Name: TXT_SetupBackground
Description: BG0に背景画像をロード
Arguments:
Returns:
*---------------------------------------------------------------------------*/
void TXT_SetupBackground( void )
{
void* pPltFile;
void* pChrFile;
void* pScnFile;
NNSG2dPaletteData* pPltData;
NNSG2dCharacterData* pChrData;
NNSG2dScreenData* pScnData;
GX_SetVisiblePlane(GX_PLANEMASK_BG0);
G2_SetBG0Priority(3);
pPltFile = LoadNCLR( &pPltData, "/data/BG.NCLR", &sAllocator );
SDK_NULL_ASSERT( pPltFile );
pChrFile = LoadNCGR( &pChrData, "/data/BG.NCGR", &sAllocator );
SDK_NULL_ASSERT( pChrFile );
pScnFile = LoadNSCR( &pScnData, "/data/BG.NSCR", &sAllocator );
SDK_NULL_ASSERT( pScnFile );
NNS_G2dBGSetup(
NNS_G2D_BGSELECT_MAIN0,
pScnData,
pChrData,
pPltData,
GX_BG_SCRBASE_0x7800,
GX_BG_CHARBASE_0x38000
);
NNS_FndFreeToAllocator( &sAllocator, pPltFile );
NNS_FndFreeToAllocator( &sAllocator, pChrFile );
NNS_FndFreeToAllocator( &sAllocator, pScnFile );
}
/*---------------------------------------------------------------------------*
Name: TXT_Alloc
Description:
Arguments: size:
Returns:
*---------------------------------------------------------------------------*/
void* TXT_Alloc(u32 size)
{
return NNS_FndAllocFromAllocator( &sAllocator, size );
}
/*---------------------------------------------------------------------------*
Name: TXT_Free
Description: TXT_Alloc()
Arguments: ptr:
Returns:
*---------------------------------------------------------------------------*/
void TXT_Free(void* ptr)
{
NNS_FndFreeToAllocator( &sAllocator, ptr );
}
/*---------------------------------------------------------------------------*
Name: TXT_LoadFont
Description:
Arguments: pFname:
Returns:
*---------------------------------------------------------------------------*/
void* TXT_LoadFont( NNSG2dFont* pFont, const char* pFname )
{
void* pBuf;
pBuf = LoadNFTR( pFont, pFname, &sAllocator );
if( pBuf == NULL )
{
OS_Panic("Fail to load font file(%s).", pFname);
}
return pBuf;
}
void TXT_UnloadFont( void* pFile )
{
NNS_FndFreeToAllocator( &sAllocator, pFile );
}
/*---------------------------------------------------------------------------*
Name: TXT_LoadFile
Description:
Arguments: ppFile:
fpath:
Returns:
0
*ppFile
*---------------------------------------------------------------------------*/
u32 TXT_LoadFile(void** ppFile, const char* fpath)
{
return CMN_LoadFile(ppFile, fpath, &sAllocator);
}
/*---------------------------------------------------------------------------*
Name: TXT_SetCharCanvasOBJAttrs
Description: OAMのNNS_G2dArrangeOBJ*
Arguments:
Returns:
*---------------------------------------------------------------------------*/
void TXT_SetCharCanvasOBJAttrs(
GXOamAttr * oam,
int num,
int priority,
GXOamMode mode,
BOOL mosaic,
GXOamEffect effect,
int cParam,
int rsParam
)
{
int i;
for( i = 0; i < num; i++ )
{
G2_SetOBJPriority(oam, priority);
G2_SetOBJMode(oam, mode, cParam);
G2_SetOBJEffect(oam, effect, rsParam);
G2_OBJMosaic(oam, mosaic);
oam++;
}
}

View File

@ -0,0 +1,370 @@
/*---------------------------------------------------------------------------*
Project: NITRO-System - demos - g2d - Text - textdemolib
File: wprintf.c
Copyright 2004-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.
$Revision$
*---------------------------------------------------------------------------*/
#include "g2d_textdemolib.h"
/* inner function for sized-buffer output */
typedef struct dst_string_tag {
size_t len;
wchar_t *cur;
wchar_t *base;
} dst_string;
static void string_put_char(dst_string *p, wchar_t c)
{
if(p->len > 0) *p->cur = c, --p->len;
++p->cur;
}
static void string_fill_char(dst_string *p, wchar_t c, int n)
{
if(n > 0) {
size_t i, k = p->len;
if(k > (size_t)n) k = (size_t)n;
for( i = 0 ; i < k ; ++i )
p->cur[i] = c;
p->len -= k;
p->cur += n;
}
}
static void string_put_string(dst_string *p, const wchar_t *s, int n)
{
if(n > 0) {
size_t i, k = p->len;
if(k > (size_t)n) k = (size_t)n;
for( i = 0 ; i < k ; ++i )
p->cur[i] = s[i];
p->len -= k;
p->cur += n;
}
}
// based on OS_VSNPrintf
/*---------------------------------------------------------------------------*
Name: OS_VSNPrintf
Description: small-size vsnprintf which is similar to 'vsnprintf'
without following supports.
* CodeWarrior Extensions (#s)
* MSL AltiVec Extensions (v, vh, vl, hv, lv, @)
* indexed argments (%m$, *m$)
* floating-point
* wchar_t
Note: '+' and '#' do not work, MSL's sprintf().
to keep same result, they are no implement.
{ // exsample
wchar_t buf[5];
sprintf(buf, "%-i\n", 45); // "45" (OK)
sprintf(buf, "%0i\n", 45); // "45" (OK)
sprintf(buf, "% i\n", 45); // " 45" (OK)
sprintf(buf, "%+i\n", 45); // "%+i" ("+45" expected)
sprintf(buf, "%#x\n", 45); // "%#x" ("0x2d" expected)
// but, this works correctly!
sprintf(buf, "% +i\n", 45); // "+45" (OK)
}
Arguments: dst : destination buffer.
len : destination buffer size.
fmt : format string.
vlist : parameters.
Returns: length of the generated string. (except '\0')
if(result < len),
put NUL in dst[result].
else if(len > 0),
put NUL in dst[len - 1].
else,
do nothing.
*---------------------------------------------------------------------------*/
int NNSi_G2dVSNWPrintf(wchar_t *dst, size_t len, const wchar_t *fmt, va_list vlist)
{
wchar_t buf[24];
int n_buf;
wchar_t prefix[2];
int n_prefix;
const wchar_t *s = fmt;
dst_string str;
str.len = len, str.cur = str.base = dst;
while(*s) {
if(*s != L'%') {
/* normal character */
string_put_char(&str, *s++);
} else {
/* output with format */
enum {
flag_blank = 000001, /* L' ' */
flag_plus = 000002, /* L'+' */
flag_sharp = 000004, /* L'#' */
flag_minus = 000010, /* L'-' */
flag_zero = 000020, /* L'0' */
flag_l1 = 000040, /* "l" */
flag_h1 = 000100, /* "h" */
flag_l2 = 000200, /* "ll" */
flag_h2 = 000400, /* "hh" */
flag_unsigned = 010000, /* L'o', L'u', ... */
flag_end } ;
int flag = 0, width = 0, precision = -1, radix = 10;
wchar_t hex_char = L'a' - 10;
const wchar_t *p_start = s;
/* flags */
for( ; ; ) {
switch(*++s) {
case L'+':if(s[-1] != L' ') break;
flag |= flag_plus; continue;
case L' ':flag |= flag_blank;continue;
case L'-':flag |= flag_minus;continue;
case L'0':flag |= flag_zero; continue;
}
break;
}
/* width */
if(*s == L'*') {
++s, width = va_arg(vlist, int);
if(width < 0)
width = -width, flag |= flag_minus;
} else {
while((*s >= L'0') && (*s <= L'9'))
width = (width * 10) + *s++ - L'0';
}
/* precision */
if(*s == L'.') {
++s, precision = 0;
if(*s == L'*') {
++s, precision = va_arg(vlist, int);
if(precision < 0) precision = -1;
} else {
while((*s >= L'0') && (*s <= L'9'))
precision = (precision * 10) + *s++ - L'0';
}
}
/* option */
switch(*s) {
case L'h':
if(*++s != L'h') flag |= flag_h1;
else ++s, flag |= flag_h2;
break;
case L'l':
if(*++s != L'l') flag |= flag_l1;
else ++s, flag |= flag_l2;
break;
}
/* type */
switch(*s) {
case L'd': /* signed decimal */
case L'i': /* signed decimal */
goto put_integer;
case L'o': /* unsigned octal */
radix = 8;
flag |= flag_unsigned;
goto put_integer;
case L'u': /* unsigned decimal */
flag |= flag_unsigned;
goto put_integer;
case L'X': /* unsigned hexadecimal */
hex_char = L'A' - 10;
goto put_hexadecimal;
case L'x': /* unsigned hexadecimal */
goto put_hexadecimal;
case L'p': /* pointer */
/* equal to code warrior */
flag |= flag_sharp;
precision = 8;
goto put_hexadecimal;
case L'c': /* character */
if(precision >= 0)
goto put_invalid;
{
int c = va_arg(vlist, int);
width -= 1;
if(flag & flag_minus) {
string_put_char(&str, (wchar_t)c);
string_fill_char(&str, L' ', width);
} else {
wchar_t pad = (wchar_t)(
(flag & flag_zero) ? L'0' : L' ');
string_fill_char(&str, pad, width);
string_put_char(&str, (wchar_t)c);
}
++s;
}
break;
case L's': /* string */
{
int n_buf = 0;
const wchar_t *p_buf = va_arg(vlist, const wchar_t*);
if(precision < 0) {
while(p_buf[n_buf])
++n_buf;
} else {
while((n_buf < precision) && p_buf[n_buf])
++n_buf;
}
width -= n_buf;
if(flag & flag_minus) {
string_put_string(&str, p_buf, n_buf);
string_fill_char(&str, L' ', width);
} else {
wchar_t pad = (wchar_t)(
(flag & flag_zero) ? L'0' : L' ');
string_fill_char(&str, pad, width);
string_put_string(&str, p_buf, n_buf);
}
++s;
}
break;
case L'n': /* store the number of output */
{
int pos = str.cur - str.base;
if(flag & flag_h2)
;
else if(flag & flag_h1)
*va_arg(vlist, signed short*) = (signed short)pos;
else if(flag & flag_l2)
*va_arg(vlist, u64*) = (u64)pos;
else
*va_arg(vlist, signed int*) = (signed int)pos;
}
++s;
break;
case L'%': /* output L'%' */
if(p_start + 1 != s)
goto put_invalid;
string_put_char(&str, *s++);
break;
default: /* invalid type */
goto put_invalid;
put_invalid:
string_put_string(&str, p_start, s - p_start);
break;
put_hexadecimal:
radix = 16;
flag |= flag_unsigned;
put_integer:
{
u64 val = 0;
n_prefix = 0;
if(flag & flag_minus)
flag &= ~flag_zero;
if(precision < 0) precision = 1;
else flag &= ~flag_zero;
if(flag & flag_unsigned) {
if(flag & flag_h2)
val = va_arg(vlist, wchar_t);
else if(flag & flag_h1)
val = va_arg(vlist, unsigned short);
else if(flag & flag_l2)
val = va_arg(vlist, u64);
else
val = va_arg(vlist, unsigned long);
flag &= ~(flag_plus | flag_blank);
if(flag & flag_sharp) {
if(radix == 16) {
if(val != 0) {
prefix[0] = (wchar_t)(hex_char + (10 + L'x' - L'a'));
prefix[1] = L'0';
n_prefix = 2;
}
} else if(radix == 8) {
prefix[0] = L'0';
n_prefix = 1;
}
}
} else {
if(flag & flag_h2)
val = va_arg(vlist, wchar_t);
else if(flag & flag_h1)
val = va_arg(vlist, short);
else if(flag & flag_l2)
val = va_arg(vlist, u64);
else
val = va_arg(vlist, long);
if((val >> 32) & 0x80000000) {
val = ~val + 1;
prefix[0] = L'-';
n_prefix = 1;
} else {
if(val || precision) {
if(flag & flag_plus) {
prefix[0] = L'+';
n_prefix = 1;
} else
if(flag & flag_blank) {
prefix[0] = L' ';
n_prefix = 1;
}
}
}
}
n_buf = 0;
while(val != 0) {
int d = (int)(val % radix);
val /= radix;
buf[n_buf++] = (wchar_t)((d < 10) ?
(d + L'0') : (d + hex_char));
}
if((n_prefix > 0) && (prefix[0] == L'0')) {
n_prefix = 0;
buf[n_buf++] = L'0';
}
}
goto put_to_stream;
put_to_stream:
{
int n_pad = precision - n_buf;
if(flag & flag_zero) {
if(n_pad < width - n_buf - n_prefix)
n_pad = width - n_buf - n_prefix;
}
if(n_pad > 0) width -= n_pad;
width -= n_prefix + n_buf;
if(!(flag & flag_minus))
string_fill_char(&str, L' ', width);
while(n_prefix > 0)
string_put_char(&str, prefix[--n_prefix]);
string_fill_char(&str, L'0', n_pad);
while(n_buf > 0)
string_put_char(&str, buf[--n_buf]);
if(flag & flag_minus)
string_fill_char(&str, L' ', width);
++s;
}
break;
}
}
}
if(str.len > 0)
*str.cur = '\0';
else if(len > 0)
str.base[len - 1] = '\0';
return str.cur - str.base;
}