mirror of
https://gitlab.com/skmp/dca3-game.git
synced 2025-01-16 21:08:22 +01:00
808 lines
29 KiB
C++
808 lines
29 KiB
C++
/* KallistiOS ##version##
|
|
|
|
pvr_prim.c
|
|
Copyright (C) 2002 Megan Potter
|
|
|
|
*/
|
|
|
|
#include <assert.h>
|
|
#include <string.h>
|
|
#include "dc/pvr.h"
|
|
#include "pvr_internal.h"
|
|
|
|
#define assert_msg(cond, txt) assert(cond && txt)
|
|
|
|
/*
|
|
|
|
Primitive handling
|
|
|
|
These functions help you prepare primitives for loading into the
|
|
PVR for scene processing.
|
|
|
|
*/
|
|
|
|
/* Compile a polygon context into a polygon header */
|
|
void pvr_poly_compile(pvr_poly_hdr_t *dst, pvr_poly_cxt_t *src) {
|
|
int u, v;
|
|
uint32 txr_base;
|
|
|
|
/* Basically we just take each parameter, clip it, shift it
|
|
into place, and OR it into the final result. */
|
|
|
|
/* The base values for CMD */
|
|
dst->cmd = PVR_CMD_POLYHDR;
|
|
|
|
if(src->txr.enable == PVR_TEXTURE_ENABLE)
|
|
dst->cmd |= 8;
|
|
|
|
/* Or in the list type, shading type, color and UV formats */
|
|
dst->cmd |= (src->list_type << PVR_TA_CMD_TYPE_SHIFT) & PVR_TA_CMD_TYPE_MASK;
|
|
dst->cmd |= (src->fmt.color << PVR_TA_CMD_CLRFMT_SHIFT) & PVR_TA_CMD_CLRFMT_MASK;
|
|
dst->cmd |= (src->gen.shading << PVR_TA_CMD_SHADE_SHIFT) & PVR_TA_CMD_SHADE_MASK;
|
|
dst->cmd |= (src->fmt.uv << PVR_TA_CMD_UVFMT_SHIFT) & PVR_TA_CMD_UVFMT_MASK;
|
|
dst->cmd |= (src->gen.clip_mode << PVR_TA_CMD_USERCLIP_SHIFT) & PVR_TA_CMD_USERCLIP_MASK;
|
|
dst->cmd |= (src->fmt.modifier << PVR_TA_CMD_MODIFIER_SHIFT) & PVR_TA_CMD_MODIFIER_MASK;
|
|
dst->cmd |= (src->gen.modifier_mode << PVR_TA_CMD_MODIFIERMODE_SHIFT) & PVR_TA_CMD_MODIFIERMODE_MASK;
|
|
dst->cmd |= (src->gen.specular << PVR_TA_CMD_SPECULAR_SHIFT) & PVR_TA_CMD_SPECULAR_MASK;
|
|
|
|
/* Polygon mode 1 */
|
|
dst->mode1 = (src->depth.comparison << PVR_TA_PM1_DEPTHCMP_SHIFT) & PVR_TA_PM1_DEPTHCMP_MASK;
|
|
dst->mode1 |= (src->gen.culling << PVR_TA_PM1_CULLING_SHIFT) & PVR_TA_PM1_CULLING_MASK;
|
|
dst->mode1 |= (src->depth.write << PVR_TA_PM1_DEPTHWRITE_SHIFT) & PVR_TA_PM1_DEPTHWRITE_MASK;
|
|
dst->mode1 |= (src->txr.enable << PVR_TA_PM1_TXRENABLE_SHIFT) & PVR_TA_PM1_TXRENABLE_MASK;
|
|
|
|
/* Polygon mode 2 */
|
|
dst->mode2 = (src->blend.src << PVR_TA_PM2_SRCBLEND_SHIFT) & PVR_TA_PM2_SRCBLEND_MASK;
|
|
dst->mode2 |= (src->blend.dst << PVR_TA_PM2_DSTBLEND_SHIFT) & PVR_TA_PM2_DSTBLEND_MASK;
|
|
dst->mode2 |= (src->blend.src_enable << PVR_TA_PM2_SRCENABLE_SHIFT) & PVR_TA_PM2_SRCENABLE_MASK;
|
|
dst->mode2 |= (src->blend.dst_enable << PVR_TA_PM2_DSTENABLE_SHIFT) & PVR_TA_PM2_DSTENABLE_MASK;
|
|
dst->mode2 |= (src->gen.fog_type << PVR_TA_PM2_FOG_SHIFT) & PVR_TA_PM2_FOG_MASK;
|
|
dst->mode2 |= (src->gen.color_clamp << PVR_TA_PM2_CLAMP_SHIFT) & PVR_TA_PM2_CLAMP_MASK;
|
|
dst->mode2 |= (src->gen.alpha << PVR_TA_PM2_ALPHA_SHIFT) & PVR_TA_PM2_ALPHA_MASK;
|
|
|
|
if(src->txr.enable == PVR_TEXTURE_DISABLE) {
|
|
dst->mode3 = 0;
|
|
}
|
|
else {
|
|
dst->mode2 |= (src->txr.alpha << PVR_TA_PM2_TXRALPHA_SHIFT) & PVR_TA_PM2_TXRALPHA_MASK;
|
|
dst->mode2 |= (src->txr.uv_flip << PVR_TA_PM2_UVFLIP_SHIFT) & PVR_TA_PM2_UVFLIP_MASK;
|
|
dst->mode2 |= (src->txr.uv_clamp << PVR_TA_PM2_UVCLAMP_SHIFT) & PVR_TA_PM2_UVCLAMP_MASK;
|
|
dst->mode2 |= (src->txr.filter << PVR_TA_PM2_FILTER_SHIFT) & PVR_TA_PM2_FILTER_MASK;
|
|
dst->mode2 |= (src->txr.mipmap_bias << PVR_TA_PM2_MIPBIAS_SHIFT) & PVR_TA_PM2_MIPBIAS_MASK;
|
|
dst->mode2 |= (src->txr.env << PVR_TA_PM2_TXRENV_SHIFT) & PVR_TA_PM2_TXRENV_MASK;
|
|
|
|
switch(src->txr.width) {
|
|
case 8:
|
|
u = 0;
|
|
break;
|
|
case 16:
|
|
u = 1;
|
|
break;
|
|
case 32:
|
|
u = 2;
|
|
break;
|
|
case 64:
|
|
u = 3;
|
|
break;
|
|
case 128:
|
|
u = 4;
|
|
break;
|
|
case 256:
|
|
u = 5;
|
|
break;
|
|
case 512:
|
|
u = 6;
|
|
break;
|
|
case 1024:
|
|
u = 7;
|
|
break;
|
|
default:
|
|
assert_msg(0, "Invalid texture U size");
|
|
u = 0;
|
|
break;
|
|
}
|
|
|
|
switch(src->txr.height) {
|
|
case 8:
|
|
v = 0;
|
|
break;
|
|
case 16:
|
|
v = 1;
|
|
break;
|
|
case 32:
|
|
v = 2;
|
|
break;
|
|
case 64:
|
|
v = 3;
|
|
break;
|
|
case 128:
|
|
v = 4;
|
|
break;
|
|
case 256:
|
|
v = 5;
|
|
break;
|
|
case 512:
|
|
v = 6;
|
|
break;
|
|
case 1024:
|
|
v = 7;
|
|
break;
|
|
default:
|
|
assert_msg(0, "Invalid texture V size");
|
|
v = 0;
|
|
break;
|
|
}
|
|
|
|
dst->mode2 |= (u << PVR_TA_PM2_USIZE_SHIFT) & PVR_TA_PM2_USIZE_MASK;
|
|
dst->mode2 |= (v << PVR_TA_PM2_VSIZE_SHIFT) & PVR_TA_PM2_VSIZE_MASK;
|
|
|
|
/* Polygon mode 3 */
|
|
dst->mode3 = (src->txr.mipmap << PVR_TA_PM3_MIPMAP_SHIFT) & PVR_TA_PM3_MIPMAP_MASK;
|
|
dst->mode3 |= (src->txr.format << PVR_TA_PM3_TXRFMT_SHIFT) & PVR_TA_PM3_TXRFMT_MASK;
|
|
|
|
/* Convert the texture address */
|
|
txr_base = (ptr_t)src->txr.base - (ptr_t)emu_vram;
|
|
txr_base = (txr_base & 0x00fffff8) >> 3;
|
|
dst->mode3 |= txr_base;
|
|
}
|
|
|
|
if(src->fmt.modifier && src->gen.modifier_mode) {
|
|
/* If we're affected by a modifier volume, silently promote the header
|
|
to the one that is affected by a modifier volume. */
|
|
dst->d1 = dst->mode2;
|
|
dst->d2 = dst->mode3;
|
|
}
|
|
else {
|
|
dst->d1 = dst->d2 = 0xffffffff;
|
|
}
|
|
|
|
dst->d3 = dst->d4 = 0xffffffff;
|
|
}
|
|
|
|
/* Create a colored polygon context with parameters similar to
|
|
the old "ta" function `ta_poly_hdr_col' */
|
|
void pvr_poly_cxt_col(pvr_poly_cxt_t *dst, pvr_list_t list) {
|
|
int alpha;
|
|
|
|
/* Start off blank */
|
|
memset(dst, 0, sizeof(pvr_poly_cxt_t));
|
|
|
|
/* Fill in a few values */
|
|
dst->list_type = list;
|
|
alpha = list > PVR_LIST_OP_MOD;
|
|
dst->fmt.color = PVR_CLRFMT_ARGBPACKED;
|
|
dst->fmt.uv = PVR_UVFMT_32BIT;
|
|
dst->gen.shading = PVR_SHADE_GOURAUD;
|
|
dst->depth.comparison = PVR_DEPTHCMP_GREATER;
|
|
dst->depth.write = PVR_DEPTHWRITE_ENABLE;
|
|
dst->gen.culling = PVR_CULLING_CCW;
|
|
dst->txr.enable = PVR_TEXTURE_DISABLE;
|
|
|
|
if(!alpha) {
|
|
dst->gen.alpha = PVR_ALPHA_DISABLE;
|
|
dst->blend.src = PVR_BLEND_ONE;
|
|
dst->blend.dst = PVR_BLEND_ZERO;
|
|
}
|
|
else {
|
|
dst->gen.alpha = PVR_ALPHA_ENABLE;
|
|
dst->blend.src = PVR_BLEND_SRCALPHA;
|
|
dst->blend.dst = PVR_BLEND_INVSRCALPHA;
|
|
}
|
|
|
|
dst->blend.src_enable = PVR_BLEND_DISABLE;
|
|
dst->blend.dst_enable = PVR_BLEND_DISABLE;
|
|
dst->gen.fog_type = PVR_FOG_DISABLE;
|
|
dst->gen.color_clamp = PVR_CLRCLAMP_DISABLE;
|
|
}
|
|
|
|
/* Create a textured polygon context with parameters similar to
|
|
the old "ta" function `ta_poly_hdr_txr' */
|
|
void pvr_poly_cxt_txr(pvr_poly_cxt_t *dst, pvr_list_t list,
|
|
int textureformat, int tw, int th, pvr_ptr_t textureaddr,
|
|
int filtering) {
|
|
int alpha;
|
|
|
|
/* Start off blank */
|
|
memset(dst, 0, sizeof(pvr_poly_cxt_t));
|
|
|
|
/* Fill in a few values */
|
|
dst->list_type = list;
|
|
alpha = list > PVR_LIST_OP_MOD;
|
|
dst->fmt.color = PVR_CLRFMT_ARGBPACKED;
|
|
dst->fmt.uv = PVR_UVFMT_32BIT;
|
|
dst->gen.shading = PVR_SHADE_GOURAUD;
|
|
dst->depth.comparison = PVR_DEPTHCMP_GREATER;
|
|
dst->depth.write = PVR_DEPTHWRITE_ENABLE;
|
|
dst->gen.culling = PVR_CULLING_CCW;
|
|
dst->txr.enable = PVR_TEXTURE_ENABLE;
|
|
|
|
if(!alpha) {
|
|
dst->gen.alpha = PVR_ALPHA_DISABLE;
|
|
dst->txr.alpha = PVR_TXRALPHA_ENABLE;
|
|
dst->blend.src = PVR_BLEND_ONE;
|
|
dst->blend.dst = PVR_BLEND_ZERO;
|
|
dst->txr.env = PVR_TXRENV_MODULATE;
|
|
}
|
|
else {
|
|
dst->gen.alpha = PVR_ALPHA_ENABLE;
|
|
dst->txr.alpha = PVR_TXRALPHA_ENABLE;
|
|
dst->blend.src = PVR_BLEND_SRCALPHA;
|
|
dst->blend.dst = PVR_BLEND_INVSRCALPHA;
|
|
dst->txr.env = PVR_TXRENV_MODULATEALPHA;
|
|
}
|
|
|
|
dst->blend.src_enable = PVR_BLEND_DISABLE;
|
|
dst->blend.dst_enable = PVR_BLEND_DISABLE;
|
|
dst->gen.fog_type = PVR_FOG_DISABLE;
|
|
dst->gen.color_clamp = PVR_CLRCLAMP_DISABLE;
|
|
dst->txr.uv_flip = PVR_UVFLIP_NONE;
|
|
dst->txr.uv_clamp = PVR_UVCLAMP_NONE;
|
|
dst->txr.filter = filtering;
|
|
dst->txr.mipmap_bias = PVR_MIPBIAS_NORMAL;
|
|
dst->txr.width = tw;
|
|
dst->txr.height = th;
|
|
dst->txr.base = textureaddr;
|
|
dst->txr.format = textureformat;
|
|
}
|
|
|
|
/* Create an untextured sprite context. */
|
|
void pvr_sprite_cxt_col(pvr_sprite_cxt_t *dst, pvr_list_t list) {
|
|
int alpha;
|
|
|
|
/* Start off blank */
|
|
memset(dst, 0, sizeof(pvr_sprite_cxt_t));
|
|
|
|
/* Fill in a few values */
|
|
dst->list_type = list;
|
|
alpha = list > PVR_LIST_OP_MOD;
|
|
dst->depth.comparison = PVR_DEPTHCMP_GREATER;
|
|
dst->depth.write = PVR_DEPTHWRITE_ENABLE;
|
|
dst->gen.culling = PVR_CULLING_CCW;
|
|
dst->txr.enable = PVR_TEXTURE_DISABLE;
|
|
|
|
if(!alpha) {
|
|
dst->gen.alpha = PVR_ALPHA_DISABLE;
|
|
dst->blend.src = PVR_BLEND_ONE;
|
|
dst->blend.dst = PVR_BLEND_ZERO;
|
|
}
|
|
else {
|
|
dst->gen.alpha = PVR_ALPHA_ENABLE;
|
|
dst->blend.src = PVR_BLEND_SRCALPHA;
|
|
dst->blend.dst = PVR_BLEND_INVSRCALPHA;
|
|
}
|
|
|
|
dst->blend.src_enable = PVR_BLEND_DISABLE;
|
|
dst->blend.dst_enable = PVR_BLEND_DISABLE;
|
|
dst->gen.fog_type = PVR_FOG_DISABLE;
|
|
dst->gen.color_clamp = PVR_CLRCLAMP_DISABLE;
|
|
}
|
|
|
|
/* Create a textured sprite context. */
|
|
void pvr_sprite_cxt_txr(pvr_sprite_cxt_t *dst, pvr_list_t list,
|
|
int textureformat, int tw, int th, pvr_ptr_t textureaddr,
|
|
int filtering) {
|
|
int alpha;
|
|
|
|
/* Start off blank */
|
|
memset(dst, 0, sizeof(pvr_sprite_cxt_t));
|
|
|
|
/* Fill in a few values */
|
|
dst->list_type = list;
|
|
alpha = list > PVR_LIST_OP_MOD;
|
|
dst->depth.comparison = PVR_DEPTHCMP_GREATER;
|
|
dst->depth.write = PVR_DEPTHWRITE_ENABLE;
|
|
dst->gen.culling = PVR_CULLING_CCW;
|
|
|
|
if(!alpha) {
|
|
dst->gen.alpha = PVR_ALPHA_DISABLE;
|
|
dst->txr.alpha = PVR_TXRALPHA_ENABLE;
|
|
dst->blend.src = PVR_BLEND_ONE;
|
|
dst->blend.dst = PVR_BLEND_ZERO;
|
|
dst->txr.env = PVR_TXRENV_MODULATE;
|
|
}
|
|
else {
|
|
dst->gen.alpha = PVR_ALPHA_ENABLE;
|
|
dst->txr.alpha = PVR_TXRALPHA_ENABLE;
|
|
dst->blend.src = PVR_BLEND_SRCALPHA;
|
|
dst->blend.dst = PVR_BLEND_INVSRCALPHA;
|
|
dst->txr.env = PVR_TXRENV_MODULATEALPHA;
|
|
}
|
|
|
|
dst->blend.src_enable = PVR_BLEND_DISABLE;
|
|
dst->blend.dst_enable = PVR_BLEND_DISABLE;
|
|
dst->gen.fog_type = PVR_FOG_DISABLE;
|
|
dst->gen.color_clamp = PVR_CLRCLAMP_DISABLE;
|
|
dst->txr.enable = PVR_TEXTURE_ENABLE;
|
|
dst->txr.uv_flip = PVR_UVFLIP_NONE;
|
|
dst->txr.uv_clamp = PVR_UVCLAMP_NONE;
|
|
dst->txr.filter = filtering;
|
|
dst->txr.mipmap_bias = PVR_MIPBIAS_NORMAL;
|
|
dst->txr.width = tw;
|
|
dst->txr.height = th;
|
|
dst->txr.base = textureaddr;
|
|
dst->txr.format = textureformat;
|
|
}
|
|
|
|
void pvr_sprite_compile(pvr_sprite_hdr_t *dst, pvr_sprite_cxt_t *src) {
|
|
int u, v;
|
|
uint32 txr_base;
|
|
|
|
/* Basically we just take each parameter, clip it, shift it
|
|
into place, and OR it into the final result. */
|
|
|
|
/* The base values for CMD */
|
|
dst->cmd = PVR_CMD_SPRITE;
|
|
|
|
if(src->txr.enable == PVR_TEXTURE_ENABLE)
|
|
dst->cmd |= 8;
|
|
|
|
/* Or in the list type, clipping mode, and UV formats */
|
|
dst->cmd |= (src->list_type << PVR_TA_CMD_TYPE_SHIFT) & PVR_TA_CMD_TYPE_MASK;
|
|
dst->cmd |= (PVR_UVFMT_16BIT << PVR_TA_CMD_UVFMT_SHIFT) & PVR_TA_CMD_UVFMT_MASK;
|
|
dst->cmd |= (src->gen.clip_mode << PVR_TA_CMD_USERCLIP_SHIFT) & PVR_TA_CMD_USERCLIP_MASK;
|
|
dst->cmd |= (src->gen.specular << PVR_TA_CMD_SPECULAR_SHIFT) & PVR_TA_CMD_SPECULAR_MASK;
|
|
|
|
/* Polygon mode 1 */
|
|
dst->mode1 = (src->depth.comparison << PVR_TA_PM1_DEPTHCMP_SHIFT) & PVR_TA_PM1_DEPTHCMP_MASK;
|
|
dst->mode1 |= (src->gen.culling << PVR_TA_PM1_CULLING_SHIFT) & PVR_TA_PM1_CULLING_MASK;
|
|
dst->mode1 |= (src->depth.write << PVR_TA_PM1_DEPTHWRITE_SHIFT) & PVR_TA_PM1_DEPTHWRITE_MASK;
|
|
dst->mode1 |= (src->txr.enable << PVR_TA_PM1_TXRENABLE_SHIFT) & PVR_TA_PM1_TXRENABLE_MASK;
|
|
|
|
/* Polygon mode 2 */
|
|
dst->mode2 = (src->blend.src << PVR_TA_PM2_SRCBLEND_SHIFT) & PVR_TA_PM2_SRCBLEND_MASK;
|
|
dst->mode2 |= (src->blend.dst << PVR_TA_PM2_DSTBLEND_SHIFT) & PVR_TA_PM2_DSTBLEND_MASK;
|
|
dst->mode2 |= (src->blend.src_enable << PVR_TA_PM2_SRCENABLE_SHIFT) & PVR_TA_PM2_SRCENABLE_MASK;
|
|
dst->mode2 |= (src->blend.dst_enable << PVR_TA_PM2_DSTENABLE_SHIFT) & PVR_TA_PM2_DSTENABLE_MASK;
|
|
dst->mode2 |= (src->gen.fog_type << PVR_TA_PM2_FOG_SHIFT) & PVR_TA_PM2_FOG_MASK;
|
|
dst->mode2 |= (src->gen.color_clamp << PVR_TA_PM2_CLAMP_SHIFT) & PVR_TA_PM2_CLAMP_MASK;
|
|
dst->mode2 |= (src->gen.alpha << PVR_TA_PM2_ALPHA_SHIFT) & PVR_TA_PM2_ALPHA_MASK;
|
|
|
|
if(src->txr.enable == PVR_TEXTURE_DISABLE) {
|
|
dst->mode3 = 0;
|
|
}
|
|
else {
|
|
dst->mode2 |= (src->txr.alpha << PVR_TA_PM2_TXRALPHA_SHIFT) & PVR_TA_PM2_TXRALPHA_MASK;
|
|
dst->mode2 |= (src->txr.uv_flip << PVR_TA_PM2_UVFLIP_SHIFT) & PVR_TA_PM2_UVFLIP_MASK;
|
|
dst->mode2 |= (src->txr.uv_clamp << PVR_TA_PM2_UVCLAMP_SHIFT) & PVR_TA_PM2_UVCLAMP_MASK;
|
|
dst->mode2 |= (src->txr.filter << PVR_TA_PM2_FILTER_SHIFT) & PVR_TA_PM2_FILTER_MASK;
|
|
dst->mode2 |= (src->txr.mipmap_bias << PVR_TA_PM2_MIPBIAS_SHIFT) & PVR_TA_PM2_MIPBIAS_MASK;
|
|
dst->mode2 |= (src->txr.env << PVR_TA_PM2_TXRENV_SHIFT) & PVR_TA_PM2_TXRENV_MASK;
|
|
|
|
switch(src->txr.width) {
|
|
case 8:
|
|
u = 0;
|
|
break;
|
|
case 16:
|
|
u = 1;
|
|
break;
|
|
case 32:
|
|
u = 2;
|
|
break;
|
|
case 64:
|
|
u = 3;
|
|
break;
|
|
case 128:
|
|
u = 4;
|
|
break;
|
|
case 256:
|
|
u = 5;
|
|
break;
|
|
case 512:
|
|
u = 6;
|
|
break;
|
|
case 1024:
|
|
u = 7;
|
|
break;
|
|
default:
|
|
assert_msg(0, "Invalid texture U size");
|
|
u = 0;
|
|
break;
|
|
}
|
|
|
|
switch(src->txr.height) {
|
|
case 8:
|
|
v = 0;
|
|
break;
|
|
case 16:
|
|
v = 1;
|
|
break;
|
|
case 32:
|
|
v = 2;
|
|
break;
|
|
case 64:
|
|
v = 3;
|
|
break;
|
|
case 128:
|
|
v = 4;
|
|
break;
|
|
case 256:
|
|
v = 5;
|
|
break;
|
|
case 512:
|
|
v = 6;
|
|
break;
|
|
case 1024:
|
|
v = 7;
|
|
break;
|
|
default:
|
|
assert_msg(0, "Invalid texture V size");
|
|
v = 0;
|
|
break;
|
|
}
|
|
|
|
dst->mode2 |= (u << PVR_TA_PM2_USIZE_SHIFT) & PVR_TA_PM2_USIZE_MASK;
|
|
dst->mode2 |= (v << PVR_TA_PM2_VSIZE_SHIFT) & PVR_TA_PM2_VSIZE_MASK;
|
|
|
|
/* Polygon mode 3 */
|
|
dst->mode3 = (src->txr.mipmap << PVR_TA_PM3_MIPMAP_SHIFT) & PVR_TA_PM3_MIPMAP_MASK;
|
|
dst->mode3 |= (src->txr.format << PVR_TA_PM3_TXRFMT_SHIFT) & PVR_TA_PM3_TXRFMT_MASK;
|
|
|
|
txr_base = (ptr_t)src->txr.base-(ptr_t)emu_vram;
|
|
txr_base = (txr_base & 0x00fffff8) >> 3;
|
|
dst->mode3 |= txr_base;
|
|
}
|
|
|
|
dst->argb = 0xFFFFFFFF;
|
|
dst->oargb = 0x00000000;
|
|
}
|
|
|
|
void pvr_mod_compile(pvr_mod_hdr_t *dst, pvr_list_t list, uint32 mode,
|
|
uint32 cull) {
|
|
dst->cmd = PVR_CMD_MODIFIER;
|
|
dst->cmd |= (list << PVR_TA_CMD_TYPE_SHIFT) & PVR_TA_CMD_TYPE_MASK;
|
|
|
|
dst->mode1 = (mode << PVR_TA_PM1_MODIFIERINST_SHIFT) & PVR_TA_PM1_MODIFIERINST_MASK;
|
|
dst->mode1 |= (cull << PVR_TA_PM1_CULLING_SHIFT) & PVR_TA_PM1_CULLING_MASK;
|
|
|
|
dst->d1 = dst->d2 = dst->d3 = dst->d4 = dst->d5 = dst->d6 = 0;
|
|
}
|
|
|
|
/* Compile a polygon context into a polygon header that is affected by
|
|
modifier volumes */
|
|
void pvr_poly_mod_compile(pvr_poly_mod_hdr_t *dst, pvr_poly_cxt_t *src) {
|
|
int u, v;
|
|
uint32 txr_base;
|
|
|
|
/* Basically we just take each parameter, clip it, shift it
|
|
into place, and OR it into the final result. */
|
|
|
|
/* The base values for CMD */
|
|
dst->cmd = PVR_CMD_POLYHDR;
|
|
|
|
if(src->txr.enable == PVR_TEXTURE_ENABLE)
|
|
dst->cmd |= 8;
|
|
|
|
/* Or in the list type, shading type, color and UV formats */
|
|
dst->cmd |= (src->list_type << PVR_TA_CMD_TYPE_SHIFT) & PVR_TA_CMD_TYPE_MASK;
|
|
dst->cmd |= (src->fmt.color << PVR_TA_CMD_CLRFMT_SHIFT) & PVR_TA_CMD_CLRFMT_MASK;
|
|
dst->cmd |= (src->gen.shading << PVR_TA_CMD_SHADE_SHIFT) & PVR_TA_CMD_SHADE_MASK;
|
|
dst->cmd |= (src->fmt.uv << PVR_TA_CMD_UVFMT_SHIFT) & PVR_TA_CMD_UVFMT_MASK;
|
|
dst->cmd |= (src->gen.clip_mode << PVR_TA_CMD_USERCLIP_SHIFT) & PVR_TA_CMD_USERCLIP_MASK;
|
|
dst->cmd |= (src->fmt.modifier << PVR_TA_CMD_MODIFIER_SHIFT) & PVR_TA_CMD_MODIFIER_MASK;
|
|
dst->cmd |= (src->gen.modifier_mode << PVR_TA_CMD_MODIFIERMODE_SHIFT) & PVR_TA_CMD_MODIFIERMODE_MASK;
|
|
dst->cmd |= (src->gen.specular << PVR_TA_CMD_SPECULAR_SHIFT) & PVR_TA_CMD_SPECULAR_MASK;
|
|
|
|
/* Polygon mode 1 */
|
|
dst->mode1 = (src->depth.comparison << PVR_TA_PM1_DEPTHCMP_SHIFT) & PVR_TA_PM1_DEPTHCMP_MASK;
|
|
dst->mode1 |= (src->gen.culling << PVR_TA_PM1_CULLING_SHIFT) & PVR_TA_PM1_CULLING_MASK;
|
|
dst->mode1 |= (src->depth.write << PVR_TA_PM1_DEPTHWRITE_SHIFT) & PVR_TA_PM1_DEPTHWRITE_MASK;
|
|
dst->mode1 |= (src->txr.enable << PVR_TA_PM1_TXRENABLE_SHIFT) & PVR_TA_PM1_TXRENABLE_MASK;
|
|
|
|
/* Polygon mode 2 (outside volume) */
|
|
dst->mode2_0 = (src->blend.src << PVR_TA_PM2_SRCBLEND_SHIFT) & PVR_TA_PM2_SRCBLEND_MASK;
|
|
dst->mode2_0 |= (src->blend.dst << PVR_TA_PM2_DSTBLEND_SHIFT) & PVR_TA_PM2_DSTBLEND_MASK;
|
|
dst->mode2_0 |= (src->blend.src_enable << PVR_TA_PM2_SRCENABLE_SHIFT) & PVR_TA_PM2_SRCENABLE_MASK;
|
|
dst->mode2_0 |= (src->blend.dst_enable << PVR_TA_PM2_DSTENABLE_SHIFT) & PVR_TA_PM2_DSTENABLE_MASK;
|
|
dst->mode2_0 |= (src->gen.fog_type << PVR_TA_PM2_FOG_SHIFT) & PVR_TA_PM2_FOG_MASK;
|
|
dst->mode2_0 |= (src->gen.color_clamp << PVR_TA_PM2_CLAMP_SHIFT) & PVR_TA_PM2_CLAMP_MASK;
|
|
dst->mode2_0 |= (src->gen.alpha << PVR_TA_PM2_ALPHA_SHIFT) & PVR_TA_PM2_ALPHA_MASK;
|
|
|
|
if(src->txr.enable == PVR_TEXTURE_DISABLE) {
|
|
dst->mode3_0 = 0;
|
|
}
|
|
else {
|
|
dst->mode2_0 |= (src->txr.alpha << PVR_TA_PM2_TXRALPHA_SHIFT) & PVR_TA_PM2_TXRALPHA_MASK;
|
|
dst->mode2_0 |= (src->txr.uv_flip << PVR_TA_PM2_UVFLIP_SHIFT) & PVR_TA_PM2_UVFLIP_MASK;
|
|
dst->mode2_0 |= (src->txr.uv_clamp << PVR_TA_PM2_UVCLAMP_SHIFT) & PVR_TA_PM2_UVCLAMP_MASK;
|
|
dst->mode2_0 |= (src->txr.filter << PVR_TA_PM2_FILTER_SHIFT) & PVR_TA_PM2_FILTER_MASK;
|
|
dst->mode2_0 |= (src->txr.mipmap_bias << PVR_TA_PM2_MIPBIAS_SHIFT) & PVR_TA_PM2_MIPBIAS_MASK;
|
|
dst->mode2_0 |= (src->txr.env << PVR_TA_PM2_TXRENV_SHIFT) & PVR_TA_PM2_TXRENV_MASK;
|
|
|
|
switch(src->txr.width) {
|
|
case 8:
|
|
u = 0;
|
|
break;
|
|
case 16:
|
|
u = 1;
|
|
break;
|
|
case 32:
|
|
u = 2;
|
|
break;
|
|
case 64:
|
|
u = 3;
|
|
break;
|
|
case 128:
|
|
u = 4;
|
|
break;
|
|
case 256:
|
|
u = 5;
|
|
break;
|
|
case 512:
|
|
u = 6;
|
|
break;
|
|
case 1024:
|
|
u = 7;
|
|
break;
|
|
default:
|
|
assert_msg(0, "Invalid texture U size");
|
|
u = 0;
|
|
break;
|
|
}
|
|
|
|
switch(src->txr.height) {
|
|
case 8:
|
|
v = 0;
|
|
break;
|
|
case 16:
|
|
v = 1;
|
|
break;
|
|
case 32:
|
|
v = 2;
|
|
break;
|
|
case 64:
|
|
v = 3;
|
|
break;
|
|
case 128:
|
|
v = 4;
|
|
break;
|
|
case 256:
|
|
v = 5;
|
|
break;
|
|
case 512:
|
|
v = 6;
|
|
break;
|
|
case 1024:
|
|
v = 7;
|
|
break;
|
|
default:
|
|
assert_msg(0, "Invalid texture V size");
|
|
v = 0;
|
|
break;
|
|
}
|
|
|
|
dst->mode2_0 |= (u << PVR_TA_PM2_USIZE_SHIFT) & PVR_TA_PM2_USIZE_MASK;
|
|
dst->mode2_0 |= (v << PVR_TA_PM2_VSIZE_SHIFT) & PVR_TA_PM2_VSIZE_MASK;
|
|
|
|
/* Polygon mode 3 (outside volume) */
|
|
dst->mode3_0 = (src->txr.mipmap << PVR_TA_PM3_MIPMAP_SHIFT) & PVR_TA_PM3_MIPMAP_MASK;
|
|
dst->mode3_0 |= (src->txr.format << PVR_TA_PM3_TXRFMT_SHIFT) & PVR_TA_PM3_TXRFMT_MASK;
|
|
|
|
/* Convert the texture address */
|
|
txr_base = (ptr_t)src->txr.base-(ptr_t)emu_vram;
|
|
txr_base = (txr_base & 0x00fffff8) >> 3;
|
|
dst->mode3_0 |= txr_base;
|
|
}
|
|
|
|
/* Polygon mode 2 (within volume) */
|
|
dst->mode2_1 = (src->blend.src2 << PVR_TA_PM2_SRCBLEND_SHIFT) & PVR_TA_PM2_SRCBLEND_MASK;
|
|
dst->mode2_1 |= (src->blend.dst2 << PVR_TA_PM2_DSTBLEND_SHIFT) & PVR_TA_PM2_DSTBLEND_MASK;
|
|
dst->mode2_1 |= (src->blend.src_enable2 << PVR_TA_PM2_SRCENABLE_SHIFT) & PVR_TA_PM2_SRCENABLE_MASK;
|
|
dst->mode2_1 |= (src->blend.dst_enable2 << PVR_TA_PM2_DSTENABLE_SHIFT) & PVR_TA_PM2_DSTENABLE_MASK;
|
|
dst->mode2_1 |= (src->gen.fog_type2 << PVR_TA_PM2_FOG_SHIFT) & PVR_TA_PM2_FOG_MASK;
|
|
dst->mode2_1 |= (src->gen.color_clamp2 << PVR_TA_PM2_CLAMP_SHIFT) & PVR_TA_PM2_CLAMP_MASK;
|
|
dst->mode2_1 |= (src->gen.alpha2 << PVR_TA_PM2_ALPHA_SHIFT) & PVR_TA_PM2_ALPHA_MASK;
|
|
|
|
if(src->txr2.enable == PVR_TEXTURE_DISABLE) {
|
|
dst->mode3_1 = 0;
|
|
}
|
|
else {
|
|
dst->mode2_1 |= (src->txr2.alpha << PVR_TA_PM2_TXRALPHA_SHIFT) & PVR_TA_PM2_TXRALPHA_MASK;
|
|
dst->mode2_1 |= (src->txr2.uv_flip << PVR_TA_PM2_UVFLIP_SHIFT) & PVR_TA_PM2_UVFLIP_MASK;
|
|
dst->mode2_1 |= (src->txr2.uv_clamp << PVR_TA_PM2_UVCLAMP_SHIFT) & PVR_TA_PM2_UVCLAMP_MASK;
|
|
dst->mode2_1 |= (src->txr2.filter << PVR_TA_PM2_FILTER_SHIFT) & PVR_TA_PM2_FILTER_MASK;
|
|
dst->mode2_1 |= (src->txr2.mipmap_bias << PVR_TA_PM2_MIPBIAS_SHIFT) & PVR_TA_PM2_MIPBIAS_MASK;
|
|
dst->mode2_1 |= (src->txr2.env << PVR_TA_PM2_TXRENV_SHIFT) & PVR_TA_PM2_TXRENV_MASK;
|
|
|
|
switch(src->txr2.width) {
|
|
case 8:
|
|
u = 0;
|
|
break;
|
|
case 16:
|
|
u = 1;
|
|
break;
|
|
case 32:
|
|
u = 2;
|
|
break;
|
|
case 64:
|
|
u = 3;
|
|
break;
|
|
case 128:
|
|
u = 4;
|
|
break;
|
|
case 256:
|
|
u = 5;
|
|
break;
|
|
case 512:
|
|
u = 6;
|
|
break;
|
|
case 1024:
|
|
u = 7;
|
|
break;
|
|
default:
|
|
assert_msg(0, "Invalid texture U size");
|
|
u = 0;
|
|
break;
|
|
}
|
|
|
|
switch(src->txr2.height) {
|
|
case 8:
|
|
v = 0;
|
|
break;
|
|
case 16:
|
|
v = 1;
|
|
break;
|
|
case 32:
|
|
v = 2;
|
|
break;
|
|
case 64:
|
|
v = 3;
|
|
break;
|
|
case 128:
|
|
v = 4;
|
|
break;
|
|
case 256:
|
|
v = 5;
|
|
break;
|
|
case 512:
|
|
v = 6;
|
|
break;
|
|
case 1024:
|
|
v = 7;
|
|
break;
|
|
default:
|
|
assert_msg(0, "Invalid texture V size");
|
|
v = 0;
|
|
break;
|
|
}
|
|
|
|
dst->mode2_1 |= (u << PVR_TA_PM2_USIZE_SHIFT) & PVR_TA_PM2_USIZE_MASK;
|
|
dst->mode2_1 |= (v << PVR_TA_PM2_VSIZE_SHIFT) & PVR_TA_PM2_VSIZE_MASK;
|
|
|
|
/* Polygon mode 3 (within volume) */
|
|
dst->mode3_1 = (src->txr2.mipmap << PVR_TA_PM3_MIPMAP_SHIFT) & PVR_TA_PM3_MIPMAP_MASK;
|
|
dst->mode3_1 |= (src->txr2.format << PVR_TA_PM3_TXRFMT_SHIFT) & PVR_TA_PM3_TXRFMT_MASK;
|
|
|
|
/* Convert the texture address */
|
|
txr_base = (ptr_t)src->txr2.base-(ptr_t)emu_vram;
|
|
txr_base = (txr_base & 0x00fffff8) >> 3;
|
|
dst->mode3_1 |= txr_base;
|
|
}
|
|
|
|
dst->d1 = dst->d2 = 0xffffffff;
|
|
}
|
|
|
|
/* Create a colored polygon context for polygons affected by modifier volumes */
|
|
void pvr_poly_cxt_col_mod(pvr_poly_cxt_t *dst, pvr_list_t list) {
|
|
int alpha;
|
|
|
|
/* Start off blank */
|
|
memset(dst, 0, sizeof(pvr_poly_cxt_t));
|
|
|
|
/* Fill in a few values */
|
|
dst->list_type = list;
|
|
alpha = list > PVR_LIST_OP_MOD;
|
|
dst->fmt.color = PVR_CLRFMT_ARGBPACKED;
|
|
dst->fmt.uv = PVR_UVFMT_32BIT;
|
|
dst->gen.shading = PVR_SHADE_GOURAUD;
|
|
dst->depth.comparison = PVR_DEPTHCMP_GREATER;
|
|
dst->depth.write = PVR_DEPTHWRITE_ENABLE;
|
|
dst->gen.culling = PVR_CULLING_CCW;
|
|
dst->fmt.modifier = PVR_MODIFIER_ENABLE;
|
|
dst->gen.modifier_mode = PVR_MODIFIER_NORMAL;
|
|
dst->txr.enable = PVR_TEXTURE_DISABLE;
|
|
dst->txr2.enable = PVR_TEXTURE_DISABLE;
|
|
|
|
if(!alpha) {
|
|
dst->gen.alpha = PVR_ALPHA_DISABLE;
|
|
dst->blend.src = PVR_BLEND_ONE;
|
|
dst->blend.dst = PVR_BLEND_ZERO;
|
|
dst->gen.alpha2 = PVR_ALPHA_DISABLE;
|
|
dst->blend.src2 = PVR_BLEND_ONE;
|
|
dst->blend.dst2 = PVR_BLEND_ZERO;
|
|
}
|
|
else {
|
|
dst->gen.alpha = PVR_ALPHA_ENABLE;
|
|
dst->blend.src = PVR_BLEND_SRCALPHA;
|
|
dst->blend.dst = PVR_BLEND_INVSRCALPHA;
|
|
dst->gen.alpha2 = PVR_ALPHA_ENABLE;
|
|
dst->blend.src2 = PVR_BLEND_SRCALPHA;
|
|
dst->blend.dst2 = PVR_BLEND_INVSRCALPHA;
|
|
}
|
|
|
|
dst->blend.src_enable = PVR_BLEND_DISABLE;
|
|
dst->blend.dst_enable = PVR_BLEND_DISABLE;
|
|
dst->gen.fog_type = PVR_FOG_DISABLE;
|
|
dst->gen.color_clamp = PVR_CLRCLAMP_DISABLE;
|
|
dst->blend.src_enable2 = PVR_BLEND_DISABLE;
|
|
dst->blend.dst_enable2 = PVR_BLEND_DISABLE;
|
|
dst->gen.fog_type2 = PVR_FOG_DISABLE;
|
|
dst->gen.color_clamp2 = PVR_CLRCLAMP_DISABLE;
|
|
}
|
|
|
|
/* Create a textured polygon context for polygons affected by modifier
|
|
volumes */
|
|
void pvr_poly_cxt_txr_mod(pvr_poly_cxt_t *dst, pvr_list_t list,
|
|
int textureformat, int tw, int th,
|
|
pvr_ptr_t textureaddr, int filtering,
|
|
int textureformat2, int tw2, int th2,
|
|
pvr_ptr_t textureaddr2, int filtering2) {
|
|
int alpha;
|
|
|
|
/* Start off blank */
|
|
memset(dst, 0, sizeof(pvr_poly_cxt_t));
|
|
|
|
/* Fill in a few values */
|
|
dst->list_type = list;
|
|
alpha = list > PVR_LIST_OP_MOD;
|
|
dst->fmt.color = PVR_CLRFMT_ARGBPACKED;
|
|
dst->fmt.uv = PVR_UVFMT_32BIT;
|
|
dst->gen.shading = PVR_SHADE_GOURAUD;
|
|
dst->depth.comparison = PVR_DEPTHCMP_GREATER;
|
|
dst->depth.write = PVR_DEPTHWRITE_ENABLE;
|
|
dst->gen.culling = PVR_CULLING_CCW;
|
|
dst->fmt.modifier = PVR_MODIFIER_ENABLE;
|
|
dst->gen.modifier_mode = PVR_MODIFIER_NORMAL;
|
|
dst->txr.enable = PVR_TEXTURE_ENABLE;
|
|
dst->txr2.enable = PVR_TEXTURE_ENABLE;
|
|
|
|
if(!alpha) {
|
|
dst->gen.alpha = PVR_ALPHA_DISABLE;
|
|
dst->txr.alpha = PVR_TXRALPHA_ENABLE;
|
|
dst->blend.src = PVR_BLEND_ONE;
|
|
dst->blend.dst = PVR_BLEND_ZERO;
|
|
dst->txr.env = PVR_TXRENV_MODULATE;
|
|
dst->gen.alpha2 = PVR_ALPHA_DISABLE;
|
|
dst->txr2.alpha = PVR_TXRALPHA_ENABLE;
|
|
dst->blend.src2 = PVR_BLEND_ONE;
|
|
dst->blend.dst2 = PVR_BLEND_ZERO;
|
|
dst->txr2.env = PVR_TXRENV_MODULATE;
|
|
}
|
|
else {
|
|
dst->gen.alpha = PVR_ALPHA_ENABLE;
|
|
dst->txr.alpha = PVR_TXRALPHA_ENABLE;
|
|
dst->blend.src = PVR_BLEND_SRCALPHA;
|
|
dst->blend.dst = PVR_BLEND_INVSRCALPHA;
|
|
dst->txr.env = PVR_TXRENV_MODULATEALPHA;
|
|
dst->gen.alpha2 = PVR_ALPHA_ENABLE;
|
|
dst->txr2.alpha = PVR_TXRALPHA_ENABLE;
|
|
dst->blend.src2 = PVR_BLEND_SRCALPHA;
|
|
dst->blend.dst2 = PVR_BLEND_INVSRCALPHA;
|
|
dst->txr2.env = PVR_TXRENV_MODULATEALPHA;
|
|
}
|
|
|
|
dst->blend.src_enable = PVR_BLEND_DISABLE;
|
|
dst->blend.dst_enable = PVR_BLEND_DISABLE;
|
|
dst->gen.fog_type = PVR_FOG_DISABLE;
|
|
dst->gen.color_clamp = PVR_CLRCLAMP_DISABLE;
|
|
dst->txr.uv_flip = PVR_UVFLIP_NONE;
|
|
dst->txr.uv_clamp = PVR_UVCLAMP_NONE;
|
|
dst->txr.filter = filtering;
|
|
dst->txr.mipmap_bias = PVR_MIPBIAS_NORMAL;
|
|
dst->txr.width = tw;
|
|
dst->txr.height = th;
|
|
dst->txr.base = textureaddr;
|
|
dst->txr.format = textureformat;
|
|
dst->blend.src_enable2 = PVR_BLEND_DISABLE;
|
|
dst->blend.dst_enable2 = PVR_BLEND_DISABLE;
|
|
dst->gen.fog_type2 = PVR_FOG_DISABLE;
|
|
dst->gen.color_clamp2 = PVR_CLRCLAMP_DISABLE;
|
|
dst->txr2.uv_flip = PVR_UVFLIP_NONE;
|
|
dst->txr2.uv_clamp = PVR_UVCLAMP_NONE;
|
|
dst->txr2.filter = filtering2;
|
|
dst->txr2.mipmap_bias = PVR_MIPBIAS_NORMAL;
|
|
dst->txr2.width = tw2;
|
|
dst->txr2.height = th2;
|
|
dst->txr2.base = textureaddr2;
|
|
dst->txr2.format = textureformat2;
|
|
}
|