Yoti можешь ещё раз разъяснить для таких тугодумов как я:homebrew может использовать все возможности psp(все медиакодеки,всю ОЗУ,CPU-кеш,библиотеки и т.д.)?То есть homebrew-это игры,ограниченные лишь самой консолью?
Denil X,
какое именно homebrew? Usermode homebrew абсолютно аналогично по возможностям игре, купленной в PSN.
Да именно возможности UM Homebrew,я так понял возможности написания кода для всех видов игр одинаковы.И ту же самую GTA можно было бы написать в виде хоумбрюшки,я правильно понимаю?То бишь iso игры отличаются лишь форматом,удобоваримом для чтения с UMD диска.А homebrew выпускают в виртуальном магазе что бы не тратить UMD диски за зря.Если я правильно понял-"нажми любой крестик для подтверхдения"
Другие консоли: Все PSP, все PSV, SCPH-1002, SCPH-102, SCPH-77008, CECH-4208C, SCPH-1000R
Регистрация: 19.03.2008
Адрес: Россия
Сообщений: 5,731
Вы сказали Спасибо: 818
Поблагодарили 3,834 раз(а) в 2,013 сообщениях
Сила репутации: 1
Репутация: 3834 
(репутация неоспорима)
Denil X,
PSN игры содержат образ типа NP-UMD под именем DATA.PSAR и какой-то простенький загрузчик. Смотри темы про подпись ISO и как оно получается на входе и на выходе.
Всем привет. Многие скорее всего уже забыли/продали/потеряли свою PSP, а мне захотелось покодить. Возможно свою PSP я куда-нибудь приспособлю для дальнейшего использования.
Начал кодить с gu. Разобрался с примером cube, написал свой загрузчик *.obj файлов под разные vtype флаги у sceGumDrawArray(). Тем не менее я надолго застрял с загрузкой текстур в sceGuTexImage(), где используется data не пойми какой структуры. Скорее всего это RGBA структура выровненная по 16 bytes, но все же мне не удалось из простой *.bmp правильно выгрузить текстуру. Пример:
struct COLOR
{
float r, g, b, a;
};
Image.h
#ifndef __IMAGE_H__
#define __IMAGE_H__
#include <stdlib.h>
#include <stdio.h>
#include "StructsExtended.h"
#define __attribute__(x)
class Image
{
public:
static void Read_BMP(const char* path, struct COLOR __attribute__((aligned(16)))* data, unsigned long* size);
};
void Image::Read_BMP(const char* path, struct COLOR __attribute__((aligned(16)))* data, unsigned long* size)
{
int i;
FILE* f = fopen(path, "rb");
if (f == NULL) {
return;
}
unsigned char info[54];
fread(info, sizeof(unsigned char), 54, f); // read the 54-byte header
// extract image height and width from header
int width = *(int*)&info[18];
int height = *(int*)&info[22];
(*size) = width * height * 3;
unsigned char* tmp_data = (unsigned char*)malloc(sizeof(unsigned char) * (*size));
fread(tmp_data, sizeof(unsigned char), (*size), f); // read the rest of the data at once
fclose(f);
//In the last part, the swap between every first and third pixel is done
// because windows stores the color values as (B, G, R) triples, not (R, G, B).
unsigned long curr_data_index = 0;
for (i = 0; i < (*size); i += 3)
{
(data + curr_data_index)->b = *(tmp_data + i);
(data + curr_data_index)->g = *(tmp_data + i + 1);
(data + curr_data_index)->r = *(tmp_data + i + 2);
curr_data_index++;
}
free(tmp_data);
}
#endif // !__IMAGE_H__
Тогда я начал копать и наткнулся на выше упомянутый graphic.h, у которого есть своя реализация загрузки картинок, что меня сильно обрадовало, но попытавшись его подключить я наткнулся на ошибки рода:
1>------ Сборка начата: проект: 3d obj loader, Конфигурация: Debug Win32 ------
1> psp-gcc -I. -ID:/PSP/pspsdk/psp/sdk/include -O2 -G0 -Wall -D_PSP_FW_VERSION=150 -L. -LD:/PSP/pspsdk/psp/sdk/lib morph.o d:/PSP/pspsdk/psp/sdk/samples/gu/common/callbacks.o d:/PSP/pspsdk/psp/sdk/samples/gu/common/vram.o d:/PSP/pspsdk/psp/sdk/samples/intraFont/graphics/graphics.o d:/PSP/pspsdk/psp/sdk/samples/intraFont/graphics/framebuffer.o -lpspgum -lpspgu -lpng -lpspgum -lm -lz -lpspdebug -lpspdisplay -lpspge -lpspctrl -lpspsdk -lc -lpspnet -lpspnet_inet -lpspnet_apctl -lpspnet_resolver -lpsputility -lpspuser -lpspkernel -o morph.elf
1> morph.o: In function `main':
1> morph.cpp.text+0x7e0): undefined reference to `loadImage(char const*)'
1> make: *** [morph.elf] Error 1
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140\Microsoft.MakeFile.Targets(41,5): error MSB3073: выход из команды "make" с кодом 2.
========== Сборка: успешно: 0, с ошибками: 1, без изменений: 0, пропущено: 0 ==========
Сразу говорю, что в конструкции Makefile'а я плохо разбираюсь, а так же какие libs нужно подключать и т.д., несмотря на то, что компилировать через консоль мне приходилось и что-то в этом я все же понимаю.
Программа расположена в папке d:\PSP\CodingTests\3d obj loader
PSPSDK находится в папке d:\PSP\pspsdk
Продолжив мучатся я понял, что намного проще будет использовать библиотеки совместимые с RISC архитектурой. Впрочем, как в PSPSDK и понапихано Поэтому нашел простенький png загрузчик использующий использующий png.h:
#ifndef __IMAGE_H__
#define __IMAGE_H__
#include <stdlib.h>
#include <stdio.h>
#include <png.h>
#include "StructsExtended.h"
class Image
{
public:
int width, height;
png_byte color_type;
png_byte bit_depth;
png_bytep *row_pointers;
void read_png_file(const char *path);
void write_png_file(const char *path);
};
void Image::read_png_file(const char* path)
{
FILE *fp = fopen(path, "rb");
png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png) abort();
png_infop info = png_create_info_struct(png);
if (!info) abort();
if (setjmp(png_jmpbuf(png))) abort();
png_init_io(png, fp);
png_read_info(png, info);
width = png_get_image_width(png, info);
height = png_get_image_height(png, info);
color_type = png_get_color_type(png, info);
bit_depth = png_get_bit_depth(png, info);
// Read any color_type into 8bit depth, RGBA format.
// See http://www.libpng.org/pub/png/libpng-manual.txt
if (bit_depth == 16)
png_set_strip_16(png);
if (color_type == PNG_COLOR_TYPE_PALETTE)
png_set_palette_to_rgb(png);
// PNG_COLOR_TYPE_GRAY_ALPHA is always 8 or 16bit depth.
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
png_set_expand_gray_1_2_4_to_8(png);
if (png_get_valid(png, info, PNG_INFO_tRNS))
png_set_tRNS_to_alpha(png);
// These color_type don't have an alpha channel then fill it with 0xff.
if (color_type == PNG_COLOR_TYPE_RGB ||
color_type == PNG_COLOR_TYPE_GRAY ||
color_type == PNG_COLOR_TYPE_PALETTE)
png_set_filler(png, 0xFF, PNG_FILLER_AFTER);
if (color_type == PNG_COLOR_TYPE_GRAY ||
color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
png_set_gray_to_rgb(png);
png_read_update_info(png, info);
row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * height);
for (int y = 0; y < height; y++) {
row_pointers[y] = (png_byte*)malloc(png_get_rowbytes(png, info));
}
png_read_image(png, row_pointers);
fclose(fp);
}
void Image::write_png_file(const char *path)
{
int y;
FILE *fp = fopen(path, "wb");
if (!fp) abort();
png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png) abort();
png_infop info = png_create_info_struct(png);
if (!info) abort();
if (setjmp(png_jmpbuf(png))) abort();
png_init_io(png, fp);
// Output is 8bit depth, RGBA format.
png_set_IHDR(
png,
info,
width, height,
8,
PNG_COLOR_TYPE_RGBA,
PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT,
PNG_FILTER_TYPE_DEFAULT
);
png_write_info(png, info);
// To remove the alpha channel for PNG_COLOR_TYPE_RGB format,
// Use png_set_filler().
//png_set_filler(png, 0, PNG_FILLER_AFTER);
png_write_image(png, row_pointers);
png_write_end(png, NULL);
for (int y = 0; y < height; y++) {
free(row_pointers[y]);
}
free(row_pointers);
fclose(fp);
}
#endif // !__IMAGE_H__
Боюсь, помощи с графикой долго ждать придётся. У нас разве что Ilsor что-то делал на этот счёт. Смотри его темы, может примеры кода подберёшь какие…
Боюсь мне другого и не остается.
Пока что я застрял на правильном отображении текстуры на загружаемом *.obj . Для элементарной отладки нарисовал в Blender'e параллелепипед и натянул на него текстуру "спичечного коробка".
Модель спичечного коробка
v -2.958658 -2.038629 3.805706
v -2.958658 -0.038629 3.805706
v -2.958658 -2.038629 -3.352732
v -2.958658 -0.038629 -3.352732
v 2.076324 -2.038629 3.805706
v 2.076324 -0.038629 3.805706
v 2.076324 -2.038629 -3.352732
v 2.076324 -0.038629 -3.352732
vt 0.002347 0.075742
vt 0.701126 0.277643
vt 0.002347 0.277644
vt 0.068838 0.261809
vt 0.411862 0.320771
vt 0.068838 0.320771
vt 0.699870 0.077725
vt -0.002597 0.272442
vt 0.699870 0.272442
vt 0.001634 0.285340
vt 0.481343 0.310242
vt 0.481343 0.285340
vt -0.000594 0.987048
vt 0.480016 0.269660
vt 0.480016 0.987048
vt 0.961166 0.289394
vt 0.482478 0.999686
vt 0.482478 0.289393
vt 0.701126 0.075742
vt 0.411862 0.261809
vt -0.002597 0.077725
vt 0.001634 0.310242
vt -0.000594 0.269660
vt 0.961166 0.999686
vn -1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 0.0000 1.0000
vn 0.0000 -1.0000 0.0000
vn 0.0000 1.0000 0.0000
g Cube_Cube.001_Material.001
usemtl Material.001
s off
f 2/1/1 3/2/1 1/3/1
f 4/4/2 7/5/2 3/6/2
f 8/7/3 5/8/3 7/9/3
f 6/10/4 1/11/4 5/12/4
f 7/13/5 1/14/5 3/15/5
f 4/16/6 6/17/6 8/18/6
f 2/1/1 4/19/1 3/2/1
f 4/4/2 8/20/2 7/5/2
f 8/7/3 6/21/3 5/8/3
f 6/10/4 2/22/4 1/11/4
f 7/13/5 5/23/5 1/14/5
f 4/16/6 2/24/6 6/17/6
Используя ручную трассировку (на бумажке вырисовывал ), то получилось так, что по логике вещей все должно работать, поскольку каждый vertex из структуры...
struct Vertex_UVColorNormalXYZ
{
float u, v;
unsigned int color;
float normal_x, normal_y, normal_z;
float x, y, z;
};
...содержит корректные координаты [U,V] для mapping'а.
Единственное, где я действительно плаваю, это текстурные настройки (хотя я уже все перерыл и перепробовал всевозможные комбинации), а так же в выравнивании data текстуры по 16 байт, как требует void sceGuTexImage:
Note: Data must be aligned to 1 quad word (16 bytes)
Пока же data от текстуры просто
png_bytep *row_pointers;
// а он в свою очередь
typedef png_byte FAR * png_bytep;
//т.е.
typedef unsigned char png_byte;
Оказалось, что дело было в выравнивании.
Вот, настряпал "страшный код", для большего понимания того, что происходит, и, как оказалось, на нем все заработало...
struct COLOR
{
unsigned char r, g, b, a;
};
struct COLOR __attribute__((aligned(16))) *img_data = (struct COLOR __attribute__((aligned(16))) *)malloc(sizeof(struct COLOR __attribute__((aligned(16)))) * img_tmp.width * img_tmp.height);
unsigned long img_index = 0;
for (int y = 0; y < img_tmp.height; y++)
{
for (int x = 0; x < img_tmp.width * img_tmp.bit_depth; x += 4)
{
img_data[img_index].r = img_tmp.row_pointers[y][x];
img_data[img_index].g = img_tmp.row_pointers[y][x + 1];
img_data[img_index].b = img_tmp.row_pointers[y][x + 2];
img_data[img_index].a = img_tmp.row_pointers[y][x + 3];
img_index++;
}
}
Т.е. я просто перевел в RGBA структуру с выравниванием по 16 байт, как требует sdk. И вот какой результат вышел.
Правда, как вы могли заметить, некоторые элементы теряются (в основном обрезанные края текстуры). Например: "шеркалка" вовсе съехала. Да и сама картинка имеет нечеткое отображение.
О боже... Все оказалось намного проще.
Image::read_png_file как-то повернул / перевернул картинку. Я сейчас просто сижу и пытаюсь подобрать алгоритм, чтобы ее восстановить так, чтобы UV координаты оказались на нужных местах
PS: так и не понятно для чего нужно выравнивание...
Наконец-то. Оказалось, что в png_bytep, в котором хранилась текстура был далеко не "квадратным" динамическим массивом, и количество столбцов каждой строки было разным, поэтому пришлось добавить немного ухищрений для того, чтобы правильно пересобрать текстуру.
public:
//...
// для хранения количества столбцов каждой строки
png_size_t *row_weight_size;
//...
// в void Image::read_png_file
row_weight_size = (png_size_t *)malloc(sizeof(png_size_t) * height);
row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * height);
for (int y = 0; y < height; y++) {
row_weight_size[y] = png_get_rowbytes(png, info);
row_pointers[y] = (png_byte*)malloc(row_weight_size[y]);
}
//...
// функция восстановления текстуры
void Image::png_data(struct COLOR *img_data)
{
unsigned long img_data_index = 0;
for (int y = height - 1; y >= 0; y--) {
for (int x = 0; x < row_weight_size[y]; x+=4) {
img_data[img_data_index].r = row_pointers[y][x];
img_data[img_data_index].g = row_pointers[y][x + 1];
img_data[img_data_index].b = row_pointers[y][x + 2];
img_data[img_data_index].a = row_pointers[y][x + 3];
img_data_index++;
}
}
}
Как работать с библиотеками при портировании игр на PSP?
Хочу портировать игру Terraria на PSP. Но не могу разобраться. Нашёл SDK называется Minimalist PSPSDK. Написал пару простых прог типа калькулятора и текстового редактора. Но как зашло до игр и графики появилась нужда использовать сторонние библиотеки. Типа math,png,opengl,graphics но не могу разобраться как это делать. Компилировал через make.bat. Хочу разобраться как работать с библиотеками я слышал они обозначаются форматом *.a и хедером *.h . Но не могу найти никакой из них,как и куда их устанавливать,где взять доки. И есть вопрос что такое PspDebugScreenSetXY()?