#DS 배경 스펙
DS 는 각각의 스크린에서 자신의 256 색 팔레트를 가지고 있는 배경을 4개까지 표시할 수 있다. 이 타일화된 배경은 2부분으로 구성된다.
8x8 픽셀 타일로 구성된 타일셋으로 전체 이미지를 구성한다.
256x256 픽셀에서 512x512 범위의 작은 지도인 타일맵은 화면상에 타일들이 배열된 것을 표시해 준다.
타일맵은 8bit 또는 16bit 배경으로 변경가능하다. 이 배경은 bitmap, bmp,gif, jpeg, 등등 이 로드될 수 있다. 하지만 항상 기억해야 할 것이 있는데, 이 타입의 배경은 스크린당 하나로 제한된다는 것이다. RAM을 많이 차지 한다.(8bit일때 3/8, 16bit일때 6/8)

DS는 스크린당 2개까지 회전및 스케일링해서 표시할 수 있다. 하지만 많이 사용되지는 않는다.
-.변환
PAGfx Frontend
sprite 사용과 매우 비슷하다.

PAGfx.ini
#TranspColor Magenta
 
#Sprites :
 
#Backgrounds :
C:\test.bmp EasyBg
 
#Textures :

가능한 배경 모드는 다음과 같다.
:8bit bitmap 이미지를 위한 8bit
:16bit bitmap 이미지를 위한 16bit
:평이하고 일반적인 배경으로 많이  사용하는 256x256, 512x256, 256x512, 512,512 크기의 TileBg
:TileBg와 비슷하지만 PAlib의 LargeMap 함수를 사용하는 1024×2048 같은 어떠한 배경크기도 허용되는 LargeMap
:회전하는 배경을 위한 128×128, 256×256, 512×512, 1024×1024 크기의 RotBg
:TileBg와 LargeMap 사이에서 최상의 포맷으로 자동 선택되는 EasyBg 으로 앞으로 계속 사용될 것이다.

#EasyBg
PAGfx에서 변환시 EasyBg 타입을 선택한다.(TiledBg도 동작할 것이다.)

-. 로딩
PA_EasyBgLoad
PAGfx에서 EasyBg 옵션을 사용하라. 다른 배경 변환툴은 필요없다.
PA_EasyBgLoad (screen, background number, background name);
DS는 화면당 4개의 배경을 가진다 그래서 배경숫자를 0~3까지 사용한다. 숫자가 낮을수록 우선순위는 더 높다.(sprite와 같다.) 배경0 은 배경1 위에 있다.
PAlibExamples/Backgrounds/LoadBg 의 코드를 보자.

// Load a simple background, very easy and simple...
 
// Includes
#include <PA9.h>       // Include for PA_Lib
 
// Converted using PAGfx
#include "gfx/all_gfx.c"
#include "gfx/all_gfx.h"
 
 
// Function: main()
int main(int argc, char ** argv)
{
PA_Init();    // Initializes PA_Lib
PA_InitVBL(); // Initializes a standard VBL

// Load Backgrounds with their palettes !
PA_EasyBgLoad(0, // screen
  3, // background number (0-3)
  bg0); // Background name, used by PAGfx...
PA_EasyBgLoad(1, 0, bg0); // Same thing, but on the top screen...
 
// Infinite loop to keep the program running
while (1)
{
PA_WaitForVBL();
}

return 0;
} // End of main()
양쪽 화면에 팔레트를 가진 배경을 로딩한다.

-.배경 스크롤
일반적인 스크롤
배경 스크롤은 sprite를 움직이는 것만큼 쉽다. PAlibExamples/ScrollBg 에서 코드를 확인할수 있다.
PA_InitText(1, 0); // Init text on the top screen, background 0...

// Load Backgrounds and their palettes...
PA_EasyBgLoad(0, 3, BG3);
PA_EasyBgLoad(1, 3, BG3);

s32 scrollx = 0; // No X scroll by default...
s32 scrolly = 0; // No Y scroll by default...
 
// Infinite loop to keep the program running
while (1)
{
// We'll modify scrollx and scrolly according to the keys pressed
scrollx += (Pad.Held.Left - Pad.Held.Right) * 4; // Move 4 pixels per press
scrolly += (Pad.Held.Up - Pad.Held.Down) * 4; // Move 4 pixels per press
 
// Scroll the background to scrollx, scrolly...
PA_EasyBgScrollXY(0, // Screen
  3, // Background number
  scrollx, // X scroll
  scrolly); // Y scroll

// Display the X and Y scrolls :
PA_OutputText(1, 0, 0, "x : %d   \ny : %d   ", scrollx, scrolly);

PA_WaitForVBL();
}
텍스트 초기화 함수에서 텍스트가 로딩될 배경 숫자를 선택할수 있다.(0~3) 텍스트를 위해 사용된 배경에 배경을 로딩하면 텍스트를 덮을 것이다. 만일 사용된 배경에 텍스트를 로딩하면 배경이 지워질 것이다. 이처럼 배경과 텍스트를 같이 섞어서 쓸수 없다.
scrollx += (Pad.Held.Left - Pad.Held.Right) * 4; sprite를 위해 많이 사용되는 것이다. 4는 속도이다.
PA_EasyBgScrollXY(Screen, Background number, X scroll, Y scroll); 동시에 X, Y로 스크롤할 필요 없을때 PA_EasyBgScrollX 와 PA_EasyBgScrollY 를 사용해면 된다.

배경이 화면을 벗어났을때 어떻게 될까? 이것은 그 화면 사이즈에 달렸는데.. 반복해서 보일 수도 있고 그렇지 않을 수도 있다. 만일 배경이 256 넓이면 수평으로 반복될 것이다. 만일 256~512 사이이면 그렇게 안될것이다. DS 기본 사이즈가 256 이거나 512 크기이기 때문이다. ( 더 많은 다른 스크롤 모드를 사용하여 512 보다 큰 것은 잘 보여질 것이다.) 반복되지 않을때 배경과 다시 나타날때까지 빈 공간이 나타날 것이다. 수직방향과 같으며 배경 크기에 따라 다르다.

시차 스크롤
시차 스크롤은 모든 배경에서 다른 스크롤 속도를 나타나게 하는 놀라운 기술로 3D 효과같은 깊이 있는 표현을 제공한다. 이것을 사용하지 않는 것은 망신스런 일이다. 보기에도 좋고 사용방법도 쉽다. 많은 게임에서 사용된다. 슈팅게임 에서(가까운 별이 한 속도로 스크롤되고, 멀리 있는 별은 또 다른 속도로 스크롤되는)  아주 다양한 상황에서 사용된다.

PAlib는 시차 스크롤에대해 몇가지 좋은 함수을 가지고 있다. Backgrounds/Parallax 예제를 살펴보자.

// Load the 4 Backgrounds on the bottom screen...
PA_EasyBgLoad(0, 1, BG1); //screen, background number, background name
PA_EasyBgLoad(0, 2, BG2);
PA_EasyBgLoad(0, 3, BG3);
 
// Initialise parallax vertically (Y axis) for both backgrounds
// 256 is normal speed, 128 half speed, 512 twice as fast...
PA_InitParallaxY(0, //screen
  0, //Parallax speed for Background 0. 0 is no parallax (will scroll independently with    PA_EasyBgScrollXY)
  256, // Normal speed for Bg1
  192, //   3/4 speed
  128); // Half speed
PA_InitParallaxY(1, 0, 256, 192, 128); // Same thing, but for Screen 1...

s32 scroll = 0;
 

// Infinite loop to keep the program running
while (1)
{
scroll += 1; // Scroll by one pixel...
// Backgrounds with a parallax speed of 256 will scroll 1 pixel, 192 will scroll 0.75, and 128 0.5
// We could also have put a negative parallax speed to have some backgrounds scroll in different directions

PA_ParallaxScrollY(0, -scroll)// Scroll the screen 0 backgrounds.
 
PA_WaitForVBL();
}
먼저 배경을 로딩할 필요가 있다. 적어도 2개 이상. 하나만 가지고는 다른 속도로 스크롤 할수 없기 때문이다.
그 후엔 시차 스크롤을 초기화 해야 한다. PA_InitParallaxY(screen, bg0 speed, bg1 speed, bg2 speed, bg3 speed); 각각 다른 배경에 다른 속도를 설정한다. 256 은 기본 1 픽셀 속도이다. 512는 두배 빠른 속도이고, 128은 절반 속도이다. 약간의 시행착오를 하다보면 자기 게임에 맞는 보기 좋은 속도를 찾을수 있을 것이다. 어렵지 않다. 주 배경을 놓고 가장 가까이 있는 것을 256 속도로 놓고 멀리 있는 것은 더 낮은 값을 주면 된다. 만일 시차 스크롤을 원하지 않으면 속도를 0 으로 설정하면 된다. 위의 코드에서 배경 0 이 그것이다. ( 텍스트, 스코어 같은 것들을 표시하기 위해 배경을 사용한다면 같이 움직이기를 원할 것이다.)
자기 자신을 스크롤하기 때문에 scroll += 1; 이렇게 하면 된다. 하지만 Pad키를 사용하여 스크롤해야 한다.
 PA_ParallaxScrollY(screen, scroll); 이건 흥미로운 함수로 실제 시차 스크롤를 시킨다. 여기서는 특별한 방향으로 스크롤하기 위해서 -scroll 로 설정했다.

-. 배경 회전
멋지지만 일반적인 배경에 사용하긴 힘들다. 이것들을 변환하기 위해서 RotBg 배경모드를 사용해야 한다.
Backgrounds/RotBackgrounds 예제를 살펴 보자.
PA_SetVideoMode(0, 2)//screen, mode

PA_LoadPAGfxRotBg(0, //screen
  3, // background number
  Rot, // background name in PAGfx
  1); // wraparound !

PA_InitText(1, 0);

// Infinite loop to keep the program running
s32 scrollx = 0;
s32 scrolly = 0;
s32 rotcenterx = 0;
s32 rotcentery = 0;
s16 angle = 0;
s32 zoom = 256;

PA_OutputSimpleText(1, 2, 2, "Zoom       : Start/Select");
PA_OutputSimpleText(1, 2, 3, "ScrollX    : Left/Right");
PA_OutputSimpleText(1, 2, 4, "Scrolly    : Up/Down");
PA_OutputSimpleText(1, 2, 5, "RotCenterX : A/Y");
PA_OutputSimpleText(1, 2, 6, "RotCenterY : B/X");
PA_OutputSimpleText(1, 2, 7, "Angle      : R/L");
 
while (1){
zoom += Pad.Held.Start - Pad.Held.Select;
scrollx += Pad.Held.Right - Pad.Held.Left;
scrolly += Pad.Held.Down - Pad.Held.Up;
rotcenterx += Pad.Held.A - Pad.Held.Y;
rotcentery += Pad.Held.B - Pad.Held.X;
angle += Pad.Held.R - Pad.Held.L;

PA_SetBgRot(0, 3, scrollx, scrolly, rotcenterx, rotcentery, angle, zoom);

PA_WaitForVBL();
}
보는 것처럼 타일 배경 로딩과 회전배경사이엔 특별히 다른게 2가지 있다.
PA_SetVideoMode(screen, video); 이것 없이는 배경을 회전시킬수 없다.
비디오 모드 0 은 일반적인 타일모드 ( 또는 큰 맵)로 4개 배경을 설정한다. 이것은 기본 모드이다.
비디오 모드 1 은 먼저 일반적인 타일모드 ( 또는 큰 맵)로 3개 배경을 설정하고 배경 3이 회전 배경이 된다.
비디오 모드 2 는 먼저 일반적인 타일모드로 2개의 배경이 설정되고 나머지 2개가 회전하는 배경이 된다.(2, 3)
회전하는 배경은 다른 배경으로 사용될수 없다. 배경 2,3 은 비디오 모드에 달려 있다.
 
PA_LoadPAGfxRotBg(screen, background number, background name in PAGfx, wraparound (0/1 for off/on)); 이것은 다른 배경 로딩함수와 유사하다. 배경과 PAGfx로 변환한 팔레트를 로딩한다.

PA_SetBgRot(screen, background, scrollx, scrolly, rotcenterx, rotcentery, angle, zoom);
이것은 sprite를 회전/확대 하는 것과 유사한 종류이다. 각도와 줌을 위해(256 줌이 100% 등등) 같은 값을 취한다.
scrollx 와 scrolly 는 배경 위치이다.
rotcenterx 와 rotcentery 는 회전 중심이고 변경가능하다.
angle은 sprite 와 같다.
zoom 은 X , Y 동시의 줌이다.

-. 8 / 16 bit 배경
8bit 와 16bit 배경 함수는 서로 매우 유사하다. 8/16bit 배경과 다른 배경과의 주요 차이점은 무엇일까? 다른 배경은 8x8 픽셀 타일로 만들어진 배경이라는 것이다. 이것은 bitmap 배경을 위한 것이 아니다.

8/16bit vs Tiles
시작하기 전에 bitmap 배경 사용의 득과 실을 따져 보는 것이 최상이다.
손실
다른 배경 타입보다 더 많은 비디오 RAM 공간을 차지한다. 8bit는 주어진 스크린을 위해 ram의 3/8를 사용하고 16bit는 6/8 이다. 만일 16bit를 사용한다면 많아야 2개의 평범한 배경을(너무 복잡하지 않은) 사용할 수 있는 제한이 있다.
그리는데 매우 느리다. 타일은 8x8 블럭이지만 bitmap은 픽셀하나 하나 그린다. 타일보다 bitmap 배경에서는 8x8 블럭이 변경되기 위해 64배나 많이 걸린다. 더해서 8bit 배경은 픽셀로 그리는데 16bit 보다 더느린 특별한 제약이 있다.
같은 이유로 배경 전체를 지우는데 오랜 시간이 걸린다. 다른 배경으로 순간적으로 변경하는 곳에서 그렇다.
이것은 배경3 에만 놓여 질수 있다. 배경의 우선권을 변경할수 있기에 사실 문제는 아니다. 하지만 변경후에 배경3을 배경으로 로딩할수 없다는 것을 기억해야 한다. 그렇지 않으면 버그가 될수 있다. (배경 0-2 는 가능하다)

이득
스크린상에 실제로 바로 그릴수 있다. PAlib는 스타일러스를 사용하여 그릴수 있는 함수를 제공한다.
8bit 또는 16bit (포맷에 따라) 배경에 어떠한 변환없이 어떤 이미지 포맷이든 바로 로딩할 수 있다. 이것이 느릴지라도 이것은 매우 굉장한 사실이다. 이러한 이미지는 롬에 포함하기에 매우 작다. 한번에 로딩할 필요가 있는 splash 스크린이나 정적인 배경을 위해 이상적이다. 이런 것은 속도가 문제가 되지 않는다. 지원되는 포맷은 jpeg(16bit만), gif(8/16bit),bmp(16bit), raw(8/16bit)
16bit 배경은 팔레트의 제한이 없다는 걸 의미한다. 스크린상에 모든 색 표현이 가능하다. 이것은 예를 들어 jpeg로 연결해 사용할때 꽤 유용하다.

최종 고려
다음과 같은 종류의 프로그램이나 게임에 사용될 수 있다.
splash 화면이 정말 중요하게 사용된다. jpeg를 사용하여 16bit 배경에 로드할수 있다. 이것은 멋져 보이지만 롬에서 여유가 많이 줄어 들 것이다.
메뉴 화면은 뒤 화면으로 8bit 또는16bit 배경을 가질수 있다. 메뉴 항목에 sprite를 사용할 수 있다.
작은 비디오 촬영 영상으로 8/16bit 스크린상에 움직이는 gif를 사용할 수 있다. 이건 아주 좋은데 많은 공간을 차지 하지도 않는다. 단지 만화같은 애니메이션이 보기에 좋고 영화같은 것은 아니다.
게임에서 bitmap 배경을 특별히 사용하지는 않는다. 스타일러스로 그리기를 원하지 않는한 말이다.
최고 점수에대한 사인을 스타일러스로 그리는데 사용할 수 있다. polarium 게임 처럼. 기본적인 세글자 이름보다 좋은 대체품이 될것이다.

8 / 16 bit 배경
팔레트를 로딩해야 하므로 8bit 배경이 좀더 복잡하다.
8/ 16 bit 배경을 만들기 위해서 먼저 일반적으로 사용하는 아무 그리기 프로그램에서 이미지를 만들어야 한다. 이미지는 256x192 여야 한다. 안그러면 화면상에 비뚤어져 보일 것이다.
8bit 배경을 사용하기 위해서 다음 코드가 필요하다.
PA_Init8bitBg(0,3);
PA_Load8bitBgPal(0,(void*)bmp_Pal);  
PA_Load8bitBitmap(0,background_Bitmap);
PA_Init8bitBg(0,3); 우선권3을 가진 8bit 배경을 넣기 위해 스크린 0을 초기화 한다.
우선권은 0~3이 될수 있다.
PA_Load8bitBgPal(0,(void*)bmp_Pal); 8bit bitmap을 위한 팔레트를 로딩한다.
PA_Load8bitBitmap(0,background_Bitmap); 화면상에 그림을 넣는다. 0은 스크린 숫자고 background_Bitmap은 파일명이다.

16bit 배경은 더 쉽다.
PA_Init16bitBg(0, 3);
PA_Load16bitBitmap(0,background_Bitmap);
이 라인들은 위 코드와 거의 동일하다. 16bit 이미지는 팔레트를 가지고 있지 않기 때문에 로딩할 필요가 없다.
Posted by 버들피리불며

BLOG main image
닌텐도 DS 관련해서 Palib를 소개하고 제가 개발한 홈브류와 다른 개발자의 홈브류를 소개하고자 합니다. NDS 자체 제작(Homebrew)에 관심있는 다른 분들의 길잡이가 되고 싶습니다. by 버들피리불며

공지사항

카테고리

분류 전체보기 (39)
따라하기 (5)
PA_lib 소개 (10)
Homebrew 소개 (7)
나의 Homebrew (15)
기부하기(Donate) (1)
Wii (1)
Total : 117,195
Today : 1 Yesterday : 1