codingva1en0k/ fromxa@va1en0k.net /КарманныйбильярдПрокачиваем PlayStation: Portable. часть втораяВероятно, ты читал первую часть статьи. Там речь шла о том, как выводитьтекст на экран, а также о простейшей экранной клавиатуре и какой-никакойотладке. Теперь, когда с debug mode (так называется текстовый режим)более-менее покончено, пришло время разобрать основной арсенал двухмерногокодера.Как пройти в библиотеку?Среди всего скачанного на твой компьютер месяц назад не было библиотек,которые мы собираемся использовать сегодня, а именно — zlib и libpng.Поэтому самое время запустить Cygwin Shell и начать получать их из репозитария.Устанавливаются библиотеки так:svn checkout svn://svn.pspdev.org/psp/trunk/zlibcd zlibmakemake installcd ..rm -Rf zlibsvn checkout svn://svn.pspdev.org/psp/trunk/libpngcd libpngmakemake installrm -Rf libpngВ результате последовательного запуска этих команд на компьютер будут092скачаны исходные коды библиотек (svn checkout), после чего выполнитсясборка (make) и установка (make install). В конце, в целях экономииместа и чтобы не смущать программиста, директории с исходниками будутудалены (rm -Rf).Теперь можно переходить к использованию скачанного кода. Открываемнаш старый main.cpp (или как ты его назвал?) и, истории ради сохранивего под другим именем, начинаем модифицировать. Первое, что мы напишем— мозаику из кучи логотипов «][акера» (логотип 16 на 16 в формате PNGты найдешь на диске). Конечно, никто не мешает тебе взять любую другуюкартинку, преобразовав ее в PNG и поменяв название.Переименуем нашу программу, изменив первый параметр макроса, которыйзадает информацию о модуле:PSP_MODULE_INFO("<strong>Xakep</strong> Logos", 0, 1, 1);Теперь изменим секцию инклудов, добавим в нее новые библиотечныефайлы:#include #include #include xàêåð 07 /115/ 08
codingВот что бывает, если забывать очищать экран#include #include #include #include #include"graphics.h"Как видишь, появились некоторые новые заголовочные файлы, например,graphics.h (описывает некоторые полезные в работе с картинкамифункции). Возьми его на диске вместе с graphics.c, framebuffer.c иframebuffer.h и положи в папку с основным файлом. В них содержитсякод, который в противном случае пришлось бы писать самому.Ну что ж, определим простой макрос:#define printf pspDebugScreenPrintfОн всего лишь позволяет обращаться к функции pspDebugScreenPrintf— как будто это функция printf. Как ты помнишь, их формат и назначение абсолютносовпадают, так что макрос повысит читабельность кода и упроститпрограммирование.«Странные» функции ExitCallback(), CallbackThread() иSetupCallbacks() остаются без изменений, потому что никаких новыхкаллбэков нам не потребуется, а выход из программы все равно долженпроисходить. Всю функцию main() придется заменить на новый код,который ты можешь рассмотреть на соответствующей врезке или глянуть надиске (сначала смотрим код и пишем, потом — разбираем).Ну и наконец, совершим новый Makefile, учитывающий тот факт, что у настеперь четыре файла вместо двух и новые библиотеки:TARGET = helloOBJS = main.o graphics.o framebuffer.oCFLAGS = -O2 -G0 -WallCXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rttiASFLAGS = $(CFLAGS)LIBDIR =LIBS = -lpspgu -lpng -lz -lmLDFLAGS =EXTRA_TARGETS = EBOOT.PBPPSP_EBOOT_TITLE = Image ExamplePSPSDK=$(shell psp-config --pspsdk-path)include $(PSPSDK)/lib/build.makРабота с графикойРазберем представленный листинг (когда соберешь его командой make истанешь закидывать на приставку, не забудь скопировать туда же картинкуxakep.png с диска!). Код почти всех новых функций содержится в graphics.cpp и его можно посмотреть в любой момент, поэтому я ограничусь простымописанием. Структура Image хранит четыре значения помимо самой картинки:ее размеры (Image::imageHeight — высота и Image::imageWidth— ширина) и два значения, описывающие размеры двухмерного массива цветовColor* data, в котором хранится картинка как набор разноцветных точек.Функция blitAlphaImageToScreen() отображает картинку или ее частьна экране (в виде прямоугольника). Первые два аргумента — координатывыводимого прямоугольника на хранящейся в памяти картинке, еще двапараметра — его размеры (если выводим всю картинку, то параметры должныбыть 0, 0, ourImageimageWidth, ourImageimageHeight).Потом идет ссылка на структуру с картинкой (типа Image) и координатына экране выводимого прямоугольника (мы задаем их как произведениеширины или высоты на номер текущего столбца или строки, которые перечисляютсяв цикле). Ну, а flipScreen() меняет экран на содержимоевидеопамяти, в которую мы запихивали картинки.Помимо blitAlphaImageToScreen() в graphics.cpp есть еще несколькопохожих функций. Например, blitImageToScreen() действуеттакже, но учитывает альфа-канал (еще 8 бит в структуре Color, отвечающиеза прозрачность точки). «Сестры» blitAlphaImageToImage() иblitImageToImage() отличаются тем, что копируют картинку или еекусок не на экран, а в другую структуру типа Image, ссылка на которуюпередается им последним аргументом. Вместо вызова loadImage() дляполучения картинки из файла можно воспользоваться createImage()(два параметра: ширина и высота будущей картинки) — она возвращаетуказатель на пустую черную картинку заданных размеров. После манипуляцийс картинкой ее можно очистить и залить цветом: clearImage() (опятьдва параметра: цвет и указатель на картинку). Цвет тут задается структуройтипа Color, создать которую можно при помощи макроса RGB:Color red = RGB(255, 0, 0);Точно также можно очистить и весь экран: clearScreen(RGB(0, 255,0)). Отдельный прямоугольник на картинке или экране можно залить припомощи функций fillImageRect или fillScreenRect, передав цвет,координаты и размеры прямоугольника, а для fillImageRect — еще и указательна картинку, последним аргументом. Отдельный пиксель на экранеили картинке задается функциями putPixelScreen или putPixelImage;их параметры: цвет, координата по Х (по горизонтали, от нуля до 272, если наэкране) и по У (по вертикали, на экране может быть от нуля до 480); ну а получитьего цвет можно через getPixelScreen и getPixelImage (параметры— координаты Х или У, ну и указатель, если функция работает с картинкой).На картинке можно написать и текст: printTextImagе; координаты текста— это два первых параметра, потом идет указатель на строку, цвет и указательна картинку. Еще пара функций: drawLineScreen и drawLineImage рисуютлинии, если передать им координаты точек начала и конца и цвет:sceDisplayWaitVblankStart();drawLineScreen(10, 10, 70, 70, RGB(255, 0, 0));drawLineScreen(10, 70, 70, 10, RGB(0, 255, 0));flipScreen();Если написать это вместо всего, что касается картинки в main(), то можноувидеть зеленую и красную линию крест-накрест, как на скрине.Простые движенияПопробуем теперь заставить этот крест ездить по экрану. Если ты внимательночитал первую статью (хотя бы часть про кнопки), у тебя не будет сэтим проблем:SceCtrlData pad;int x=0, y=0;while(1) {sceDisplayWaitVblankStart();sceCtrlReadBufferPositive(&pad, 1);if (pad.Buttons & PSP_CTRL_UP) y -= 10;if (pad.Buttons & PSP_CTRL_DOWN) y += 10;if (pad.Buttons & PSP_CTRL_LEFT) x -= 10;if (pad.Buttons & PSP_CTRL_RIGHT) x += 10;drawLineScreen(x + 10, y + 10, x + 70, y + 70,RGB(255, 0, 0));drawLineScreen(x + 10, y + 70, x + 70, y + 10,xàêåð 07 /115/ 08093