Implement shadows for walls

This commit is contained in:
jndean
2023-11-03 20:14:34 +00:00
parent 6908ef7843
commit ffceed917d
18 changed files with 164 additions and 92 deletions

View File

@@ -1,5 +1,5 @@
# Things that are interesting about IpuDoom
## Things that are interesting about IpuDoom
- Fixed precision int math
- 64-bit int division
@@ -10,9 +10,16 @@
- Save 50-60k of lookup tabes for transcendentals by using float functions
- Store textures on other tiles, JIT-fetch as needed (by live patching exchange programs to select a tile)
- Can call exchanges from deep in the call stack, don't need to exit the vertex
- Texture tiles also do colour mapping to create shadow effects (light dropoff)
#### Things I don't support, to make my life easier:
### Places could save memory
- Transcendental lookups -> live calc
- Move scalelight table from render tiles to texture tiles, include light level in column request. Saves 8K
### Things I don't support, to make my life easier:
- gamemodes other than shareware
- multiplayer
- cheating

View File

@@ -27,16 +27,18 @@ Activity Log:
- [x] IPU interacts with host to load and unpack all level geometry from disk whenever a level is loaded
- [x] Implement all methods used by the automap (vector rendering, sprite rendering, AM event responder). Automap is now disabled on CPU, renders entirely on IPU.
![automap](https://static.wikia.nocookie.net/doom/images/9/9c/Automap.png)
![automap](README_imgs/Automap.gif)
- [x] Implement BinarySpacePartion search (stackless recursion version for IPU), solidseg occlusion and floor/ceiling clipping to get (untextured) rendering of vertical walls running on the IPU. CPU still renders everything else.
![gameplay gif](README_imgs/flats.gif)
- [x] Implement BinarySpacePartion search (stackless recursion version for IPU), solidseg occlusion and floor/ceiling clipping to get (untextured) rendering of vertical walls running on the IPU. CPU still renders everything else (floors, ceilings, objects, enemies).
![gameplay with untextured walls](README_imgs/flats.gif)
- [x] Reformat textures into a big buffer that can be striped over dedicated texture tiles, and accessed by the render tiles using JIT-patched exchange programs to enable fetches based on dynamic indices.
![gameplay gif](README_imgs/WallsTextured_noCPU.gif)
- [x] Split rendering across 32 render tiles. Reformat textures into a big buffer that can be striped over dedicated texture tiles, and accessed by the render tiles using JIT-patched exchange programs to enable fetches based on dynamic indices.
![gameplay with textured walls (but nothing else)](README_imgs/WallsTextured_noCPU.gif)
Immediate next steps:
- [x] Get texture tiles to do light level mapping (add shadows to walls)
- [ ] Implement system to notify IPU of map state changes, so that doors open and close properly.
- [ ] Port visplane system to get IPU rendering floors and ceilings
Longer term next steps:

BIN
README_imgs/Automap.gif Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

View File

@@ -34,6 +34,8 @@ extern "C" {
#define IPUMAXNUMTEXTURES (130)
#define IPUCOMMSBUFSIZE (IPUNUMRENDERTILES)
#define COLOURMAPSIZE (8704)
typedef struct {
int gameepisode;

View File

@@ -4,6 +4,8 @@
#include "doomtype.h"
#include "r_data.h"
#include "r_main.h"
#include "r_segs.h"
#include "ipu_interface.h"
#include "ipu_utils.h"
@@ -22,9 +24,12 @@ const int* tileLocalTextureOffsets;
// -------- Components for the tiles that serve textures ------------ //
static pixel_t colourMap_TT[COLOURMAPSIZE];
static pixel_t* scalelight_TT[LIGHTLEVELS][MAXLIGHTSCALE];
extern "C"
__SUPER__
void IPU_R_InitTextureTile(unsigned* progBuf, int progBufSize) {
__SUPER__
void IPU_R_InitTextureTile(unsigned* progBuf, int progBufSize, const pixel_t* colourMapBuf) {
// progBuf starts with a directory of 3 program offsets
unsigned* progHead = progBuf + 3;
unsigned* progEnd = &progBuf[progBufSize];
@@ -68,6 +73,23 @@ void IPU_R_InitTextureTile(unsigned* progBuf, int progBufSize) {
progHead = assembler.assemble(progHead, progEnd - progHead);
progHead++;
}
// Next, precompute light scales from the colourmap. This normally happens in R_ExecuteSetViewSize
memcpy(colourMap_TT, colourMapBuf, sizeof(colourMap_TT));
for (int i = 0; i < LIGHTLEVELS; i++) {
int startmap = ((LIGHTLEVELS - 1 - i) * 2) * NUMCOLORMAPS / LIGHTLEVELS;
for (int j = 0; j < MAXLIGHTSCALE; j++) {
int level = startmap - j / DISTMAP;
if (level < 0)
level = 0;
if (level >= NUMCOLORMAPS)
level = NUMCOLORMAPS - 1;
scalelight_TT[i][j] = colourMap_TT + level * 256;
}
}
}
extern "C"
@@ -78,7 +100,7 @@ void IPU_R_FulfilColumnRequest(unsigned* progBuf, unsigned char* textureBuf, uns
auto sendProgram = &progBuf[progBuf[1]];
auto aggrProgram = &progBuf[progBuf[2]];
int noise = 0;
// int noise = 0;
while (1) {
@@ -87,23 +109,31 @@ void IPU_R_FulfilColumnRequest(unsigned* progBuf, unsigned char* textureBuf, uns
// Unpack received data
unsigned textureNum = ((IPUColRequest_t*) textureBuf)->texture;
unsigned columnOffset = ((IPUColRequest_t*) textureBuf)->columnOffset;
unsigned lightNum = ((IPUColRequest_t*) textureBuf)->lightNum;
unsigned lightScale = ((IPUColRequest_t*) textureBuf)->lightScale;
byte* col = textureBuf;
// TMP: need seperate send buffer for lightscaled output to be sent from, currently use start of textureBuf
pixel_t* sendBuf = &textureBuf[IPUTEXTURETILEBUFSIZE - (IPUTEXTURECACHELINESIZE * sizeof(int))];
if (textureNum != 0xffffffff &&
textureNum >= tileLocalTextureRange[0] &&
textureNum < tileLocalTextureRange[1]) {
col = &textureBuf[tileLocalTextureOffsets[textureNum] + columnOffset];
byte* src = &textureBuf[tileLocalTextureOffsets[textureNum] + columnOffset];
pixel_t* dc_colourmap = scalelight_TT[lightNum][lightScale];
for (int i = 0; i < IPUTEXTURECACHELINESIZE * sizeof(int); ++i) {
sendBuf[i] = dc_colourmap[src[i]];
}
}
// noise = (noise + 1) % 4;
// noise = (noise + 1) % 6;
// unsigned renderStripe = (tileID - IPUFIRSTTEXTURETILE) / IPUTEXTURETILESPERRENDERTILE;
// {
// // unsigned colour = (renderStripe * 9) % 256;
// colour = colour | (colour << 8) | (colour << 16) | (colour << 24);
// // colour = colour | (colour << 8) | (colour << 16) | (colour << 24);
// for (int i = 0; i < IPUTEXTURECACHELINESIZE; i++) {
// if (noise == 0) {
// ((unsigned*)col)[i] += 0x01010101;
// ((unsigned*)col)[i] += 0x01010101u;
// }
// // ((unsigned*)col)[i] = colour;
// }
@@ -122,7 +152,8 @@ void IPU_R_FulfilColumnRequest(unsigned* progBuf, unsigned char* textureBuf, uns
// col = textureBuf;
// }
XCOM_Execute(sendProgram, col, NULL);
XCOM_Execute(sendProgram, sendBuf, NULL);
// XCOM_Execute(sendProgram, col, NULL);
XCOM_Execute(aggrProgram, NULL, commsBuf);
@@ -220,6 +251,8 @@ byte* IPU_R_RequestColumn(int texture, int column) {
IPUColRequest_t *request = (IPUColRequest_t*) tileLocalTextureBuf;
request->texture = texture;
request->columnOffset = (column & texturewidthmask[texture]) * (textureheight[texture] >> FRACBITS);
request->lightNum = lightnum;
request->lightScale = walllightindex;
*((unsigned*) &request[1]) = 0; // The Done Flag
XCOM_Execute(
@@ -310,13 +343,29 @@ void IPU_R_RenderTileDone() {
// -------- Components for the sans tiles ------------ //
extern "C"
__SUPER__
void IPU_R_InitSansTile(unsigned* progBuf, int progBufSize) {
// progBuf starts with a directory of 3 program offsets
unsigned* progHead = progBuf + 1;
unsigned* progEnd = &progBuf[progBufSize];
// First program receives the `done` flag
progBuf[0] = progHead - progBuf;
XCOMAssembler assembler;
int aggrTile = XCOM_logical2physical(IPUFIRSTRENDERTILE);
int sendCycle = XCOM_WORSTSENDDELAY;
int muxCycle = sendCycle + XCOM_TimeToMux(aggrTile, __builtin_ipu_get_tile_id());
assembler.addRecv(0, 1, aggrTile, muxCycle);
progHead = assembler.assemble(progHead, progEnd - progHead);
progHead++;
}
extern "C"
__SUPER__
void IPU_R_Sans(unsigned* progBuf, unsigned* commsBuf) {
// Start of buffer is a directory of programs
auto recvProgram = &progBuf[progBuf[0]];
auto sendProgram = &progBuf[progBuf[1]];
auto aggrProgram = &progBuf[progBuf[2]];
auto aggrProgram = &progBuf[progBuf[0]];
while (1) {
asm volatile(R"(

View File

@@ -12,7 +12,7 @@ extern "C" {
typedef struct {
unsigned texture, columnOffset;
unsigned texture, columnOffset, lightNum, lightScale;
} IPUColRequest_t;
@@ -24,8 +24,9 @@ extern const int* tileLocalTextureOffsets;
__SUPER__ void IPU_R_InitTextureTile(unsigned* progBuf, int progBufSize);
__SUPER__ void IPU_R_InitTextureTile(unsigned* progBuf, int progBufSize, const pixel_t* colourMap);
__SUPER__ void IPU_R_InitColumnRequester(unsigned* progBuf, int progBufSize);
__SUPER__ void IPU_R_InitSansTile(unsigned* progBuf, int progBufSize);
__SUPER__ byte* IPU_R_RequestColumn(int texture, int column);
__SUPER__ void IPU_R_FulfilColumnRequest(unsigned* progBuf, unsigned char* textureBuf, unsigned* commsBuf);

View File

@@ -99,9 +99,10 @@ R_RenderPlayerView_Vertex : public poplar::SupervisorVertex {
struct R_InitTexture_Vertex : public poplar::SupervisorVertex {
poplar::Output<poplar::Vector<unsigned>> progBuf;
poplar::Input<poplar::Vector<unsigned char>> colourMap;
__SUPER__ void compute() {
IPU_R_InitTextureTile(&progBuf[0], progBuf.size());
IPU_R_InitTextureTile(&progBuf[0], progBuf.size(), &colourMap[sizeof(int)]);
}
};
@@ -132,11 +133,8 @@ R_FulfilColumnRequests_Vertex : public poplar::SupervisorVertex {
struct R_InitSans_Vertex : public poplar::SupervisorVertex {
poplar::Output<poplar::Vector<unsigned>> progBuf;
__SUPER__ void compute() {
// Reuse IPU_R_InitTextureTile because the 'done' flag receiving program
// it compiles is perfectly valid for use by a sans tile
IPU_R_InitTextureTile(&progBuf[0], progBuf.size());
IPU_R_InitSansTile(&progBuf[0], progBuf.size());
}
};

View File

@@ -708,8 +708,6 @@ void R_InitTextures_TT(void) {
printf("\b");
}
int totaltexturesize = 0; // JOSEF TMP
for (i = 0; i < numtextures; i++, directory++) {
if (!(i & 63))
printf(".");
@@ -737,8 +735,6 @@ void R_InitTextures_TT(void) {
texture->height = SHORT(mtexture->height);
texture->patchcount = SHORT(mtexture->patchcount);
totaltexturesize += texture->width * texture->height; // JOSEF TMP
memcpy(texture->name, mtexture->name, sizeof(texture->name));
mpatch = &mtexture->patches[0];
patch = &texture->patches[0];
@@ -766,12 +762,6 @@ void R_InitTextures_TT(void) {
totalwidth += texture->width;
}
printf("\n JOSEF: Total Texture Size = %d bytes (%dKb), numtextures = %d\n",
totaltexturesize,
totaltexturesize / 1000,
numtextures
);
Z_Free(patchlookup);
W_ReleaseLumpName(("TEXTURE1"));

View File

@@ -123,7 +123,7 @@ void R_DrawColumn(void) {
if ((unsigned)dc_x >= SCREENWIDTH || dc_yl < 0 || dc_yh >= SCREENHEIGHT) {
printf("ERROR: R_DrawColumn: %u to %u at %u\n", dc_yl, dc_yh, dc_x);
}
char colour = (bspnum - (lightnum & 1)) % 256; // JOSEF: TMP!
// if (tileID >= 16) return; // JOSEF: TMP, Show CPU & IPU side-by-side
// Framebuffer destination address.
// Use ylookup LUT to avoid multiply with ScreenWidth.
@@ -143,7 +143,6 @@ void R_DrawColumn(void) {
// using a lighting/special effects LUT.
// LATER: *dest = dc_colormap[dc_source[(frac >> FRACBITS) & 127]]; // LATER
// *dest = colour;
*dest = dc_source[(frac >> FRACBITS) & 127];
dest += IPUCOLSPERRENDERTILE; // JOSEF: SCREENWIDTH;

View File

@@ -102,9 +102,9 @@ int viewangletox[FINEANGLES / 2];
// from clipangle to -clipangle.
angle_t xtoviewangle[SCREENWIDTH + 1];
// lighttable_t *scalelight[LIGHTLEVELS][MAXLIGHTSCALE]; // JOSEF: TODO
// lighttable_t *scalelightfixed[MAXLIGHTSCALE]; // JOSEF: TODO
// lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ]; // JOSEF: TODO
// lighttable_t *scalelight[LIGHTLEVELS][MAXLIGHTSCALE];// JOSEF: This lives on texture tile instead
// lighttable_t *scalelightfixed[MAXLIGHTSCALE];
// lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ]; // JOSEF: TODO (on texture/flats tile?)
// bumped light from gun blasts
int extralight;
@@ -532,14 +532,13 @@ void R_InitTextureMapping(void) {
clipangle = xtoviewangle[0];
}
/*
//
// R_InitLightTables
// Only inits the zlight table,
// because the scalelight table changes with view size.
//
#define DISTMAP 2
/*
void R_InitLightTables(void) {
int i;
int j;
@@ -635,8 +634,6 @@ void R_ExecuteSetViewSize(void) {
// JOSEF
tileLeftClip = tileID * IPUCOLSPERRENDERTILE;
tileRightClip = tileLeftClip + IPUCOLSPERRENDERTILE;
// tileLeftClip += 1; // Helps visualise multitil rendering :)
// tileRightClip -= 1;
R_InitBuffer(scaledviewwidth, viewheight);
@@ -664,24 +661,25 @@ void R_ExecuteSetViewSize(void) {
cosadj = abs(finecosine[xtoviewangle[i] >> ANGLETOFINESHIFT]);
distscale[i] = FixedDiv(FRACUNIT, cosadj);
}
*/
// JOSEF: Texture tiles handle light levels
// Calculate the light levels to use
// for each level / scale combination.
for (i = 0; i < LIGHTLEVELS; i++) {
startmap = ((LIGHTLEVELS - 1 - i) * 2) * NUMCOLORMAPS / LIGHTLEVELS;
for (j = 0; j < MAXLIGHTSCALE; j++) {
level = startmap - j * SCREENWIDTH / (viewwidth << detailshift) / DISTMAP;
// for (i = 0; i < LIGHTLEVELS; i++) {
// startmap = ((LIGHTLEVELS - 1 - i) * 2) * NUMCOLORMAPS / LIGHTLEVELS;
// for (j = 0; j < MAXLIGHTSCALE; j++) {
// level = startmap - j * SCREENWIDTH / (viewwidth << detailshift) / DISTMAP;
if (level < 0)
level = 0;
// if (level < 0)
// level = 0;
if (level >= NUMCOLORMAPS)
level = NUMCOLORMAPS - 1;
// if (level >= NUMCOLORMAPS)
// level = NUMCOLORMAPS - 1;
scalelight[i][j] = colormaps + level * 256;
}
}
*/
// scalelight[i][j] = colormaps + level * 256; // LATER
// }
// }
}
/*
@@ -764,17 +762,17 @@ void R_SetupFrame(player_t *player) {
sscount = 0;
/* Later
if (player->fixedcolormap) {
fixedcolormap = colormaps + player->fixedcolormap * 256;
printf("JOSEF: Warning: Fixed colourmap being used, need to implement that on texture tiles (send them a special value?)");
// fixedcolormap = colormaps + player->fixedcolormap * 256; // LATER
walllights = scalelightfixed;
// walllights = scalelightfixed; // LATER
for (i = 0; i < MAXLIGHTSCALE; i++)
scalelightfixed[i] = fixedcolormap;
// for (i = 0; i < MAXLIGHTSCALE; i++) // LATER
// scalelightfixed[i] = fixedcolormap;
} else
fixedcolormap = 0;
*/
framecount++;
validcount++;

View File

@@ -61,6 +61,9 @@ extern int loopcount;
#define MAXLIGHTZ 128
#define LIGHTZSHIFT 20
#define DISTMAP 2
extern lighttable_t *scalelight[LIGHTLEVELS][MAXLIGHTSCALE];
extern lighttable_t *scalelightfixed[MAXLIGHTSCALE];
extern lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ];

View File

@@ -90,7 +90,9 @@ fixed_t topstep;
fixed_t bottomfrac;
fixed_t bottomstep;
lighttable_t **walllights;
// lighttable_t **walllights; // JOSEF: texture tiles handle light scaling
int lightnum; // JOSEF: Make this a global to pass to texture tiles
unsigned walllightindex; // JOSEF
short *maskedtexturecol;
@@ -102,7 +104,7 @@ int abs(int); // JOSEF
// R_RenderMaskedSegRange
//
void R_RenderMaskedSegRange(drawseg_t *ds, int x1, int x2) {
unsigned index;
// unsigned index; // Replace with wallightindex?
column_t *col;
int lightnum;
int texnum;
@@ -195,7 +197,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, int x1, int x2) {
__SUPER__
void R_RenderSegLoop(void) {
angle_t angle;
unsigned index;
// unsigned index; // JOSEF: Replaced with walllightindex
int yl;
int yh;
int mid;
@@ -247,12 +249,16 @@ void R_RenderSegLoop(void) {
texturecolumn = rw_offset - FixedMul(finetangent[angle], rw_distance);
texturecolumn >>= FRACBITS;
// calculate lighting
index = rw_scale >> LIGHTSCALESHIFT;
walllightindex = rw_scale >> LIGHTSCALESHIFT; // JOSEF: walllightindex
if (walllightindex >= MAXLIGHTSCALE) // JOSEF: walllightindex
walllightindex = MAXLIGHTSCALE - 1; // JOSEF: walllightindex
// if (tileID == 0 && curline->v1->x == -30932992 && curline->v1->y == -31457280 && curline->v2->x ==-30932992 && curline->v2->y == -14155776)
// dc_colormap = walllights[index]; // JOSEF: Texturetile handles this
if (index >= MAXLIGHTSCALE)
index = MAXLIGHTSCALE - 1;
// dc_colormap = walllights[index]; // LATER
dc_x = rw_x;
dc_iscale = 0xffffffffu / (unsigned)rw_scale;
} else {
@@ -336,7 +342,6 @@ void R_RenderSegLoop(void) {
}
}
int lightnum; // JOSEF: Temprarily made this global for vis
//
// R_StoreWallRange
@@ -349,7 +354,8 @@ void R_StoreWallRange(int start, int stop) {
fixed_t sineval;
angle_t distangle, offsetangle;
fixed_t vtop;
// int lightnum; // JOSEF: Temprarily made this global for vis
// int lightnum; // JOSEF: Made this a global to pass to texture tiles
// don't overflow and crash
if (ds_p == &drawsegs[MAXDRAWSEGS])
return;
@@ -562,16 +568,14 @@ void R_StoreWallRange(int start, int stop) {
else if (curline->v1->x == curline->v2->x)
lightnum++;
// JOSEF: TMP FOR SHADING FLATS
lightnum = (lightnum < 0)? 0: ((lightnum >= LIGHTLEVELS)? LIGHTLEVELS - 1: lightnum);
// LATER
// if (lightnum < 0)
// walllights = scalelight[0];
// else if (lightnum >= LIGHTLEVELS)
// walllights = scalelight[LIGHTLEVELS - 1];
// else
// walllights = scalelight[lightnum];
// JOSEF: Clip now, then let the texture tile do the walllights lookup later
lightnum = (lightnum < 0) ? 0 : ((lightnum >= LIGHTLEVELS) ? LIGHTLEVELS - 1 : lightnum);
// if (lightnum < 0)
// walllights = scalelight[0];
// else if (lightnum >= LIGHTLEVELS)
// walllights = scalelight[LIGHTLEVELS - 1];
// else
// walllights = scalelight[lightnum];
}
}

View File

@@ -22,6 +22,9 @@
#include "ipu_texturetiles.h"
#include "r_defs.h"
extern int lightnum;
extern unsigned walllightindex;
__SUPER__ void R_RenderMaskedSegRange(drawseg_t *ds, int x1, int x2);
#endif

View File

@@ -170,10 +170,13 @@ void IpuDoom::buildIpuGraph() {
poplar::Tensor textureOffsets = m_ipuGraph.addVariable(poplar::INT, {IPUMAXNUMTEXTURES}, "textureOffsets");
poplar::Tensor textureRanges = m_ipuGraph.addVariable(poplar::INT, {IPUTEXTURETILESPERRENDERTILE + 1}, "textureRanges");
poplar::Tensor colourMap = m_ipuGraph.addVariable(poplar::UNSIGNED_CHAR, {COLOURMAPSIZE}, "colourMap");
auto textureOffsetStream = m_ipuGraph.addHostToDeviceFIFO("textureOffsets-stream", poplar::INT, IPUMAXNUMTEXTURES);
auto textureRangeStream = m_ipuGraph.addHostToDeviceFIFO("textureRanges-stream", poplar::INT, IPUTEXTURETILESPERRENDERTILE + 1);
auto colourMapStream = m_ipuGraph.addHostToDeviceFIFO("colourMap-stream", poplar::UNSIGNED_CHAR, COLOURMAPSIZE);
m_ipuGraph.setTileMapping(textureOffsets, IPUFIRSTTEXTURETILE);
m_ipuGraph.setTileMapping(textureRanges, IPUFIRSTRENDERTILE);
m_ipuGraph.setTileMapping(colourMap, IPUFIRSTTEXTURETILE);
poplar::ComputeSet R_Init_CS = m_ipuGraph.addComputeSet("R_Init_CS");
for (int renderTile = 0; renderTile < IPUNUMRENDERTILES; ++renderTile) {
@@ -192,6 +195,7 @@ void IpuDoom::buildIpuGraph() {
int logicalTile = IPUFIRSTTEXTURETILE + textureTile;
vtx = m_ipuGraph.addVertex(R_InitTextureAndSans_CS, "R_InitTexture_Vertex", {
{"progBuf", progBuf[logicalTile]},
{"colourMap", colourMap},
});
m_ipuGraph.setTileMapping(vtx, logicalTile);
m_ipuGraph.setPerfEstimate(vtx, 2000);
@@ -215,6 +219,7 @@ void IpuDoom::buildIpuGraph() {
poplar::program::Copy(textureBufStream, textureBuf.slice(0, IPUTEXTURETILESPERRENDERTILE)),
poplar::program::Copy(textureOffsetStream, textureOffsets),
poplar::program::Copy(textureRangeStream, textureRanges),
poplar::program::Copy(colourMapStream, colourMap),
poplar::program::Execute(R_InitTextureAndSans_CS),
poplar::program::Repeat(2, poplar::program::Sequence({ // <- number of R_Init_CS steps
poplar::program::Execute(R_Init_CS),
@@ -400,13 +405,17 @@ void IpuDoom::buildIpuGraph() {
// I_VideoBuffer is initialised quite late
m_ipuEngine->connectStreamToCallback("lumpBuf-stream", [this](void* p) {
IPU_LoadLumpForTransfer(m_lumpNum_h, (byte*) p);
IPU_LoadLumpNum(m_lumpNum_h, (byte*) p, IPUMAXLUMPBYTES);
});
m_ipuEngine->connectStreamToCallback("colourMap-stream", [this](void* p) {
int size = IPU_LoadLumpName("COLORMAP", (byte*) p, COLOURMAPSIZE);
assert(size == 8704); // The size of the colour mapping we expect in Doom 1
});
m_ipuEngine->connectHostFunction(
"requestLumpFromHost", 0, [](poplar::ArrayRef<const void *> inputs, poplar::ArrayRef<void *> outputs) {
const int* _lumpNum = static_cast<const int *>(inputs[0]);
unsigned char* _lumpBuf = static_cast<unsigned char *>(outputs[0]);
IPU_LoadLumpForTransfer(*_lumpNum, _lumpBuf);
IPU_LoadLumpNum(*_lumpNum, _lumpBuf, IPUMAXLUMPBYTES);
});
m_ipuEngine->connectStreamToCallback("marknumSpriteBuf-stream", [this](void* p) {
IPU_Setup_PackMarkNums(p);

View File

@@ -136,9 +136,9 @@ void IPU_Setup_PackMarkNums(void* buf) {
}
}
void IPU_LoadLumpForTransfer(int lumpnum, byte* buf) {
int size = W_LumpLength(lumpnum);
int required = size + sizeof(int); // Space for size field
int IPU_LoadLumpNum(int lumpnum, byte* buf, int maxSize) {
const int size = W_LumpLength(lumpnum);
const int required = size + sizeof(int); // Space for size field
if (required > IPUMAXLUMPBYTES) {
I_Error("\nERROR: Need %d bytes to transfer lump %d to IPU, only have %d\n",
required, lumpnum, IPUMAXLUMPBYTES);
@@ -147,5 +147,11 @@ void IPU_LoadLumpForTransfer(int lumpnum, byte* buf) {
byte* data = W_CacheLumpNum(lumpnum, PU_STATIC);
memcpy(buf + sizeof(int), data, size);
W_ReleaseLumpNum(lumpnum);
return size;
}
int IPU_LoadLumpName(const char* name, byte* buf, int maxSize) {
return IPU_LoadLumpNum(W_GetNumForName(name), buf, maxSize);
}

View File

@@ -20,7 +20,8 @@ void IPU_G_Responder_PackMiscValues(void* src_buf, void* dst_buf);
void IPU_R_RenderPlayerView_PackMiscValues(void* buf);
void IPU_R_ExecuteSetViewSize_PackMiscValues(void* buf);
void IPU_R_Init_PackMiscValues(void* buf);
void IPU_LoadLumpForTransfer(int lumpnum, byte* buf);
int IPU_LoadLumpNum(int lumpnum, byte* buf, int maxSize);
int IPU_LoadLumpName(const char* lumpname, byte* buf, int maxSize);
void IPU_Setup_PackMarkNums(void* buf);
void IPU_NotifyLineMapped(line_t *line);
void IPU_CheckAlreadyMappedLines(void);

View File

@@ -261,7 +261,7 @@ int W_NumLumps (void)
// Returns -1 if name not found.
//
lumpindex_t W_CheckNumForName(char* name)
lumpindex_t W_CheckNumForName(const char* name)
{
lumpindex_t i;
@@ -310,7 +310,7 @@ lumpindex_t W_CheckNumForName(char* name)
// W_GetNumForName
// Calls W_CheckNumForName, but bombs out if not found.
//
lumpindex_t W_GetNumForName(char* name)
lumpindex_t W_GetNumForName(const char* name)
{
lumpindex_t i;

View File

@@ -55,8 +55,8 @@ extern unsigned int numlumps;
wad_file_t *W_AddFile(char *filename);
void W_Reload(void);
lumpindex_t W_CheckNumForName(char *name);
lumpindex_t W_GetNumForName(char *name);
lumpindex_t W_CheckNumForName(const char *name);
lumpindex_t W_GetNumForName(const char *name);
int W_LumpLength(lumpindex_t lump);
void W_ReadLump(lumpindex_t lump, void *dest);