PSPx форум

PSPx форум (https://www.pspx.ru/forum/index.php)
-   Программирование для PSP (https://www.pspx.ru/forum/forumdisplay.php?f=101)
-   -   Горячая линия по программированию (https://www.pspx.ru/forum/showthread.php?t=35747)

Denil X 06.08.2014 21:54

Yoti можешь ещё раз разъяснить для таких тугодумов как я:homebrew может использовать все возможности psp(все медиакодеки,всю ОЗУ,CPU-кеш,библиотеки и т.д.)?То есть homebrew-это игры,ограниченные лишь самой консолью?

Yoti 10.08.2014 21:04

jtg,
Пример
Код:

int i1 = 0, i2 = 0;

int CreateThread_Thread1(SceSize args, void*argp)
{
        while(1)
        {
                i1 = i1 + 1;
                sceKernelDelayThread(0.05*1000*1000);
        }

        return 0;
}

int CreateThread_Thread2(SceSize args, void*argp)
{
        while(1)
        {
                i2 = i2 + 2;
                sceKernelDelayThread(0.10*1000*1000);
        }

        return 0;
}

int CreateThread(void)
{
        SceUID thid;

        thid = sceKernelCreateThread("thread1", CreateThread_Thread1, 0x11, 0xFA0, 0, 0);
        if (thid >= 0)
                sceKernelStartThread(thid, 0, 0);
        else
                return -1;

        thid = sceKernelCreateThread("thread2", CreateThread_Thread2, 0x11, 0xFA0, 0, 0);
        if (thid >= 0)
                sceKernelStartThread(thid, 0, 0);
        else
                return -2;

        while(1)
        {
                printf("%i/%i\n", i1, i2);
                sceKernelDelayThread(0.5*1000*1000);
        }

        return 0;
}


Вызываешь CreateThread(), видишь на экране то, что числа растут независимо.

Denil X,
какое именно homebrew? Usermode homebrew абсолютно аналогично по возможностям игре, купленной в PSN.

Denil X 11.08.2014 00:25

Цитата:

Сообщение от Yoti (Сообщение 1088430)
Denil X,
какое именно homebrew? Usermode homebrew абсолютно аналогично по возможностям игре, купленной в PSN.

Да именно возможности UM Homebrew,я так понял возможности написания кода для всех видов игр одинаковы.И ту же самую GTA можно было бы написать в виде хоумбрюшки,я правильно понимаю?То бишь iso игры отличаются лишь форматом,удобоваримом для чтения с UMD диска.А homebrew выпускают в виртуальном магазе что бы не тратить UMD диски за зря.Если я правильно понял-"нажми любой крестик для подтверхдения":)

Yoti 12.08.2014 09:56

Denil X,
PSN игры содержат образ типа NP-UMD под именем DATA.PSAR и какой-то простенький загрузчик. Смотри темы про подпись ISO и как оно получается на входе и на выходе.

DDS(present) 15.04.2018 16:33

Всем привет. Многие скорее всего уже забыли/продали/потеряли свою 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

Мой Makefile
Код:

TARGET = morph
OBJS = 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

INCDIR =
CFLAGS = -O2 -G0 -Wall
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)

LIBDIR =
LDFLAGS =
LIBS =  -lpspgum -lpspgu -lpng -lpspgum -lm -lz

EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = 3d obj loader

PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak

PS: модель автобуса загружается отлично (пример).

DDS(present) 15.04.2018 20:23

Продолжив мучатся я понял, что намного проще будет использовать библиотеки совместимые с RISC архитектурой. Впрочем, как в PSPSDK и понапихано :acute: Поэтому нашел простенький 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__

Настройка вывода текстур:

Код:

        Image img_tmp;
        img_tmp.read_png_file("bus_d_low.png");
        //...
       
        //...
        // setup texture
        sceGuTexMode(GU_PSM_8888, 0, 0, 0);
        sceGuTexImage(0, img_tmp.width, img_tmp.height, img_tmp.width, (void*)img_tmp.row_pointers);
        sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGB);

И на выходе получилось следующее...

Yoti 16.04.2018 11:42

Боюсь, помощи с графикой долго ждать придётся. У нас разве что Ilsor что-то делал на этот счёт. Смотри его темы, может примеры кода подберёшь какие…

DDS(present) 16.04.2018 18:37

Цитата:

Сообщение от Yoti (Сообщение 1140217)
Боюсь, помощи с графикой долго ждать придётся. У нас разве что 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

Но, как не странно выходит вот это.

Используя ручную трассировку (на бумажке вырисовывал :good:), то получилось так, что по логике вещей все должно работать, поскольку каждый 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 координаты оказались на нужных местах :suicide:

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++;
                }
        }
}

И непосредственно сам вызов:

Код:

        Image img_tmp;
        img_tmp.read_png_file("Models/matchbook.png");

        struct COLOR *img_data = (struct COLOR*)malloc(sizeof(struct COLOR) * img_tmp.height * img_tmp.width);
        img_tmp.png_data(img_data);

Спичечный коробок
Автобус

WasTaz 28.05.2019 21:38

Как работать с библиотеками при портировании игр на PSP?
 
Хочу портировать игру Terraria на PSP. Но не могу разобраться. Нашёл SDK называется Minimalist PSPSDK. Написал пару простых прог типа калькулятора и текстового редактора. Но как зашло до игр и графики появилась нужда использовать сторонние библиотеки. Типа math,png,opengl,graphics но не могу разобраться как это делать. Компилировал через make.bat. Хочу разобраться как работать с библиотеками я слышал они обозначаются форматом *.a и хедером *.h . Но не могу найти никакой из них,как и куда их устанавливать,где взять доки. И есть вопрос что такое PspDebugScreenSetXY()? :dash::dash::dash::suicide:

gpav887 02.06.2022 12:09

Здарова, есть ли команда которая выполняет функцию команы sleep(); ?

AlanKerneH 04.02.2024 00:03

Помогите пожалуйста, хотел скачать PSPxIDE а он перекидывает на этот сайт:
https://fastpic.org/view/123/2024/02...ced2b.png.html

ErikPshat 04.02.2024 06:08

Цитата:

Сообщение от AlanKerneH (Сообщение 1279011)
хотел скачать PSPxIDE

Обычно используют Minimalist PSPSDK или здесь.
Есть ещё Dev-C++ IDE.


Текущее время: 08:01. Часовой пояс GMT +3.

Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2024, vBulletin Solutions, Inc. Перевод: zCarot
PSPx Forum - Сообщество фанатов игровых консолей.