#165565 - MaesterRowen - Sat Dec 27, 2008 11:22 pm
Hello everyone.
I have spent a large portion of the day trying to understand and figure out how to make circular windows on the NDS.
I have done some searching on these forums and other resources and have found the discussion on TONCs page, as well as at this http://forum.gbadev.org/viewtopic.php?t=9023
I was wondering if anyone had any example code for the NDS that created circular windows.
I feel if I can understand how the circular window code works, the concept will be there to create any effect I would like.
I almost had a window with a diagonal edge; but I had a problem with it scrolling from the bottom to the top. It was never stationary.
I appreciate the help.
#165567 - MaesterRowen - Sun Dec 28, 2008 2:14 am
Well,
I figured it out ^_^.
Thanks!
#165579 - silent_code - Sun Dec 28, 2008 8:46 pm
Why not share your solution? :^)
_________________
July 5th 08: "Volumetric Shadow Demo" 1.6.0 (final) source released
June 5th 08: "Zombie NDS" WIP released!
It's all on my page, just click WWW below.
#165583 - Dwedit - Mon Dec 29, 2008 2:32 am
Use HDMA to transfer new window boundaries every scanline.
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."
#165586 - MaesterRowen - Mon Dec 29, 2008 4:01 am
For the record books, here is the code to make the circular window on the DS. It can probably be refined and made better, but atleast it works. It's a slight modification of the TONC guide.
Code: |
#include <nds.h>
#include <stdio.h>
#include <stdlib.h>
#include "bg01.h"
#define WIN0_BG0 BIT(0)
#define WIN0_BG1 BIT(1)
#define WIN0_BG2 BIT(2)
#define WIN0_BG3 BIT(3)
#define WIN1_BG0 BIT(8)
#define WIN1_BG1 BIT(9)
#define WIN1_BG2 BIT(10)
#define WIN1_BG3 BIT(11)
u16 g_winh[SCREEN_HEIGHT + 1];
#define DMA_HDMA (DMA_ENABLE | DMA_REPEAT | DMA_START_HBL | DMA_DST_RESET)
#define DMA_TRANSFER(_dst, _src, count, ch, mode) \
do { \
DMA_CR(ch)= 0; \
DMA_SRC(ch)= (unsigned int)(_src); \
DMA_DEST(ch)= (unsigned int)(_dst); \
DMA_CR(ch)= (count) | (mode); \
} while(0)
int getSize(uint8 *source, uint16 *dest, uint32 arg)
{
return *(uint32*)source;
}
uint8 readByte(uint8 *source)
{
return *source;
}
void decompressToVRAM(const void* source, void* dest)
{
TDecompressionStream decStream = {
getSize,
NULL,
readByte};
swiDecompressLZSSVram((void*)source, dest, 0, &decStream);
}
void win_circle(int x0, int y0, int rr, u16 winh[])
{
int x=0, y= rr, d= 1-rr;
u32 tmp;
for(int i = 0; i < SCREEN_HEIGHT + 1; i++)
{
winh[i] = 0;
}
while(y >= x)
{
// side octs
tmp= 255;
if(x0+y<255)
tmp= x0+y;
if(x0>y)
tmp |= (x0-y)<<8;
if(y0>=x) // o4, o7
winh[y0-x]= tmp;
if(y0+x<192) // o0, o3
winh[y0+x]= tmp;
if(d<0)
{
d += 2*x+3;
}
else // change in y: top/bottom octs
{
tmp= 255;
if(x0+x<255)
tmp= x0+x;
if(x0>x)
tmp |= (x0-x)<<8;
if(y0>=y) // o5, o6
winh[y0-y]= tmp;
if(y0+y<192) // o1, o2
winh[y0+y]= tmp;
d += 2*(x- --y)+3;
}
x++;
}
}
int main()
{
vramSetBankA(VRAM_A_MAIN_BG);
REG_BG3CNT = BG_BMP8_256x256 | BG_BMP_BASE(0) | BG_PRIORITY(3);
REG_BG3PA = 1 << 8;
REG_BG3PB = 0;
REG_BG3PC = 0;
REG_BG3PD = 1 << 8;
REG_BG3X = 0 << 8;
REG_BG3Y = 0 << 8;
dmaCopy(bg01Pal, BG_PALETTE, bg01PalLen);
decompressToVRAM(bg01Bitmap, BG_BMP_RAM(0));
consoleDemoInit();
WIN1_X0 = 0;
WIN1_X1 = 0;
WIN1_Y0 = 0;
WIN1_Y1 = 0;
WIN_IN = WIN1_BG3;
videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE | DISPLAY_WIN1_ON);
int tickValue = 1;
int r = 1;
int pressed = 0;
// Infinite loop to keep the program running
while (1)
{
scanKeys();
consoleClear();
if(keysDown() & KEY_A)
{
pressed = 1;
r = 1;
tickValue = 1;
WIN1_Y0 = 0;
WIN1_Y1 = 192;
}
if ( pressed == 1)
{
if(--tickValue < 0)
{
tickValue = 1;
r = r + 8;
}
if(r > 160)
{
tickValue = 60;
r= 161;
pressed = 2;
}
win_circle(128, 96, r, g_winh);
DMA_TRANSFER(&WIN1_X1, &g_winh, 1, 3, DMA_HDMA);
}
else if (pressed == 2)
{
videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE);
pressed = 3;
}
swiWaitForVBlank();
}
return 0;
}
|
#165618 - MaesterRowen - Tue Dec 30, 2008 7:15 am
Hmm, I tried out this circular window code on the hardware, and it seems to fall victim to the Vblank Window Glitch.
Guess I need to figure out how to compensate for that.