Another adaptation of one of Libnds example code projects. You can use the keypad or the touchscreen to move around, use A to talk, B to clear the text.
#include <nds.h> #include <stdio.h> #include <man.h> #define FRAMES_PER_ANIMATION 3 typedef struct { int x; int y; u16* sprite_gfx_mem; u8* frame_gfx; int state; int anim_frame; }Man; enum SpriteState {W_UP = 0, W_RIGHT = 1, W_DOWN = 2, W_LEFT = 3}; enum {SCREEN_TOP = 0, SCREEN_BOTTOM = 192, SCREEN_LEFT = 0, SCREEN_RIGHT = 256}; touchPosition touch; void animateMan(Man *sprite) { int frame = sprite->anim_frame + sprite->state * FRAMES_PER_ANIMATION; u8* offset = sprite->frame_gfx + frame * 32*32; dmaCopy(offset, sprite->sprite_gfx_mem, 32*32); } void initMan(Man *sprite, u8* gfx) { sprite->sprite_gfx_mem = oamAllocateGfx(&oamMain, SpriteSize_32x32, SpriteColorFormat_256Color); sprite->frame_gfx = (u8*)gfx; } void printStaticText() { static int i = 0; static int j = 0; char text[] = {"Hi, I'm Ninten\n"}; while(text[i]!= '\0') { if(j++ > 99999) { iprintf("%c", text[i++]); j = 0; } } i = 0; } int main(void) { Man man = {(SCREEN_WIDTH-16) / 2, (SCREEN_HEIGHT-16) / 2}; man.state = W_DOWN; int count = 0; //----------------------------------------------------------------- // Initialize the graphics engines //----------------------------------------------------------------- videoSetMode(MODE_0_2D); vramSetBankA(VRAM_A_MAIN_SPRITE); oamInit(&oamMain, SpriteMapping_1D_128, false); initMan(&man, (u8*)manTiles); dmaCopy(manPal, SPRITE_PALETTE, 512); consoleDemoInit(); while(1) { scanKeys(); touchRead(&touch); int yPos = 0; int xPos = 0; int keys = keysHeld(); if(keys) { if(keys & KEY_UP) { if(man.y >= SCREEN_TOP) man.y--; man.state = W_UP; } if(keys & KEY_LEFT) { if(man.x >= SCREEN_LEFT) man.x--; man.state = W_LEFT; } if(keys & KEY_RIGHT) { if(man.x <= SCREEN_RIGHT - 32) man.x++; man.state = W_RIGHT; } if(keys & KEY_DOWN) { if(man.y <= SCREEN_BOTTOM - 32) man.y++; man.state = W_DOWN; } if(touch.px > 0) { xPos = touch.px; if(xPos > man.x) { if(man.x <= SCREEN_RIGHT - 32) man.x++; man.state = W_RIGHT; } if(xPos < man.x) { if(man.x >= SCREEN_LEFT) man.x--; man.state = W_LEFT; } } if(touch.py > 0) { yPos = touch.py; if(yPos > man.y) { if(man.y <= SCREEN_BOTTOM - 32) man.y++; man.state = W_DOWN; } if(yPos < man.y) { if(man.y >= SCREEN_TOP) man.y--; man.state = W_UP; } } if(count++ > 10 && (man.x != xPos || man.y != yPos)) { man.anim_frame++; count = 0; } if(man.anim_frame >= FRAMES_PER_ANIMATION) man.anim_frame = 0; } animateMan(&man); oamSet(&oamMain, 0, man.x, man.y, 0, 0, SpriteSize_32x32, SpriteColorFormat_256Color, man.sprite_gfx_mem, -1, false, false, false, false, false); if(keys & KEY_A) printStaticText(); if(keys & KEY_B) consoleDemoInit(); swiWaitForVBlank(); oamUpdate(&oamMain); } return 0; } |
The code in action: