Merge pull request #76 from h4570/feature/floors

Floors sample refactor, PNGLoader refactor
This commit is contained in:
Sandro Sobczyński
2020-12-26 17:30:35 +01:00
committed by GitHub
10 changed files with 65 additions and 115 deletions
+3 -2
View File
@@ -77,8 +77,9 @@ void Engine::firePS2()
{ {
SifInitRpc(0); SifInitRpc(0);
srand(time(NULL)); srand(time(NULL));
fileService.startThread(); // fileService.startThread();
audio.startThread(&fileService); // audio.startThread(&fileService);
audio.startThread(NULL);
isInitialized = 0; isInitialized = 0;
mainThreadId = GetThreadId(); mainThreadId = GetThreadId();
} }
+1 -1
View File
@@ -32,7 +32,7 @@ public:
void init(Game *t_game, u32 t_gifPacketSize); void init(Game *t_game, u32 t_gifPacketSize);
void setDefaultScreen(); void setDefaultScreen();
Renderer *renderer; Renderer *renderer;
FileService fileService; // FileService fileService;
Audio audio; Audio audio;
ScreenSettings screen; ScreenSettings screen;
Pad pad; Pad pad;
+1 -1
View File
@@ -126,7 +126,7 @@ public:
private: private:
u8 songLoaded, volume, realVolume, songPlaying, songInLoop, songFinished; u8 songLoaded, volume, realVolume, songPlaying, songInLoop, songFinished;
std::vector<AudioListenerRef> songListeners; std::vector<AudioListenerRef *> songListeners;
FILE *wav; FILE *wav;
audsrv_fmt_t format; audsrv_fmt_t format;
FileService *fileService; FileService *fileService;
+11 -68
View File
@@ -38,13 +38,11 @@ void PngLoader::load(Texture &o_texture, char *t_subfolder, char *t_name, char *
char *path = String::createConcatenated(path_part2, t_extension); char *path = String::createConcatenated(path_part2, t_extension);
delete[] path_part1; delete[] path_part1;
delete[] path_part2; delete[] path_part2;
FILE *file = fopen(path, "rb"); FILE *file = fopen(path, "rb");
if (file == NULL) if (file == NULL)
{ PRINT_ERR("Failed to open .png file!");
PRINT_ERR("Failed to load .png file!");
return;
}
png_structp png_ptr; png_structp png_ptr;
png_infop info_ptr; png_infop info_ptr;
@@ -56,29 +54,15 @@ void PngLoader::load(Texture &o_texture, char *t_subfolder, char *t_name, char *
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL, NULL, NULL); png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL, NULL, NULL);
if (!png_ptr) if (!png_ptr)
{ PRINT_ERR("PNG struct info init failed(1)!");
printf("PNG Read Struct Init Failed\n");
fclose(file);
return;
}
info_ptr = png_create_info_struct(png_ptr); info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) if (!info_ptr)
{ PRINT_ERR("PNG struct info init failed(2)!");
printf("PNG Info Struct Init Failed\n");
fclose(file);
png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
return;
}
if (setjmp(png_jmpbuf(png_ptr))) if (setjmp(png_jmpbuf(png_ptr)))
{ PRINT_ERR("PNG reader fatal error!");
printf("Got PNG Error!\n");
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
fclose(file);
return;
}
png_init_io(png_ptr, file); png_init_io(png_ptr, file);
@@ -114,80 +98,39 @@ void PngLoader::load(Texture &o_texture, char *t_subfolder, char *t_name, char *
type = TEX_TYPE_RGB; type = TEX_TYPE_RGB;
break; break;
default: default:
PRINT_ERR("This png format is not supported!"); PRINT_ERR("This png format is not supported! RGB/RGBA only.");
} }
o_texture.setSize(width, height, type); o_texture.setSize(width, height, type);
printf("PNGLoader - width: %d | height: %d\n", width, height); printf("PNGLoader - width: %d | height: %d\n", width, height);
if (type == TEX_TYPE_RGBA) size_t row_bytes = png_get_rowbytes(png_ptr, info_ptr);
{
int row_bytes = png_get_rowbytes(png_ptr, info_ptr);
png_byte *row_pointers[height]; png_byte *row_pointers[height];
for (row = 0; row < height; row++) for (row = 0; row < height; row++)
row_pointers[row] = new png_byte[row_bytes]; row_pointers[row] = new png_byte[row_bytes];
png_read_image(png_ptr, row_pointers); png_read_image(png_ptr, row_pointers);
struct pixel
{
u8 r, g, b, a;
};
u32 x = 0; u32 x = 0;
for (i = 0; i < height; i++) for (i = 0; i < height; i++)
{
for (j = 0; j < width; j++) for (j = 0; j < width; j++)
{ {
o_texture.setData(x, row_pointers[i][4 * j]); o_texture.setData(x, row_pointers[i][4 * j]);
o_texture.setData(x + 1, row_pointers[i][4 * j + 1]); o_texture.setData(x + 1, row_pointers[i][4 * j + 1]);
o_texture.setData(x + 2, row_pointers[i][4 * j + 2]); o_texture.setData(x + 2, row_pointers[i][4 * j + 2]);
if (type == TEX_TYPE_RGBA)
{
o_texture.setData(x + 3, ((int)row_pointers[i][4 * j + 3] * 128 / 255)); o_texture.setData(x + 3, ((int)row_pointers[i][4 * j + 3] * 128 / 255));
x += 4; x += 4;
} }
}
for (row = 0; row < height; row++)
delete row_pointers[row];
}
else if (type == TEX_TYPE_RGB) else if (type == TEX_TYPE_RGB)
{
int row_bytes = png_get_rowbytes(png_ptr, info_ptr);
png_byte *row_pointers[height];
for (row = 0; row < height; row++)
row_pointers[row] = new png_byte[row_bytes];
png_read_image(png_ptr, row_pointers);
struct pixel3
{
u8 r, g, b;
};
u32 x = 0;
for (i = 0; i < height; i++)
{
for (j = 0; j < width; j++)
{
o_texture.setData(x, row_pointers[i][4 * j]);
o_texture.setData(x + 1, row_pointers[i][4 * j + 1]);
o_texture.setData(x + 2, row_pointers[i][4 * j + 2]);
x += 3; x += 3;
} }
}
for (row = 0; row < height; row++) for (row = 0; row < height; row++)
delete row_pointers[row]; delete[] row_pointers[row];
}
else
{
printf("This texture depth is not supported yet!\n");
return;
}
// Texture->Filter = GS_FILTER_NEAREST;
png_read_end(png_ptr, NULL); png_read_end(png_ptr, NULL);
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
+9 -8
View File
@@ -89,24 +89,25 @@ void Audio::setSongVolume(const u8 &t_vol)
u32 Audio::addSongListener(AudioListener *t_listener) u32 Audio::addSongListener(AudioListener *t_listener)
{ {
AudioListenerRef ref; AudioListenerRef *ref = new AudioListenerRef;
ref.id = rand() % 1000000; ref->id = rand() % 1000000;
ref.listener = t_listener; ref->listener = t_listener;
songListeners.push_back(ref); songListeners.push_back(ref);
return ref.id; return ref->id;
} }
void Audio::removeSongListener(const u32 &t_id) void Audio::removeSongListener(const u32 &t_id)
{ {
s32 index = -1; s32 index = -1;
for (u32 i = 0; i < songListeners.size(); i++) for (u32 i = 0; i < songListeners.size(); i++)
if (songListeners[i].id == t_id) if (songListeners[i]->id == t_id)
{ {
index = i; index = i;
break; break;
} }
if (index == -1) if (index == -1)
PRINT_ERR("Cant remove listener because given id was not found!"); PRINT_ERR("Cant remove listener because given id was not found!");
delete songListeners[index];
songListeners.erase(songListeners.begin() + index); songListeners.erase(songListeners.begin() + index);
} }
@@ -160,7 +161,7 @@ void Audio::playADPCM(audsrv_adpcm_t *t_adpcm, const s8 &t_ch)
void Audio::startThread(FileService *t_fileService) void Audio::startThread(FileService *t_fileService)
{ {
PRINT_LOG("Creating audio thread"); PRINT_LOG("Creating audio thread");
fileService = t_fileService; // fileService = t_fileService;
extern void *_gp; extern void *_gp;
thread.func = (void *)Audio::mainThread; thread.func = (void *)Audio::mainThread;
thread.stack = threadStack; thread.stack = threadStack;
@@ -186,7 +187,7 @@ void Audio::threadLoop()
{ {
printf("Running again.\n"); printf("Running again.\n");
for (u32 i = 0; i < getSongListenersCount(); i++) for (u32 i = 0; i < getSongListenersCount(); i++)
songListeners[i].listener->onAudioFinish(); songListeners[i]->listener->onAudioFinish();
rewindSongToStart(); rewindSongToStart();
} }
else else
@@ -202,7 +203,7 @@ void Audio::threadLoop()
WaitSema(fillbufferSema); // wait until previous chunk wasn't finished WaitSema(fillbufferSema); // wait until previous chunk wasn't finished
audsrv_play_audio(wavChunk, chunkReadStatus); audsrv_play_audio(wavChunk, chunkReadStatus);
for (u32 i = 0; i < getSongListenersCount(); i++) for (u32 i = 0; i < getSongListenersCount(); i++)
songListeners[i].listener->onAudioTick(); songListeners[i]->listener->onAudioTick();
} }
chunkReadStatus = fread(wavChunk, 1, sizeof(wavChunk), wav); chunkReadStatus = fread(wavChunk, 1, sizeof(wavChunk), wav);
+10 -5
View File
@@ -37,15 +37,15 @@ Floors::~Floors()
void Floors::onInit() void Floors::onInit()
{ {
texRepo = engine->renderer->getTextureRepository();
setBgColorAndAmbientColor(); setBgColorAndAmbientColor();
engine->renderer->setCameraDefinitions(&camera.view, &camera.unitCirclePosition, camera.planes); engine->renderer->setCameraDefinitions(&camera.view, &camera.unitCirclePosition, camera.planes);
enemy = new Enemy(texRepo); // I know that here is bug with PNG loading
ui = new Ui(texRepo); // Will be resolved in December version
engine->audio.addSongListener(this); engine->audio.addSongListener(this);
engine->audio.loadSong("sounds/mafikizolo-loot.wav"); engine->audio.loadSong("sounds/mafikizolo-loot.wav");
engine->audio.playSong(); engine->audio.playSong();
engine->audio.setSongVolume(80); engine->audio.setSongVolume(80);
texRepo = engine->renderer->getTextureRepository();
enemy = new Enemy(texRepo);
ui = new Ui(texRepo);
floorManager = new FloorManager(FLOORS_COUNT, texRepo); floorManager = new FloorManager(FLOORS_COUNT, texRepo);
player = new Player(&engine->audio, texRepo); player = new Player(&engine->audio, texRepo);
} }
@@ -60,8 +60,13 @@ void Floors::onUpdate()
player->update(engine->pad, camera, *floorManager, *enemy); player->update(engine->pad, camera, *floorManager, *enemy);
engine->renderer->draw(player->mesh); engine->renderer->draw(player->mesh);
engine->renderer->draw(enemy->getMeshes(), enemy->getMeshesCount()); engine->renderer->draw(enemy->getMeshes(), enemy->getMeshesCount());
for (u16 i = 0; i < FLOORS_COUNT; i++)
engine->renderer->draw(floorManager->floors[i].mesh, lightManager.bulbs, lightManager.bulbsCount); // You can draw array of meshes in draw() function also. It can be A LOT faster than for looping!
// Why? When given mesh is small, is not animated and is not backface culled, vertex data are send once!
engine->renderer->draw(floorManager->getMeshes(), FLOORS_COUNT, lightManager.bulbs, lightManager.bulbsCount);
// draw() in array mode, sometimes will force you to do synchronization between EE <-> VU1 <-> GS via:
// renderer->clearAndWaitForRender(); or renderer->waitForRender();
ui->render(engine->renderer); // 2D rendering ist LAST step, because layers gonna play there. ui->render(engine->renderer); // 2D rendering ist LAST step, because layers gonna play there.
} }
@@ -22,6 +22,7 @@
*/ */
FloorManager::FloorManager(int t_floorAmount, TextureRepository *t_texRepo) FloorManager::FloorManager(int t_floorAmount, TextureRepository *t_texRepo)
{ {
meshes = new Mesh *[t_floorAmount];
texRepo = t_texRepo; texRepo = t_texRepo;
floorAmount = t_floorAmount; floorAmount = t_floorAmount;
spirals = new Point[t_floorAmount]; spirals = new Point[t_floorAmount];
@@ -85,12 +86,15 @@ void FloorManager::initFloors()
floors[0].mesh.loadObj("meshes/floor/", "floor", 3.0F, false); floors[0].mesh.loadObj("meshes/floor/", "floor", 3.0F, false);
floors[0].mesh.shouldBeFrustumCulled = true; floors[0].mesh.shouldBeFrustumCulled = true;
floors[0].mesh.shouldBeLighted = true; floors[0].mesh.shouldBeLighted = true;
meshes[0] = &floors[0].mesh;
texRepo->addByMesh("meshes/floor/", floors[0].mesh, BMP); texRepo->addByMesh("meshes/floor/", floors[0].mesh, BMP);
for (u16 i = 1; i < floorAmount; i++) for (u16 i = 1; i < floorAmount; i++)
{ {
floors[i].mesh.shouldBeFrustumCulled = true;
floors[i].init(floors[0].mesh, spirals[i], i); floors[i].init(floors[0].mesh, spirals[i], i);
texRepo->getByMesh(floors[0].mesh.getId(), floors[0].mesh.getMaterial(0).getId()) texRepo->getByMesh(floors[0].mesh.getId(), floors[0].mesh.getMaterial(0).getId())
->addLink(floors[i].mesh.getId(), floors[i].mesh.getMaterial(0).getId()); ->addLink(floors[i].mesh.getId(), floors[i].mesh.getMaterial(0).getId());
meshes[i] = &floors[i].mesh;
} }
PRINT_LOG("Floors initialized!"); PRINT_LOG("Floors initialized!");
} }
@@ -31,8 +31,10 @@ public:
u16 floorAmount; u16 floorAmount;
void update(Player &t_player); void update(Player &t_player);
void onAudioTick(); void onAudioTick();
Mesh **getMeshes() { return meshes; }
private: private:
Mesh **meshes;
TextureRepository *texRepo; TextureRepository *texRepo;
u8 audioOffset, audioMode; u8 audioOffset, audioMode;
u32 audioTick; u32 audioTick;
+11 -19
View File
@@ -26,33 +26,25 @@ Enemy::Enemy(TextureRepository *t_texRepo)
PRINT_LOG("Creating enemy object"); PRINT_LOG("Creating enemy object");
meshes = new Mesh[getMeshesCount()]; meshes = new Mesh[getMeshesCount()];
drawMeshes = new Mesh *[getMeshesCount()];
meshes[0].loadMD2("meshes/enemy/", "poss_head", 0.3F, false); meshes[0].loadMD2("meshes/enemy/", "poss_head", 0.3F, false);
meshes[0].rotation.x = -1.566F;
meshes[0].rotation.z = 1.566F;
meshes[0].shouldBeFrustumCulled = false;
meshes[1].loadMD2("meshes/enemy/", "poss_body", 0.3F, false); meshes[1].loadMD2("meshes/enemy/", "poss_body", 0.3F, false);
meshes[1].rotation.x = -1.566F;
meshes[1].rotation.z = 1.566F;
meshes[1].shouldBeFrustumCulled = false;
meshes[2].loadMD2("meshes/enemy/", "poss_weapon", 0.3F, false); meshes[2].loadMD2("meshes/enemy/", "poss_weapon", 0.3F, false);
meshes[2].rotation.x = -1.566F;
meshes[2].rotation.z = 1.566F; for (u8 i = 0; i < 3; i++)
meshes[2].shouldBeFrustumCulled = false; {
meshes[i].rotation.x = -1.566F;
meshes[i].rotation.z = 1.566F;
meshes[i].shouldBeFrustumCulled = false;
t_texRepo->addByMesh("meshes/enemy/", meshes[i], PNG);
meshes[i].playAnimation(1, 6);
drawMeshes[i] = &meshes[i];
}
Vector3 initPos = Vector3(0.00F, 40.00F, 0.00F); Vector3 initPos = Vector3(0.00F, 40.00F, 0.00F);
setPosition(initPos); setPosition(initPos);
t_texRepo->addByMesh("meshes/enemy/", meshes[0], PNG);
t_texRepo->addByMesh("meshes/enemy/", meshes[1], PNG);
t_texRepo->addByMesh("meshes/enemy/", meshes[2], PNG);
meshes[0].playAnimation(1, 6);
meshes[1].playAnimation(1, 6);
meshes[2].playAnimation(1, 6);
isKilled = true; isKilled = true;
PRINT_LOG("Enemy object created!"); PRINT_LOG("Enemy object created!");
+3 -1
View File
@@ -24,7 +24,7 @@ public:
Enemy(TextureRepository *t_texRepo); Enemy(TextureRepository *t_texRepo);
~Enemy(); ~Enemy();
inline Mesh *getMeshes() const { return meshes; } inline Mesh **getMeshes() const { return drawMeshes; }
inline u8 getMeshesCount() const { return 3; } inline u8 getMeshesCount() const { return 3; }
inline Vector3 getPosition() const { return position; } inline Vector3 getPosition() const { return position; }
void setPosition(const Vector3 &t_vec); void setPosition(const Vector3 &t_vec);
@@ -35,6 +35,8 @@ public:
private: private:
/** 0 - head, 1 - body, 2 - weapon */ /** 0 - head, 1 - body, 2 - weapon */
Mesh *meshes; Mesh *meshes;
/** Only for draw() method. */
Mesh **drawMeshes;
const Floor *currentFloor; const Floor *currentFloor;
Vector3 position, currFloorMin, currFloorMax; Vector3 position, currFloorMin, currFloorMax;
u8 isKilled; u8 isKilled;