Sufficiency Economy
Group Blog
 
All blogs
 

เขียนเกม บนเครื่อง Nintendo DS : Vertical Blank Interrupts

Vertical Blank Interrupts
การ update ภาพที่อยู่บนหน้าจอ ระบบจะดำเนินการโดยเขียนข้อมูลจาก บน ซ้ายสุด (0,0) แล้วเคลื่อนที่ไปทางขวามือ จนสุด ก็จะได้ข้อมูลบรรทัดที่หนึ่ง(255,0) ต่อจากนั้น จะทำการเลื่อนไปเขียนข้อมูลบรรทัดที่สองโดยเริ่มจากซ้ายมือสุด(0,1) ไปทางขวามือ จะเห็นได้ว่ามีช่วงเวลาว่างขณะที่การเลื่อนไปเขียนข้อมูลด้านซ้ายมือ ซึ่งเราเรียกว่า Horizontal Bank Interrupts ซึ่งเป็นเวลาไม่ค่อยมาก แต่เมื่อเขียนข้อมูลจนถึงบรรทัดสุดท้ายตำแหน่ง (255,191) จะมีการเลื่อนไปเขียนข้อมูลที่ (0,0) อีกครั้ง ซึ่งช่วงเวลานี้เรียกว่า Vertical Blank Interrupts ซึ่งจะนานว่า HBlank
จากตัวอย่างที่แล้ว ที่ภาพกระพริบก็เนื่องจาก เราได้เขียนข้อมูลเข้า memory ในช่วงที่ระบบกำลัง Update ข้อมูล ดังนั้นเพื่อไม่ให้เกิดลักษณะดังกล่าว จึงต้องรอให้เกิด Vertical Blank ก่อน แล้วจึงเขียนข้อมูล
หรือพูดอีกอย่างหนึ่งว่าเขียนข้อมูลขณะที่ ระบบกำลังเลือนไปเขียนข้อมูลที่ (0,0) แต่อย่างไรก็ตาม ถ้าเราใช้เวลาในการเขียนข้อมูลมาก (คิดว่าเกิน 1/20 วินาที) ก็จะทำให้เกิดภาพกระพริบได้เหมือนกัน เพราะเลยช่วง VBlank นั้นเอง คำสั่งก็คือ
การตั้งการ Interrupts
irqInit();
irqSet(IRQ_VBLANK, 0);
irqEnable(IRQ_VBLANK);

และ การตรวจสอบการเกิด VBlank
swiWaitForVBlank();

ส่วนคำสั่ง powerON( POWER_LCD | POWER_2D_B );
เป็นการตั้งค่าเริ่มต้นเกี่ยวกับการแสดงผล เพื่อให้ Register ต่างๆ มีค่าที่เหมาะสมก่อนใช้งาน




 

Create Date : 05 กรกฎาคม 2551    
Last Update : 5 กรกฎาคม 2551 20:18:23 น.
Counter : 611 Pageviews.  

เขียนเกม บนเครื่อง Nintendo DS : ตรวจสอบการกดปุ่ม

libnds ได้เตรียมคำสั่งสำหรับรับค่าการกด Key ไว้เรียบร้อยแล้ว ถ้าอยากดูว่ามีอะไรบ้างให้ไปดูใน File header ที่ชื่อว่า input.h ซึ่งโดยปกติจะอยู่ที่ C:devkitProlibndsincludendsarm9

โดยคำสั่งที่จะใช้คือ
scanKeys(); สำหรับ scan ค่าการกดคีย์
keysHeld(); สถานะการกด : ตรงนี้งงเหมือนกันแหะๆ
ต่อมาก็ตรวจสอบการกดปุ่ม
สรุปก็คือ
scanKeys();
u32 keys = keysHeld();
if( keys & KEY_A )
นี้คือการตรวจสอบการกดปุ่ม A
ถ้าต้องการตรวจสอบการกดปุ่มอื่นก็เปลี่ยน KEY_A เป็นชื่อ คีย์ที่เราต้องการตามที่เขียนใน input.h เช่น
KEY_B KEY_SELECT KEY_START KEY_RIGHT KEY_LEFT เป็นต้น
ลองrun code ที่นี้ ดูครับ

จะเห็นได้ว่าจอล่างจะแสดงค่าการกดปุ่ม A หรือ ปุ่ม B เท่านั้น ถ้าต้องการรับปุ่มอื่นด้วย ก็ลองแก้ไข code ดูครับ

และถ้าท่านสังเกตุจะเห็นว่า ภาพจะแตกๆ หรือกระพริบ ตอนแสดงตัวอักษร
เนื่องจากว่าเราไม่ได้ตรวจสอบเหตุการณ์ VBlank เลย (แล้วVBlankคือไรหว่า) ก็ขอให้เอา comment "//" ใน บรรทัดต่อไปนี้ออก ก็จะไม่กระพริบแล้ว
//powerON( POWER_LCD | POWER_2D_B );
//irqInit();
// irqSet(IRQ_VBLANK, 0);
// irqEnable(IRQ_VBLANK);

และ
//swiWaitForVBlank();

ครั้งหน้าจะมาเล่าในส่วน VBlank ครับ




 

Create Date : 28 มิถุนายน 2551    
Last Update : 28 มิถุนายน 2551 21:08:21 น.
Counter : 763 Pageviews.  

เขียนเกม บนเครื่อง Nintendo DS : แสดงผลเป็นภาษาไทย

ก่อนอื่นต้องขอขอบคุณ คุณ newbiz ที่ให้ code มาซึ่งเป็นของ PALib ซึ่งผมนำมา Modify นิดหน่อย

ทดลองรันโปรแกรมดีกว่า โดยไป D/L ไฟล์ ที่นี้ มา Compile ดูก่อน จะได้ผลลัพธ์ตามภาพ


ข้อมูล font ที่จะแสดงอยู่ที่ ThaiFont.dat ซึ่งเป็น File Text ธรรมดา
ตัวแปรที่สำคัญมีสองตัว const unsigned char ThaiFont[256][16] สำหรับเก็บข้อมูลตัวอักษรแต่ละตัว และ FontSpace[256] เป็นค่าระยะห่างที่เหมาะสมเพราะตัวอักษรแต่ละตัวมีขนาดไม่เท่ากัน เช่น กอ ไก่ กับ ขอ ไข่
ขอ ไข่ ขนาดจะเล็กกว่าเป็นต้น

ภาษาไทยมีการเขียนประมาณสี่ระดับ คือ
กลาง คือพญัชนะทั่วไป เช่น ก ข ค
บน คือพวก สระอิ สระอี ไม้เอก ไม้โท
ล่าง คือพวก สระอุ สระอู
บนของบน คือพวกวรรณยุกต์ เอก โท ตรี จัตวา

ฟังก์ชั่น เขียนสีที่ละจุดที่ตำแหน่ง x,y ด้วยสี r, g, b
void PutPixel(int x, int y, int r, int g, int b)

ฟังก์ชั่น เขียนตัวอักษรที่ละตัว
void OutCharXY(unsigned char ch,int x,int y,int r, int g,int b)

ฟังก์ชั่น ตรวจสอบว่าเป็นสระบน หรือสระล่าง
int IsNoCol(unsigned char ch)

ฟังก์ชั่น ตรวจสอบว่าเป็นสระที่อยู่เหนือสระอื่นหรือไม่
int IsToneMark(unsigned char ch)

ฟังก์ชั่น ตรวจสอบว่าเป็นสระบนหรือไม่
int IsAbove(unsigned char ch)

ฟังก์ชั่น พิมพ์ภาษาไทย ที่ตำแหน่ง x0, y0 ด้วยสี r, g, b
void OutThai(unsigned char *text, int x0,int y0,int r, int g ,int b)

ลองศึกษา Code ดูนะครับ
แล้วเรามีการเปลี่ยนรูปแสดง เลยต้องแก้ไขไฟล์ใน folder data นิดหน่อยลองเข้าไปดูนะครับ
ครั้งหน้าจะลองให้ รับค่าป่มกดต่างๆ กันครับ




 

Create Date : 25 มิถุนายน 2551    
Last Update : 25 มิถุนายน 2551 19:30:31 น.
Counter : 1236 Pageviews.  

เขียนเกม บนเครื่อง Nintendo DS : การลงสีโดยตรง

ต่อไปเราจะลอง ลงสีที่ละจุดตามที่เราต้องการ
ให้แก้ไข source code จากกระทู้เก่าที่นี้ครับ

ให้ดูบรรทัดที่ commentไว้ แล้วเอาเครื่องหมาย "//" ออกเฉพาะบรรทัดข้างล่าง คือ
int i;
u16* video_buffer_main = (u16*)BG_BMP_RAM(0);

for(i = 0; i < 256 * 2; i++)
video_buffer_main[i] = RGB15(31,0,0) | BIT(15);

แล้วลอง compile ใหม่จะได้ผลลัพธ์ ตามรูป


u16* video_buffer_main = (u16*)BG_BMP_RAM(0);
เป็นการสร้างตัวแปรแบบ pointer ที่ชื่อว่า video_buffer_main ที่จะชี้ไปยังหน่วยความจำที่แสดงผลของหน้าจอหลัก (main)

RGB15(31,0,0) เป็นคำสั่งให้ผสมสี RGB red, Green, Blue ซึ่งมีค่าตั้งแต่ 0 ถึง 31 เป็นจำนวนเต็มนะครับ

BIT(15) เป็นค่าset bit ที่ 15 ให้เป็น 1 เกี่ยวกับค่าความทึบแสง (งงๆเหมือนกัน)

ดังนั้น video_buffer_main[i] = RGB15(31,0,0) | BIT(15); เป็นการให้ค่าสีแดง ตั้งแต่ตำแหน่ง ที่ 0 ถึง 511 แบบ linear
จึงเกิดเป็นเส้นสีแดงสองเส้นด้านบนภาพ

แต่ตามจริงภาพจะมีตำแหน่งในแกน x จาก 0 ถึง 255 และ แกน y จาก 0 ถึง 191 เพราะจอภาพของ DS มีขนาด 256x192
ดังนั้นถ้าต้องการ plot ที่จุด x,y ตามต้องการ ต้องใช้สูตร
i = y * 256 + x
ถ้าต้องการเขียนจุดสีที่ตำแหน่ง x= 4, y =1
ดังนั้น i = 260
video_buffer_main[260] = RGB15(0,31,0) | BIT(15);
ก็จะเกิดจุดสีเขียวที่ตำแหน่ง (4,1)

โอ้ถ้าได้อย่างนี้ ก็ง่ายต่อการเขียนภาษาไทยบน DS แล้วสิ
ครั้งหน้ามาดูการแสดงผลภาษาไทยกันนะครับ

ถ้างงตรงไหนก็ Post มากันครับ ถ้าตอบได้ก็จะตอบให้นะครับ




 

Create Date : 21 มิถุนายน 2551    
Last Update : 21 มิถุนายน 2551 16:36:46 น.
Counter : 700 Pageviews.  

เขียนเกม บนเครื่อง Nintendo DS : ข้อมูล Hardware เบื้องต้น

มาศึกษา Hardware ที่น่าสนใจกันก่อน
จอภาพมี 2 จอ (Main Screen, Sub Screen) ขนาด 256 x 192 pixels
หน่วยความจำ VRAM มีไว้สำหรับเก็บข้อมูล Graphic ก่อนจะนำไปแสดงผล
Mode การแสดงผลมี 8 mode แต่เราจะใช้เฉพาะ MODE_5_2D ทั้ง Main Screen และ Sub Screen
เนื่องจากเลือก Mode 5 การแสดงผลของ Background จึงมี 4 Layer ดังนี้
BG0: Text/3D
BG1: Text
BG2: extended rotation
BG3: extended rotation
Layer คือเหมือนเป็น แผ่นใส่ที่มีรูปแล้ววางซ้อนทับกันให้ภาพใน 1 จอ

ต่อไปมาดูคำสั่งใน source code Chapter01

videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE);
เป็นset Mode การแสดงผล เป็น Mode 5 2D (3D ก็มีแต่ยังศึกษาไม่ถึง เพราะยากมาก) และให้แสดงเฉพาะ Background ที่3

จัดสรรหน่วยความจำ VRAM
เนื่องจากหน่วยความจำมีน้อยมากจึงการจัดสรรให้เต็มประสิทธิภาพที่สุด โดยเราเป็นคนตั้งค่าเองว่าต้องการใช้หน่วยความจำเท่าไร กับงานอะไร
ดังนั้น vramSetBankA(VRAM_A_MAIN_BG_0x06000000);
เป็นการ set หน่วยความจำสำหรับจอ Main Screen และ

คำสั่ง vramSetBankC(VRAM_C_SUB_BG_0x06200000); สำหรับ Sub Screen

และใช้คำสั่ง dmaCopyHalfWords เพื่อ Copy ข้อมูลGraphic ไปยังหน่วยความจำที่เราตั้งค่าไว้
dmaCopyHalfWords(หมายเลขช่องทางที่จะส่ง, ข้อมูลที่จะส่ง, ตำแหน่งที่ส่งไป, ความยาวของข้อมูลที่จะส่ง);

จอบน dmaCopyHalfWords(3, CobraUpBitmap, (uint16 *)BG_BMP_RAM(0), CobraUpBitmapLen);

จอล่าง dmaCopyHalfWords(3, CobraDownBitmap, (uint16 *)BG_BMP_RAM_SUB(0), CobraDownBitmapLen);




 

Create Date : 07 มิถุนายน 2551    
Last Update : 7 มิถุนายน 2551 20:03:27 น.
Counter : 653 Pageviews.  

1  2  3  4  5  6  7  8  

wink99_th
Location :
พิษณุโลก Thailand

[Profile ทั้งหมด]

ฝากข้อความหลังไมค์
Rss Feed
Smember
ผู้ติดตามบล็อก : 8 คน [?]




New Comments
Friends' blogs
[Add wink99_th's blog to your web]
Links
 

 Pantip.com | PantipMarket.com | Pantown.com | © 2004 BlogGang.com allrights reserved.