int Sonic_CheckRight(Object* self, int* outAngle, int* otherDist) { int dist1, dist2; FindWall(self, self->y - self->width, self->x + self->height, 0xE, 0, 16, &dist1, &v_anglebuffer) FindWall(self, self->y + self->width, self->x + self->height, 0xE, 0, 16, &dist2, &v_b_F76A) return Sonic_CheckCommon(dist1, dist2, 0xC0, outAngle, otherDist); }
// aka "Sonic_DontRunOnWalls" which is the dumbest name int Sonic_CheckUp(Object* self, int* outAngle, int* otherDist) { int dist1, dist2; FindFloor(self, (self->y - self->height) ^ 0xF, self->x + self->width, 0xE, 0x1000, -16, &dist1, &v_anglebuffer) FindWall(self, (self->y - self->height) ^ 0xF, self->x - self->width, 0xE, 0x1000, -16, &dist2, &v_b_F76A) return Sonic_CheckCommon(dist1, dist2, 0x80, outAngle, otherDist); }
int Sonic_GetRightWallDistAngle(Object* self, int x, int y, int* outAngle) { int dist; FindWall(self, y, x + 10, 0xE, 0, 16, &dist, &v_anglebuffer); if(outAngle) *outAngle = (v_anglebuffer & 1) ? -0x40 : v_anglebuffer; return dist; }
int Sonic_GetLeftWallDistAngle(Object* self, int x, int y, int* outAngle) { int dist; FindWall(self, y, (x - 10) ^ 0xF, 0xE, 0x800, -16, &dist, &v_anglebuffer); if(outAngle) *outAngle = (v_anglebuffer & 1) ? 0x40 : v_anglebuffer; return dist; }
bool CMine::CalcDeltaLights (double fLightScale, int force, int recursion_depth) { // initialize totals CDSegment *srcseg, *childseg; int source_segnum, child_segnum; double effect[4]; GameInfo ().delta_lights.count = 0; GameInfo ().dl_indices.count = 0; bool bWall, bD2XLights = (level_version >= 15) && (GameInfo ().fileinfo_version >= 34); fLightScale = 1.0; ///= 100.0; for (source_segnum = 0, srcseg = Segments (); source_segnum < SegCount (); source_segnum++, srcseg++) { // skip if not marked unless we are automatically saving if (!(srcseg->wall_bitmask & MARKED_MASK) && !force) continue; // loop on all sides int source_sidenum; for (source_sidenum = 0; source_sidenum < 6; source_sidenum++) { INT16 tmapnum = srcseg->sides [source_sidenum].nBaseTex & 0x3fff; INT16 tmapnum2 = srcseg->sides [source_sidenum].nOvlTex & 0x3fff; INT16 trignum; bool bl1 = (bool) (IsLight (tmapnum) != -1); bool bl2 = (bool) (IsLight (tmapnum2) != -1); if (!(bl1 || bl2)) continue; // no lights on this side bool bCalcDeltas = false; // if the current side is a wall and has a light and is the target of a trigger // than can make the wall appear/disappear, calculate delta lights for it if ((bWall = (FindWall (source_segnum, source_sidenum) != NULL)) && ((trignum = FindTriggerTarget (0, source_segnum, source_sidenum)) >= 0)) { INT8 trigtype = Triggers (trignum)->type; bCalcDeltas = (trigtype == TT_ILLUSION_OFF) || (trigtype == TT_ILLUSION_ON) || (trigtype == TT_CLOSE_WALL) || (trigtype == TT_OPEN_WALL) || (trigtype == TT_LIGHT_OFF) || (trigtype == TT_LIGHT_ON); } if (!bCalcDeltas) bCalcDeltas = IsFlickeringLight (source_segnum, source_sidenum); if (!bCalcDeltas) { bool bb1 = IsBlastableLight (tmapnum); bool bb2 = IsBlastableLight (tmapnum2); if (bb1 == bb2) bCalcDeltas = bb1; // both lights blastable or not else if (!(bb1 ? bl2 : bl1)) // i.e. one light blastable and the other texture not a non-blastable light bCalcDeltas = true; } if (!bCalcDeltas) { //check if light is target of a "light on/off" trigger int trignum = FindTriggerTarget (0, source_segnum, source_sidenum); if ((trignum >= 0) && (Triggers (trignum)->type >= TT_LIGHT_OFF)) bCalcDeltas = true; } if (!bCalcDeltas) continue; // only set lights for textures which have a nOvlTex //if (tmapnum2 == 0) // continue; INT16 srcwall = srcseg->sides [source_sidenum].nWall; if ((srcseg->children [source_sidenum] != -1) && ((srcwall >= GameInfo ().walls.count) || (Walls (srcwall)->type == WALL_OPEN))) continue; // if ((IsLight (tmapnum) == -1) && (IsLight (tmapnum2) == -1)) // continue; if (GameInfo ().dl_indices.count >= MAX_DL_INDICES) { char szMsg [256]; sprintf (szMsg, " Light tool: Too many dynamic lights at render depth %d", recursion_depth); DEBUGMSG (szMsg); return false; } vms_vector A,source_center; // get index number and increment total number of dl_indices int dl_index_num = (int)GameInfo ().dl_indices.count++; dl_index *pdli = DLIndex (dl_index_num); if (bD2XLights) { pdli->d2x.segnum = source_segnum; pdli->d2x.sidenum = source_sidenum; pdli->d2x.count = 0; // will be incremented below } else { pdli->d2.segnum = source_segnum; pdli->d2.sidenum = source_sidenum; pdli->d2.count = 0; // will be incremented below } pdli->d2.index = (INT16)GameInfo ().delta_lights.count; // find orthogonal angle of source segment CalcOrthoVector(A,source_segnum,source_sidenum); // remember to flip the sign since we want it to point inward A.x = -A.x; A.y = -A.y; A.z = -A.z; // calculate the center of the source segment CalcCenter(source_center,source_segnum,source_sidenum); // mark those Segments () within N children of current cube //(note: this is done once per light instead of once per segment // even though some Segments () have multiple lights. // This actually reduces the number of calls since most // Segments () do not have lights) int h; for (h = 0; h < SegCount (); h++) Segments (h)->seg_number = -1; SetSegmentChildNum (srcseg, source_segnum, recursion_depth); srcseg->seg_number = recursion_depth; // setup source corner vertex for length calculation later vms_vector source_corner[4]; int j; for (j = 0; j < 4; j++) { UINT8 vertnum = side_vert[source_sidenum][j]; int h = srcseg->verts[vertnum]; source_corner[j].x = Vertices (h)->x; source_corner[j].y = Vertices (h)->y; source_corner[j].z = Vertices (h)->z; } // loop on child Segments () for (child_segnum = 0, childseg = Segments (); child_segnum < SegCount (); child_segnum++, childseg++) { if (childseg->seg_number < 0) continue; // loop on child sides int child_sidenum; for (child_sidenum = 0; child_sidenum < 6; child_sidenum++) { // if texture has a child.. #ifdef _DEBUG CBRK (source_segnum == 6 && source_sidenum == 2 && child_segnum == 10 && child_sidenum == 1); #endif if (childseg->children[child_sidenum] >= 0) { UINT16 nWall = childseg->sides[child_sidenum].nWall; // .. if there is no wall .. if (nWall >= GameInfo ().walls.count) continue; // .. or its not a door .. if (Walls (nWall)->type == WALL_OPEN) continue; // don't put light because there is no texture here } // don't affect non-flickering light emitting textures (e.g. lava) tmapnum = childseg->sides [child_sidenum].nBaseTex; tmapnum2 = childseg->sides [child_sidenum].nOvlTex & 0x3fff; if (m_nNoLightDeltas == 1) { if (((IsLight (tmapnum) >= 0) || (IsLight (tmapnum2) >= 0)) && !IsFlickeringLight (child_segnum, child_sidenum)) continue; } else if ((m_nNoLightDeltas == 2) && (IsLava (tmapnum) || IsLava (tmapnum2))) continue; // if the child side is the same as the source side, then set light and continue if (child_sidenum == source_sidenum && child_segnum == source_segnum) { if ((GameInfo ().delta_lights.count >= MAX_DELTA_LIGHTS) || (bD2XLights ? pdli->d2x.count == 8191 : pdli->d2.count == 255)) { char szMsg [256]; sprintf (szMsg, " Light tool: Too many dynamic lights at render depth %d", recursion_depth); DEBUGMSG (szMsg); return false; } delta_light *dl = DeltaLights (GameInfo ().delta_lights.count++); dl->segnum = child_segnum; dl->sidenum = child_sidenum; dl->dummy = 0; dl->vert_light [0] = dl->vert_light [1] = dl->vert_light [2] = dl->vert_light [3] = (UINT8) min (32, 32 * fLightScale); if (bD2XLights) pdli->d2x.count++; else pdli->d2.count++; continue; } // calculate vector between center of source segment and center of child #ifdef _DEBUG CBRK (child_segnum == qqq1 && child_sidenum == qqq2); #endif if (CalcSideLights (child_segnum, child_sidenum, source_center, source_corner, A, effect, fLightScale, bWall)) { theApp.SetModified (TRUE); if ((GameInfo ().delta_lights.count >= MAX_DELTA_LIGHTS) || (bD2XLights ? pdli->d2x.count == 8191 : pdli->d2.count == 255)) { char szMsg [256]; sprintf (szMsg, " Light tool: Too many dynamic lights at render depth %d", recursion_depth); DEBUGMSG (szMsg); return false; } delta_light *dl = DeltaLights (GameInfo ().delta_lights.count++); dl->segnum = child_segnum; dl->sidenum = child_sidenum; dl->dummy = 0; int iCorner; for (iCorner = 0; iCorner < 4; iCorner++) dl->vert_light [iCorner] = (UINT8) min(32, effect [iCorner]); if (bD2XLights) pdli->d2x.count++; else pdli->d2.count++; } } } // } } } return true; }