mirror of
https://github.com/jndean/IPUDOOM.git
synced 2026-08-18 16:28:53 +00:00
Extend lighting model to floors and ceilings
This commit is contained in:
@@ -16,42 +16,44 @@ wget https://distro.ibiblio.org/slitaz/sources/packages/d/doom1.wad
|
||||
```
|
||||
|
||||
|
||||
Vanilla Doom runs on the CPU, have started offloading subsystems to IPU Tile 0.
|
||||
Activity Log:
|
||||
### Progress Log:
|
||||
Started with vanilla Doom running on the CPU, began started offloading subsystems to the IPU (just Tile 0 at first):
|
||||
|
||||
- [x] Create IPU hooks for key methods like G_Ticker, G_Responder so IPU can step game time and respond to keypresses in real time. (Also setviewsize etc)
|
||||
- [x] Create IPU hooks for key methods like G_Ticker and G_Responder so IPU can step game time and respond to keypresses in real time. IPU uses callbacks on the host to load and unpack all level geometry from disk whenever the player starts a new level.
|
||||
|
||||
- [x] Implement IPU memory allocator for level state, i.e., anything with lifetime PU_LEVEL
|
||||
|
||||
- [x] IPU interacts with host to load and unpack all level geometry from disk whenever a level is loaded
|
||||
- [x] Implement an IPU-specific memory allocator with seperate memory pools for different lifetimes: static lifetime, level lifetime, frame lifetime. Makes fragmanetation easy to avoid => reduces SRAM footprint.
|
||||
|
||||
- [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.
|
||||
|
||||

|
||||
|
||||
- [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.
|
||||
- [x] Implement BinarySpacePartion search (stackless recursion version for IPU), solidseg occlusion and floor/ceiling clipping to get (untextured) rendering of vertical walls running on a sinlge IPU tile.
|
||||
|
||||

|
||||
|
||||
- [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. So now IPU can texture walls.
|
||||
- [x] Split rendering across 32 render tiles. Reformat textures into a big buffer that can be striped over other dedicated texture tiles, and accessed by the render tiles using JIT-patched exchange programs to enable fetches based on dynamic indices. So now the IPU can texture walls in real time.
|
||||
|
||||
 
|
||||
|
||||
- [x] Implement lighting model (add shadows to walls): texture tiles translate the colours during texture column fetch requests to save memory on the render tiles.
|
||||
- [x] Implement lighting model (add shadows to walls): the texture tiles translate the colours during texture column fetch requests to save SRAM on the render tiles.
|
||||
|
||||

|
||||
|
||||
- [x] Port the visplane system to the render tiles, so IPU can render floors and ceilings, (untextured for now, instead coloured to show the visplane subdivision). Also implement skybox.
|
||||
- [x] Port the visplane system to the render tiles, so IPU can render floors and ceilings, (untextured for now - instead coloured to show the visplane subdivision). Also implement skybox.
|
||||
|
||||

|
||||
|
||||
- [x] Extend the JIT-patching texture exchange to support span textures and zlighting, so IPU can texture and shade floors + ceilings.
|
||||
|
||||
[GIF TODO]
|
||||
|
||||
Immediate next steps:
|
||||
- [ ] Port 'flats' and zlight so IPU can texture and light floors + ceilings.
|
||||
- [ ] Implement system to notify IPU of map state changes, so that doors open and close properly.
|
||||
- [ ] Implement temporary(?) system to notify IPU of map state changes, so that doors open and close properly. Perhaps the same could work for enemys and projectiles.
|
||||
- [ ] Implement vissprite system and masked col rendering to add objects / enemies to levels.
|
||||
|
||||
Longer term next steps:
|
||||
|
||||
- [ ] Render other things in the level (sprites and masked components, HUD (using dedicated HUD tiles))
|
||||
- [ ] Render HUD (probably using dedicated HUD tiles)
|
||||
- [ ] Move beyond just the rendering?
|
||||
|
||||
...
|
||||
|
||||
@@ -30,6 +30,7 @@ const int* tileLocalTextureOffsets;
|
||||
|
||||
static pixel_t colourMap_TT[COLOURMAPSIZE];
|
||||
static pixel_t* scalelight_TT[LIGHTLEVELS][MAXLIGHTSCALE];
|
||||
static pixel_t* zlight_TT[LIGHTLEVELS][MAXLIGHTZ];
|
||||
|
||||
extern "C"
|
||||
__SUPER__
|
||||
@@ -80,6 +81,7 @@ void IPU_R_InitTextureTile(unsigned* progBuf, int progBufSize, const pixel_t* co
|
||||
|
||||
// Next, precompute light scales from the colourmap. This normally happens in R_ExecuteSetViewSize
|
||||
memcpy(colourMap_TT, colourMapBuf, sizeof(colourMap_TT));
|
||||
// Firstly do scalelight_TT, which is used for cols
|
||||
for (int i = 0; i < LIGHTLEVELS; i++) {
|
||||
int startmap = ((LIGHTLEVELS - 1 - i) * 2) * NUMCOLORMAPS / LIGHTLEVELS;
|
||||
for (int j = 0; j < MAXLIGHTSCALE; j++) {
|
||||
@@ -94,6 +96,23 @@ void IPU_R_InitTextureTile(unsigned* progBuf, int progBufSize, const pixel_t* co
|
||||
scalelight_TT[i][j] = colourMap_TT + level * 256;
|
||||
}
|
||||
}
|
||||
// Next do zlight_TT, which is used for spans
|
||||
for (int i = 0; i < LIGHTLEVELS; i++) {
|
||||
int startmap = ((LIGHTLEVELS - 1 - i) * 2) * NUMCOLORMAPS / LIGHTLEVELS;
|
||||
for (int j = 0; j < MAXLIGHTZ; j++) {
|
||||
int scale = FixedDiv((SCREENWIDTH / 2 * FRACUNIT), (j + 1) << LIGHTZSHIFT);
|
||||
scale >>= LIGHTSCALESHIFT;
|
||||
int level = startmap - scale / DISTMAP;
|
||||
|
||||
if (level < 0)
|
||||
level = 0;
|
||||
|
||||
if (level >= NUMCOLORMAPS)
|
||||
level = NUMCOLORMAPS - 1;
|
||||
|
||||
zlight_TT[i][j] = colourMap_TT + level * 256;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C"
|
||||
@@ -135,19 +154,24 @@ void IPU_R_FulfilColumnRequest(unsigned* progBuf, unsigned char* textureBuf, uns
|
||||
unsigned position = req->position;
|
||||
unsigned step = req->step;
|
||||
unsigned count = req->count;
|
||||
unsigned lightNum = req->lightNum;
|
||||
unsigned lightScale = req->lightScale;
|
||||
ds_colormap = zlight_TT[lightNum][lightScale];
|
||||
// Do the render loop for this line of pixels
|
||||
do {
|
||||
// Does 6 levels of indentation count as code smell?
|
||||
unsigned ytemp = (position >> 4) & 0x0fc0;
|
||||
unsigned xtemp = (position >> 26);
|
||||
int spot = xtemp | ytemp;
|
||||
*dest++ = texture[spot]; // LATER: ds_colormap[texture[spot]];
|
||||
*dest++ = ds_colormap[texture[spot]];
|
||||
position += step;
|
||||
} while (count--);
|
||||
}
|
||||
|
||||
} else {
|
||||
// Is a Column request
|
||||
unsigned lightNum = incomingRequest->colRequest.lightNum;
|
||||
unsigned columnOffset = incomingRequest->colRequest.columnOffset;
|
||||
unsigned lightNum = incomingRequest->colRequest.lightNum;
|
||||
unsigned lightScale = incomingRequest->colRequest.lightScale;
|
||||
byte* src = &texture[columnOffset];
|
||||
pixel_t* dc_colourmap = scalelight_TT[lightNum][lightScale];
|
||||
|
||||
@@ -22,7 +22,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
unsigned position, step;
|
||||
unsigned char count, lightNum;
|
||||
unsigned char count, lightNum, lightScale;
|
||||
} IPUSpanRequest_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
+7
-1
@@ -615,29 +615,35 @@ void IPURequest_R_DrawSpan(void) {
|
||||
return;
|
||||
}
|
||||
|
||||
// All requests in batch should share a texture
|
||||
// If not, dispatch old batch first
|
||||
if (requestBatch.numSpanRequests > 0 && requestBatch.texture != flatnum) {
|
||||
IPURequest_R_DrawSpan_FulfillBatch();
|
||||
}
|
||||
requestBatch.texture = flatnum;
|
||||
|
||||
// The response is fixed size, so send the existing batch if there's
|
||||
// no space to fulfil the next request
|
||||
// no space to fulfil this next request in the same response.
|
||||
int count = ds_x2 - ds_x1;
|
||||
if (spanBatchTotalCount + count > IPUTEXTURECACHELINESIZE * sizeof(int)) {
|
||||
IPURequest_R_DrawSpan_FulfillBatch();
|
||||
}
|
||||
|
||||
// Serialise request
|
||||
IPUSpanRequest_t* spanRequest = &requestBatch.spanRequests[requestBatch.numSpanRequests];
|
||||
spanRequest->position = ((ds_xfrac << 10) & 0xffff0000) | ((ds_yfrac >> 6) & 0x0000ffff);
|
||||
spanRequest->step = ((ds_xstep << 10) & 0xffff0000) | ((ds_ystep >> 6) & 0x0000ffff);
|
||||
spanRequest->count = count;
|
||||
spanRequest->lightNum = lightnum;
|
||||
spanRequest->lightScale = walllightindex;
|
||||
|
||||
// Record where the response should be written to when it is fulfilled
|
||||
spanDests[requestBatch.numSpanRequests] = ylookup[ds_y] + columnofs[ds_x1];
|
||||
|
||||
spanBatchTotalCount += count;
|
||||
requestBatch.numSpanRequests += 1;
|
||||
|
||||
// Send full batches
|
||||
if (requestBatch.numSpanRequests >= IPUMAXSPANREQUESTBATCHSIZE) {
|
||||
IPURequest_R_DrawSpan_FulfillBatch();
|
||||
}
|
||||
|
||||
+5
-2
@@ -102,9 +102,10 @@ int viewangletox[FINEANGLES / 2];
|
||||
// from clipangle to -clipangle.
|
||||
angle_t xtoviewangle[SCREENWIDTH + 1];
|
||||
|
||||
// lighttable_t *scalelight[LIGHTLEVELS][MAXLIGHTSCALE];// JOSEF: This lives on texture tile instead
|
||||
// JOSEF: These live on the texture tiles now
|
||||
// lighttable_t *scalelight[LIGHTLEVELS][MAXLIGHTSCALE];
|
||||
// lighttable_t *scalelightfixed[MAXLIGHTSCALE];
|
||||
lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ]; // JOSEF: TODO (on texture/flats tile?)
|
||||
// lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ];
|
||||
|
||||
// bumped light from gun blasts
|
||||
int extralight;
|
||||
@@ -757,6 +758,8 @@ void R_SetupFrame(player_t *player) {
|
||||
|
||||
if (player->fixedcolormap) {
|
||||
printf("JOSEF: Warning: Fixed colourmap being used, need to implement that on texture tiles (send them a special value?)");
|
||||
fixedcolormap = 0; // JOSEF
|
||||
|
||||
// fixedcolormap = colormaps + player->fixedcolormap * 256; // LATER
|
||||
|
||||
// walllights = scalelightfixed; // LATER
|
||||
|
||||
+7
-8
@@ -131,7 +131,7 @@ void R_MapPlane(int y, int x1, int x2) {
|
||||
angle_t angle;
|
||||
fixed_t distance;
|
||||
fixed_t length;
|
||||
unsigned index;
|
||||
// unsigned index; // JOSEF: store in walllightindex instead
|
||||
|
||||
if (x2 < x1 || x1 < 0 || x2 >= viewwidth || y > viewheight) {
|
||||
printf("ERROR: R_MapPlane: %d, %d at %d", x1, x2, y);
|
||||
@@ -153,18 +153,16 @@ void R_MapPlane(int y, int x1, int x2) {
|
||||
ds_xfrac = viewx + FixedMul(finecosine[angle], length);
|
||||
ds_yfrac = -viewy - FixedMul(finesine[angle], length);
|
||||
|
||||
/* LATER
|
||||
if (fixedcolormap)
|
||||
ds_colormap = fixedcolormap;
|
||||
else {
|
||||
index = distance >> LIGHTZSHIFT;
|
||||
walllightindex = distance >> LIGHTZSHIFT;
|
||||
|
||||
if (index >= MAXLIGHTZ)
|
||||
index = MAXLIGHTZ - 1;
|
||||
if (walllightindex >= MAXLIGHTZ)
|
||||
walllightindex = MAXLIGHTZ - 1;
|
||||
|
||||
ds_colormap = planezlight[index];
|
||||
// ds_colormap = planezlight[index]; // JOSEF: LATER, store this in lightscale
|
||||
}
|
||||
*/
|
||||
|
||||
ds_y = y;
|
||||
ds_x1 = x1;
|
||||
@@ -393,7 +391,8 @@ void R_DrawPlanes(void) {
|
||||
if (lightnum < 0)
|
||||
lightnum = 0;
|
||||
|
||||
// // planezlight = zlight[light]; // Texture tiles are in charge of scaling by light
|
||||
// JOSEF: Texture tiles are in charge of scaling by lightnum now
|
||||
// planezlight = zlight[lightnum];
|
||||
|
||||
pl->top[pl->maxx + 1] = 0xff;
|
||||
pl->top[pl->minx - 1] = 0xff;
|
||||
|
||||
Reference in New Issue
Block a user