Skip to content

Instantly share code, notes, and snippets.

@Erick194
Created February 2, 2020 12:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Erick194/41c9ee0ac44e3a4c4daa952ac28f1b28 to your computer and use it in GitHub Desktop.
Save Erick194/41c9ee0ac44e3a4c4daa952ac28f1b28 to your computer and use it in GitHub Desktop.
//This code is a modified version of the VALLOC.C of Mortal Kombat 3 PlayStation version and used in PSXDOOM.
int PageCount = 0;//*(r28 + 2628)
int TextureCacheIdx = 0;//80077A40
int xycount = 0; //*(r28 + 3212);
int xcount = 0; //*(r28 + 3320)
int ycount = 0; //*(r28 + 3324)
int V_PagFlags = 0;//*(r28 + 1576)//80077A38
#define MAX_VRAMMEM 256 // # of entries in manager cache
#define MAX_DYNAMIC_TPAGE 11 // max # of tpages supported for dynamic memory
#define MIN_VRAM_ALLOC_SIZE 16 // each tpage is divided into this many number of squares
#define MIN_VRAM_ALLOC_SHIFT 4 // shift to simulate the divide of (MIN_VRAM_ALLOC_SIZE)
#define VRAMSIZE (sizeof(int) * MAX_DYNAMIC_TPAGE * MAX_VRAMMEM)
/* VRAM memory allocation structure */
typedef struct v_vrammem
{
psxobj_t *imgobj[MAX_VRAMMEM]; // ptr to start addr of image
} VRAMMEM;
VRAMMEM *vram_cache;//80077DA0
void Init_Vram_Cache(void)//800333A0
{
vram_cache = (VRAMMEM *)Z_Malloc((sizeof(VRAMMEM) * MAX_DYNAMIC_TPAGE), PU_STATIC, 0);
D_memset(vram_cache, 0, (sizeof(VRAMMEM) *MAX_DYNAMIC_TPAGE));
Valloc_Init();
}
void TextureCache(psxobj_t *psxobj)
{
RECT frame;
psxobj_t **imgobj;
unsigned long *vram, *vram2;
byte *tmp;
psxobj_t *psxobj1;
byte *data;
unsigned int lastpage;
int x, y;
short xs, ys;
lastpage = PageCount;
psxobj->index = TextureCacheIdx;
if (psxobj->vtpage == 0)
{
check_again:
if ((psxobj->vbasex + xcount) > MIN_VRAM_ALLOC_SIZE)
{
ycount += xycount;
xcount = 0;
xycount = 0;
}
if ((psxobj->vbasey + ycount) > MIN_VRAM_ALLOC_SIZE)
{
do
{
PageCount = (PageCount + 1) % MAX_DYNAMIC_TPAGE;
} while ((V_PagFlags >> (PageCount & 0x1f) & 1U) != 0);
if (PageCount == lastpage)
{
I_Error("Texture Cache Overflow\n");
}
xcount = 0;
ycount = 0;
xycount = 0;
}
imgobj = &vram_cache[PageCount].imgobj[(ycount * MIN_VRAM_ALLOC_SIZE) + xcount];
vram = (unsigned long*)imgobj;
xs = psxobj->vbasex; // xsize of alloc block
ys = psxobj->vbasey; // ysize of alloc block
// copy address object into the block
for (y = 0; y < ys; y++, vram += (MIN_VRAM_ALLOC_SIZE - xs))
{
for (x = 0; x < xs; x++, vram++)
{
psxobj1 = (psxobj_t *)*(unsigned long*)vram;//get address obj on vram
if (psxobj1 != 0)
{
if (psxobj1->index == TextureCacheIdx)
{
xcount += psxobj1->vbasex;
if (xycount < psxobj1->vbasey)
xycount = psxobj1->vbasey;
goto check_again;
}
else
V_ClearBlock(psxobj1);
}
}
}
vram2 = (unsigned long*)imgobj;
xs = psxobj->vbasex; // xsize of alloc block
ys = psxobj->vbasey; // ysize of alloc block
// copy address object into the block
for (y = 0; y < ys; y++, vram2 += (MIN_VRAM_ALLOC_SIZE - xs))
{
for (x = 0; x < xs; x++, vram2++)
{
*(unsigned long *)vram2 = (unsigned long)(void*)psxobj;
}
}
data = (byte *)W_CacheLumpNum(psxobj->lump, PU_CACHE, false);
if (lumpencode[psxobj->lump] == 0)
{
tmp = (byte *)tempbuffer;
decode(data, tmp);
data = tmp;
}
// copy address vram into the object
psxobj->vptr = (unsigned long*)imgobj;
frame.x = PagesXY[PageCount][0] + (xcount << 3);
frame.y = PagesXY[PageCount][1] + (ycount << 4);
frame.w = ((psxobj->w) << 16) >> 17;
frame.h = psxobj->h;
LoadImage(&frame, (unsigned long*)(byte*)(data + 8));
psxobj->vramx = (xcount << 4);
psxobj->vramy = (ycount << 4);
psxobj->vtpage = GetTPage(1, 0, (PageCount + 4) * 128, PagesXY[PageCount][1]);
xcount += psxobj->vbasex;
if (xycount < psxobj->vbasey)
xycount = psxobj->vbasey;
}
}
void V_ClearBlock(psxobj_t *psxobj)
{
unsigned long *vmptr;
int x, y;
short xs, ys;
vmptr = (unsigned long *)psxobj->vptr;
psxobj->vtpage = 0; // erase texture page ID.
xs = psxobj->vbasex; // xsize of alloc block
ys = psxobj->vbasey; // ysize of alloc block
// erase address block
for (y = 0; y < ys; y++, vmptr += (MIN_VRAM_ALLOC_SIZE - xs))
{
for (x = 0; x < xs; x++, vmptr++)
{
*vmptr = 0; // zero block
}
}
}
void Valloc_Init(void)
{
int obj, j, i;
short xs, ys;
psxobj_t *psxobj;
psxobj_t **imgobj;
unsigned long *vmptr;
unsigned int page;
unsigned int pagenum;
unsigned int flags;
for (page = 0; page < MAX_DYNAMIC_TPAGE; page = pagenum + 1)
{
do
{
pagenum = page;
page = pagenum + 1;
} while ((V_PagFlags >> (pagenum & 0x1f)) & 1U);
imgobj = vram_cache[pagenum].imgobj;
for (obj = 0; obj < MAX_VRAMMEM; obj++, imgobj++)
{
psxobj = *imgobj;
if (psxobj != 0)
{
vmptr = (unsigned long *)psxobj->vptr;
psxobj->vtpage = 0; // erase texture page ID.
xs = psxobj->vbasex; // xsize of alloc block
ys = psxobj->vbasey; // ysize of alloc block
// erase address block
for (j = 0; j < ys; j++, vmptr += (MIN_VRAM_ALLOC_SIZE - xs))
{
for (i = 0; i < xs; i++, vmptr++)
{
*vmptr = 0; // zero block
}
}
}
}
}
// Set Page Position
PageCount = 0;
flags = V_PagFlags & 1;
while (flags != 0)
{
PageCount = (PageCount + 1) % MAX_DYNAMIC_TPAGE;
flags = V_PagFlags >> (PageCount & MAX_DYNAMIC_TPAGE) & 1;
}
//Reset Positions
xycount = 0;
xcount = 0;
ycount = 0;
}
void Vram_Viewer(int page)//80033938
{
psxobj_t **imgobj;
psxobj_t *psxobj;
int i, xpos, ypos, w, y, h, obj;
POLY_FT4 *pagepic = (POLY_FT4*) getScratchAddr(128);//1F800200
LINE_F2 *line = (LINE_F2*) getScratchAddr(128);//1F800200
setPolyFT4(pagepic);
setRGB0(pagepic, 128, 128, 128);
setXYWH(pagepic, 0, 0, 256, 240);
setUVWH(pagepic, 0, 0, 255, 255);
pagepic->tpage = GetTPage(1, 0, (page + 4) * 128, PagesXY[page][1]);
pagepic->clut =palette[0];
W_AddPrim (pagepic);
imgobj = vram_cache[page].imgobj;
for (obj = 0; obj < MAX_VRAMMEM; obj++, imgobj++)
{
psxobj = *imgobj;
if(psxobj)
{
y = psxobj->vramy;
xpos = psxobj->vramx;
y = (y << 4) - y << 4;
if(y < 0)
{
y += 255;
}
h = psxobj->h;
w = psxobj->w;
h = (h << 4) - h << 4;
ypos = y >> 8;
if(h < 0)
{
h += 255;
}
h = (h >> 8);
setLineF2(line);
setRGB0(line, 255, 0, 0);
//top line
setXY2(line, xpos, ypos, xpos + w, ypos);
W_AddPrim (line);
//right line
setXY2(line, xpos + w, ypos, xpos + w, ypos + h);
W_AddPrim (line);
//bottom line
setXY2(line, xpos + w, ypos + h, xpos, ypos + h);
W_AddPrim (line);
//left line
setXY2(line, xpos, ypos + h, xpos, ypos);
W_AddPrim (line);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment