diff --git a/main.c b/main.c index cd0353e..3eedf9e 100644 --- a/main.c +++ b/main.c @@ -52,26 +52,31 @@ extern u_long mdl_shambler[]; extern u_long tim_shambler_f[]; extern u_long tim_shambler_b[]; -// The player texture is divided into two pieces, so that each part is aligned to their own texture page -TIM_IMAGE playerFrontTex, playerBackTex; -TIM_IMAGE shamblerFrontTex, shamblerBackTex; -ps1mdl_t playerModel, shamblerModel; - -void loadTexture(const u_long* tim, TIM_IMAGE* tparam) +typedef struct { - GetTimInfo(tim, tparam); + ps1mdl_header_t* header; + ps1mdl_texcoord_t* texCoords; + ps1mdl_triangle_t* triangles; + ps1mdl_vertex_t* vertices; - // This freezes up if the TIM image has weird dimensions, such as the ones from Quake... - LoadImage(tparam->prect, tparam->paddr); + short halfSkinWidth; // Used for offsetting UVs on the back texture +} ps1mdl_t; - // Upload CLUT for palettized images - if (tparam->mode & 0x8) - { - LoadImage(tparam->crect, tparam->caddr); - } +typedef struct +{ + RECT prect, crect; + int mode; + int uoffs, voffs; +} ps1texture_t; - DrawSync(0); -} +typedef struct +{ + // Skin textures are divided into two pieces, so that each part is aligned to their own texture page + ps1texture_t front, back; +} ps1skin_t; + +ps1mdl_t playerModel, shamblerModel; +ps1skin_t playerSkin, shamblerSkin; void loadModel(const u_long* data, ps1mdl_t *mdl) { @@ -87,6 +92,38 @@ void loadModel(const u_long* data, ps1mdl_t *mdl) bytes += sizeof(ps1mdl_triangle_t) * mdl->header->triangleCount; mdl->vertices = (ps1mdl_vertex_t*)bytes; + + mdl->halfSkinWidth = mdl->header->skinWidth >> 1; +} + +void loadTexture(const u_long* tim, ps1texture_t *texture) +{ + TIM_IMAGE* tparam; + GetTimInfo(tim, tparam); + + // This freezes up if the TIM image has weird dimensions, such as the ones from Quake... + LoadImage(tparam->prect, tparam->paddr); + + // Upload CLUT for palettized images + if (tparam->mode & 0x8) + { + LoadImage(tparam->crect, tparam->caddr); + } + + DrawSync(0); + + texture->prect = *tparam->prect; + texture->crect = *tparam->crect; + texture->mode = tparam->mode; + + texture->uoffs = (texture->prect.x % 64) << (2 - (texture->mode & 0x3)); + texture->voffs = (texture->prect.y & 0xFF); +} + +void loadSkin(const u_long* frontTim, const u_long* backTim, ps1skin_t *skin) +{ + loadTexture(frontTim, &skin->front); + loadTexture(backTim, &skin->back); } // Init function @@ -126,12 +163,10 @@ void init(void) nextpri = primbuff[0]; loadModel(mdl_player, &playerModel); - loadTexture(tim_player_f, &playerFrontTex); - loadTexture(tim_player_b, &playerBackTex); + loadSkin(tim_player_f, tim_player_b, &playerSkin); loadModel(mdl_shambler, &shamblerModel); - loadTexture(tim_shambler_f, &shamblerFrontTex); - loadTexture(tim_shambler_b, &shamblerBackTex); + loadSkin(tim_shambler_f, tim_shambler_b, &shamblerSkin); // Set texture page for the entire drawing environment. Nice in some cases perhaps, but not what we need. //draw[0].tpage = getTPage(playerFrontTex.mode & 0x3, 0, playerFrontTex.prect->x, playerFrontTex.prect->y); @@ -291,19 +326,14 @@ static int fakeLight(const int *norm) return lit; } -void drawModel(ps1mdl_t *model, TIM_IMAGE *frontTex, TIM_IMAGE *backTex, int xOffset, int frameCounter) +void drawModel(ps1mdl_t *model, ps1skin_t *skin, int xOffset, int frameCounter) { - TIM_IMAGE *tex; + ps1texture_t *tex; short u0, u1, u2, uoffs, voffs; int frameNum = frameCounter % model->header->frameCount; int vertOffs = frameNum * model->header->vertexCount; - - unsigned short halfSkinWidth = model->header->skinWidth >> 1; - short frontUOffs = (frontTex->prect->x % 64) << (2 - (frontTex->mode & 0x3)); - short frontVOffs = (frontTex->prect->y & 0xFF); - short backUOffs = (backTex->prect->x % 64) << (2 - (backTex->mode & 0x3)); - short backVOffs = (backTex->prect->y & 0xFF); + short halfSkinWidth = model->halfSkinWidth; for (int triIdx = 0; triIdx < model->header->triangleCount; ++triIdx) { @@ -330,7 +360,7 @@ void drawModel(ps1mdl_t *model, TIM_IMAGE *frontTex, TIM_IMAGE *backTex, int xOf if (tri->frontFace) { u0 = tc0->u, u1 = tc1->u, u2 = tc2->u; - tex = frontTex, uoffs = frontUOffs, voffs = frontVOffs; + tex = &skin->front; } else { @@ -338,9 +368,11 @@ void drawModel(ps1mdl_t *model, TIM_IMAGE *frontTex, TIM_IMAGE *backTex, int xOf u0 = tc0->onSeam ? tc0->u : tc0->u - halfSkinWidth; u1 = tc1->onSeam ? tc1->u : tc1->u - halfSkinWidth; u2 = tc2->onSeam ? tc2->u : tc2->u - halfSkinWidth; - tex = backTex, uoffs = backUOffs, voffs = backVOffs; + tex = &skin->back; } + uoffs = tex->uoffs, voffs = tex->voffs; + POLY_GT3 *poly = (POLY_GT3*)nextpri; setPolyGT3(poly); setXY3(poly, xOffset + v0->position[0], 240 - v0->position[2], xOffset + v1->position[0], 240 - v1->position[2], xOffset + v2->position[0], 240 - v2->position[2]); @@ -348,8 +380,8 @@ void drawModel(ps1mdl_t *model, TIM_IMAGE *frontTex, TIM_IMAGE *backTex, int xOf setRGB0(poly, lit0, lit0, lit0); setRGB1(poly, lit1, lit1, lit1); setRGB2(poly, lit2, lit2, lit2); - setClut(poly, tex->crect->x, tex->crect->y); - setTPage(poly, tex->mode & 0x3, 0, tex->prect->x, tex->prect->y); + setClut(poly, tex->crect.x, tex->crect.y); + setTPage(poly, tex->mode & 0x3, 0, tex->prect.x, tex->prect.y); addPrim(ot[db] + depth, poly); nextpri += sizeof(POLY_GT3); @@ -363,29 +395,27 @@ void drawStuff(int counter) // Print the obligatory hello world and counter to show that the // program isn't locking up to the last created text stream FntPrint(-1, "COUNTER=%d, SIN=%d\n", counter, isin(counter)); - FntPrint(-1, "Image x %d y %d w %d h %d mode 0x%x\n", playerFrontTex.prect->x, playerFrontTex.prect->y, playerFrontTex.prect->w, playerFrontTex.prect->h, playerFrontTex.mode); + FntPrint(-1, "Image x %d y %d w %d h %d mode 0x%x\n", playerSkin.front.prect.x, playerSkin.front.prect.y, playerSkin.front.prect.w, playerSkin.front.prect.h, playerSkin.front.mode); FntPrint(-1, "Model: %d tris, %d verts\n", playerModel.header->triangleCount, playerModel.header->vertexCount); // Draw the last created text stream FntFlush(-1); - drawModel(&playerModel, &playerFrontTex, &playerBackTex, -40, counter >> 2); - drawModel(&shamblerModel, &shamblerFrontTex, &shamblerBackTex, 80, counter >> 2); - - return; + drawModel(&playerModel, &playerSkin, -40, counter >> 2); + drawModel(&shamblerModel, &shamblerSkin, 80, counter >> 2); - int r, g, b; + // int r, g, b; - lerpcol(255, 255, 0, 255, 0, 0, (icos(counter * 32) + 4096) >> 1, &r, &g, &b); - addTile(32, 32, 64, 64, r, g, b); + // lerpcol(255, 255, 0, 255, 0, 0, (icos(counter * 32) + 4096) >> 1, &r, &g, &b); + // addTile(32, 32, 64, 64, r, g, b); - lerpcol(0, 255, 255, 0, 255, 0, (icos(counter * 24 + 512) + 4096) >> 1, &r, &g, &b); - addTile(128, 160, 48, 48, r, g, b); + // lerpcol(0, 255, 255, 0, 255, 0, (icos(counter * 24 + 512) + 4096) >> 1, &r, &g, &b); + // addTile(128, 160, 48, 48, r, g, b); - addColoredTriangle(260, 140, 220, 220, 300, 220, 0xFF0000, 0x00FF00, 0x0000FF, 0); - addTexturedTriangle(260, 40, 220, 120, 300, 120, 0, 94, 74, 124, 58, 1, &playerFrontTex); - addTexturedSprite(20, 140, 80, 80, &playerFrontTex); - addTexturedSprite(80, 40, 154, 114, &shamblerFrontTex); + // addColoredTriangle(260, 140, 220, 220, 300, 220, 0xFF0000, 0x00FF00, 0x0000FF, 0); + // addTexturedTriangle(260, 40, 220, 120, 300, 120, 0, 94, 74, 124, 58, 1, &playerSkin.front); + // addTexturedSprite(20, 140, 80, 80, &playerSkin.front); + // addTexturedSprite(80, 40, 154, 114, &shamblerSkin.front); } // Main function, program entrypoint diff --git a/ps1mdl.h b/ps1mdl.h index ee87a83..487dc56 100644 --- a/ps1mdl.h +++ b/ps1mdl.h @@ -38,14 +38,6 @@ typedef struct unsigned char normalIndex; } ps1mdl_vertex_t; -typedef struct -{ - ps1mdl_header_t* header; - ps1mdl_texcoord_t* texCoords; - ps1mdl_triangle_t* triangles; - ps1mdl_vertex_t* vertices; -} ps1mdl_t; - #ifdef __cplusplus } #endif