Hello Tiles

در این درس ، مثال Hello World را توسعه می دهیم و با یاد گرفتن Tile ها به آن رنگ اضافه می کنیم.

بکار بردن Tile

نمایشگر های گرافیکی مانند تلویزیون ، مانیتور کامپیوتر و LCDها تصاویر گرافیکی را با استفاده از اجزایی به نام pixel(picture elements)نمایش میدهند .مانیتورهای VGA قدیمی تصاویر را با وضوح 640×480 پیکسل نمایش می دادند . امروزه نمایشگرهای hi-definition(HD)میتوانند تا وضوح 1920×1080 یا حتی بیشتر را نمایش دهند! Fuzeboxقدرت نمایش تصاویر با وضوح بالا روی نمایشگرهای HD را ندارد اما روی تلویزیون های عادی با رزلوشن 240×224 پیکسل به خوبی کار می کند . شاید به نظر خوب نباشد ولی بیشتر کنسول های بازی 8بیتی هم با همین رزلوشن بودند و بازیهای بسیار جالبی هم داشتند .

بخاطر اینکه در جریان بازی صفحه نمایش تغییر می کند پس باید اطلاعات ویدیویی (video data) در RAM ذخیره شوند . اگر هر پیکسل شامل 8 بیت (یک بایت) دیتا باشد ما به این مقدار از حافظه RAMبرای ذخیره کردن نگاشت ویدیویی (video map) در حافظه نیاز داریم :

 pixels240 wide  * 224 pixels high * 1 byte per pixel = 53760 bytes = 52 KB

گرچه به نظر زیاد نمی آید ولی برای یک میکروکنترلر کوچک این طور نیست چون تمام حافظه RAM در دسترس فقط 4KB است ! و هیچ راهی برای جا دادن دیتا های ویدیویی در RAM نیست ولی با یک ترفند به نام tiling این کار امکان پذیر میشود . اساسا ما میگیم که » OK ، بازی های ساده ی ما یک پس ضمینه دارند که زیاد تغییر نمی کند ویا تکرار می شود . پس بجای اینکه هر پیکسل را به طور جداگانه داشته باشیم ، از یک سری قطعات از پیش تعریف شده به نام tile استفاده می کنیم «. اجازه بدید به عنوان مثال به یک تصویر از بازی Super Mario Brothersکه شناخته شده ترین بازی 8 بیتی هم هست یه نگاه بیندازیم.

می بینید که قطعات زمین کپی هایی از یک tile هستند ؟ همین طور ابرها نیز از قطعات مشابه تشکیل  شدند و آجرها به نظر شبه هم هستند . حتی این تصویر هم رزلوشن 240×224 دارد و از یک شبکه 15×14 از tileهای 16×16 پیکسل ساخته شده (میتونید با شمردن قطعات زمین درستی این حرف را بررسی کنید).

چون Fuzebox قدرت پردازش واقعا بیشتری نسبت به NES اصلی دارد،میتواند از tileهای کوچکتری استفاده کند . کنسول از tileهای 6×8 پیکسل در شبکه 40×28 استفاده می کند . با مقدار دهی به Tile ها ما از بیشتر آنها استفاده می کنیم و با این روش مقدار حافظه گرافیکی مورد نیاز کاهش می یابد . به علاوه چون Tileها تغییر نمی کنند ( آنها فقط جابجا می شوند ) ، ما می توانیم آنها را در حافظه Flash ( که 64K است ) بجای RAM ذخیره کنیم . خوب حالا مشکل حافظه ویدیویی ما حل شد !

اجازه بدید بگیم که ما Tileهای 6×8 پیکسل داریم که احتمالا تعداد آنها حداکثر 512 تا است . پس ما به :

6 * 8 * 512 = 24KB

حافظه Flash برای نگه داری تمام tileها نیاز داریم ( که در نهایت قابل قبوله چون 64K فلش در دسترس داریم ) و در حافظه ویدیویی RAM ما به :

40 * 28 * 2byte address = 2240 = 2KB

از RAM برای ذخیره کردن نقشه جاری نیاز داریم ، که حدود نیمی از 4K حافظه ای است که در دسترس داریم . حالا ما میتونیم واقعا انجامش بدیم !

اولین Tile

OK برید سراغ پروژه hello2 و فایل hello2.c رو باز کنید .

#include <stdbool.h>
#include <avr/io.h>
#include <stdlib.h>
#include <avr/pgmspace.h>
#include "kernel/uzebox.h"
#include "data/fonts.pic.inc"

const char strHello[] PROGMEM ="HELLO TILES FROM THE FUZEBOX!";

//Tile Width=6
//Tile Height=8
const char tiles[] PROGMEM ={
 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF		 //tile #0
};

int main(){
  ClearVram();

  SetTileTable(tiles);
  Fill(0, 0, 40, 28, 0); // fill everything with tile #0

  SetFontTable(fonts);
  Print(7,12,strHello);

  while(1);
}

این فایل خیلی شبه hello world اصلی ست به علاوه کمی تغییرات . مهم ترین قسمت اینه که ما به آن یک tile اضافه کردیم !

//Tile Width=6
//Tile Height=8
const char tiles[] PROGMEM ={
 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF		 //tile #0
};

همانند رشته ها Tileها هم در حافظه برنامه ( program memory ) ذخیره می شوند ، چون تغییر نمی کنند و همچنین فضای بیشتری در فلش وجود دارد ، پس فلگ های const و PROGMEM را می نویسیم . هر قطعه از تعدادی بایت ساخته می شود با عرض 6 و طول 8 . هر بایت شامل ارزش یک پیکسل است و هر پیکسل/بایت شامل 8 بیت دیتای رنگی است . دیتای رنگی از اجزای قرمز ، سبز و آبی ساخته شده . با ترکیب آنها 256 رنگ ممکن بدست می آید متاسفانه رنگهای اصلی به طور مساوی در 8بیت تقسیم نمی شوند و فقط 2 بیت برای رنگ آبی بجای 3 بیت در نظر گرفته می شود .

بنا بر این اگر می خواهید رنگ سفید روشن درست کنید ، به سادگی تمام رنگها را با هم ترکیب کنید : 0xFF

برای سیاه ( نبود هیچ رنگی ) ، هیچ دیتای رنگی نداریم : 0x00

برای آبی روشن ، فقط 2 بیت بالا : 0xC0

برای قرمز روشن ، فقط 3 بیت پایین : 0x07

برای فیروزه ای ترکیب آبی و سبز یعنی 5 بیت بالایی : 0xF8

و غیره .

پس حالا که می دانید که رنگها چه طور ذخیره می شوند ، رنگ tile در کد Hello World2 را حدس بزنید و درست بودن آنرا با کامپایل کردن و آپلود کردن برنامه در Fuzebox تحقیق کنید .

پوشاندن صفحه با tileها

بیایید کمی کد بنویسیم و امتحان کنیم

int main(){
  ClearVram();

  SetTileTable(tiles);
  Fill(0, 0, 40, 28, 0); // fill everything with tile #0

  SetFontTable(fonts);
  Print(7,12,strHello);

  while(1);
}

درست مثل قبل ، پروسیجر main را داریم که با یک حلقه انتظار تمام میشود . خط اول کد video ram را پاک می کند ، که قبلا دیده بودیم .خط بعد پروسیجری است که جدول tile را مقداردهی می کند .

  SetTileTable(tiles);

این مجموعه ی قطعات موزاییکی است که ما برای کشیدن بک گراند زمین بازی به آنها رجوع می کنیم . برای مثال اینجا یک مجموعه ی آماتوری tile های بازی Mario را می بینید :

می بینید که تقریبا تمام قطعاتی که در بازی super Mario وجود دارد در اینجا آورده شده . واقعا به طور شگفت آوری تعداد کمی قطعه برای نمایش بک گراند بازی نیاز است ! اما در نهایت ما از یک ابزار کمکی برای ایجاد نقشه و جدول tileها استفاده می کنیم ، ولی حالا برای کسب تجربه به صورت دستی این کار را می کنیم .

خط بعدی فرا خوانی پروسیجری از کرنل به نام Fill است . Fill( x , y , w , h , tile# ) همان کاری را می کند که انتظار داریم . آن یک مستطیل از قطعات ایجاد می کند که تمام آن با یک tile پوشیده شده است ، در این مورد tile شماره #0 ، اولین ( و تنها ) قطعه این جدول .

  Fill(0, 0, 40, 28, 0); // fill everything with tile #0

 

هک کردن جدول قطعات

OK حالا نوبت شماست .tile را ویرایش کنید تا رنگ و طراحی آن تغییر کند .

  • رنگ بک گراند را تماما قرمز ، سبز یا آبی کنید
  • رنگ آنرا سفید کنید با نقطه های فرمز
  • بک گراند را با خطوط نازک راه راه کنید

Tile #2

OK حالا که به راحتی با tile خودتون می تونید کار کنید ، اجازه بدید قطعه دوم را هم اضافه کنیم !

کدهای hello2.c را با کد های زیر جایگزین کنید :

#include <avr/io.h>
#include <stdlib.h>
#include <avr/pgmspace.h>
#include "kernel/uzebox.h"
#include "data/fonts.pic.inc"

const char strHello[] PROGMEM ="HELLO TILES FROM THE FUZEBOX!";

//Tile Width=6
//Tile Height=8
const char tiles[] PROGMEM ={
 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,		 //tile #0 

 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0		 //tile #1
};

int main(){
  ClearVram();

  SetTileTable(tiles);
  Fill(0, 0, 40, 28, 0); // fill everything with tile #0

  SetFontTable(fonts);
  Print(7,12,strHello);

  while(1);
}

دقت کنید که قطعه دوم دقیقا بعد از اولی شروع میشود و این یک تکه بزرگ دیتای پشت سر هم است . رنگ قطعه دوم چیست ؟

حالا کد را تغییر می دهیم تا بک گراند با قطعه دوم پوشیده شود ( شماره ایندکس قطعه دوم  #1 است واین کمی گیج کننده است )

حالا یک خط بعد از Fill(…) اضافه کنید که یک مستطیل دیگر به عنوان حاشیه برای متن ایجاد کند شبیه این :

منبع:

http://www.ladyada.net/make/fuzebox/hellotile.html

پایان !

Advertisements

دربارهٔ DeltaCode

Somewhere near the sky Far away from people Far away from noise Somewhere near yourself

Posted on اوت 24, 2011, in AVR. Bookmark the permalink. ۱ دیدگاه.

  1. لذت بردم عالی بود

پاسخی بگذارید

در پایین مشخصات خود را پر کنید یا برای ورود روی شمایل‌ها کلیک نمایید:

نشان‌وارهٔ وردپرس.کام

شما در حال بیان دیدگاه با حساب کاربری WordPress.com خود هستید. بیرون رفتن / تغییر دادن )

تصویر توییتر

شما در حال بیان دیدگاه با حساب کاربری Twitter خود هستید. بیرون رفتن / تغییر دادن )

عکس فیسبوک

شما در حال بیان دیدگاه با حساب کاربری Facebook خود هستید. بیرون رفتن / تغییر دادن )

عکس گوگل+

شما در حال بیان دیدگاه با حساب کاربری Google+ خود هستید. بیرون رفتن / تغییر دادن )

درحال اتصال به %s

%d وب‌نوشت‌نویس این را دوست دارند: