//-------------------------------------------------------------------------- // MoveObjToInert() //-------------------------------------------------------------------------- void MoveObjToInert(objtype *obj) { if (inert == &inertobjlist[MAXINERTOBJ]) return; // Transfer info needed by inert objtype // inert->x = obj->x; inert->y = obj->y; inert->size = obj->size; inert->viewx = obj->viewx; inert->tilex = obj->tilex; inert->tiley = obj->tiley; inert->state = obj->state; inert->ticcount = obj->ticcount; // Setup links between inert objects // if (inert != inertobjlist) (inert-1)->next = inert; inert->next = NULL; inert++; // Free 'real' object from list. // RemoveObj(obj); }
void SetDockPanel(DOCKPANEL *dpp, DOCKWND *dwp) { DOCKPANEL *dppOld = dwp->pDockPanel; // remove the DOCKWND from it's current DOCKPANEL RemoveObj(dwp); // insert it into the new one! InsertBefore(dwp, dpp->WndListTail); dwp->pDockPanel = dpp; SetParent(dwp->hwndContents, dpp->hwndPanel); }
void GetNewActor (void) { if (objcount >= MAXACTORS-1) { objtype *obj=player->next; while (obj) { if ((obj->flags & (FL_DEADGUY|FL_VISABLE)) == FL_DEADGUY) { RemoveObj(obj); obj = NULL; } else obj = obj->next; } } if (!objfreelist) if (usedummy) { new_actor = &dummyobj; memset (new_actor,0,sizeof(*new_actor)); } else PLAY_ERROR(GETNEWACTOR_NO_FREE_SPOTS); else { new_actor = objfreelist; objfreelist = new_actor->prev; memset (new_actor,0,sizeof(*new_actor)); if (lastobj) lastobj->next = new_actor; new_actor->prev = lastobj; // new_actor->next is allready NULL from memset // new_actor->active = false; lastobj = new_actor; objcount++; } }
void DoActor (objtype * ob) { void (*think) (objtype *); if (!ob->active && !areabyplayer[ob->areanumber]) return; if (!(ob->flags & (FL_NONMARK | FL_NEVERMARK))) actorat[ob->tilex][ob->tiley] = NULL; // // non transitional object // if (!ob->ticcount) { think = (void (*)(objtype *)) ob->state->think; if (think) { think (ob); if (!ob->state) { RemoveObj (ob); return; } } if (ob->flags & FL_NEVERMARK) return; if ((ob->flags & FL_NONMARK) && actorat[ob->tilex][ob->tiley]) return; actorat[ob->tilex][ob->tiley] = ob; return; } // // transitional object // ob->ticcount -= (short) tics; while (ob->ticcount <= 0) { think = (void (*)(objtype *)) ob->state->action; // end of state action if (think) { think (ob); if (!ob->state) { RemoveObj (ob); return; } } ob->state = ob->state->next; if (!ob->state) { RemoveObj (ob); return; } if (!ob->state->tictime) { ob->ticcount = 0; goto think; } ob->ticcount += ob->state->tictime; } think: // // think // think = (void (*)(objtype *)) ob->state->think; if (think) { think (ob); if (!ob->state) { RemoveObj (ob); return; } } if (ob->flags & FL_NEVERMARK) return; if ((ob->flags & FL_NONMARK) && actorat[ob->tilex][ob->tiley]) return; actorat[ob->tilex][ob->tiley] = ob; }
void PlayLoop (void) { id0_char_t shot_color[3] = {4,9,14}; id0_int_t allgems[5]={GEM_DELAY_TIME, // used for Q & D comparison GEM_DELAY_TIME, // for having all gems... GEM_DELAY_TIME, // the "allgems" declaration MUST GEM_DELAY_TIME, // match the "gems" declaration in GEM_DELAY_TIME // the gametype structure! }; // id0_int_t originx=0; // id0_int_t i=100; id0_signed_long_t dx,dy/*,radius*/,psin,pcos,newx,newy; //id0_int_t give; id0_short_t objnum; id0_signed_long_t ox,oy,xl,xh,yl,yh,px,py,norm_dx,norm_dy; id0_short_t o_radius; void (*think)(struct objstruct *); // REFKEEN: C++ patch ingame = true; SD_SetTimeCount(0); playstate = (exittype)0; //playstate = TimeCount = 0; gamestate.shotpower = handheight = 0; pointcount = pointsleft = 0; status_flag = S_NONE; #if 0 // setup sky/ground colors and effects (based on level) // switch (gamestate.mapon) { case 255: if (!(BGFLAGS & BGF_NIGHT)) { InitBgChange(3*60,sky_daytonight,-1,NULL,BGF_NIGHT); groundcolor = &gnd_colors[0]; } else { skycolor = &sky_colors[0]; groundcolor = &gnd_colors[0]; } break; default: skycolor = &sky_colors[gamestate.mapon]; groundcolor = &gnd_colors[gamestate.mapon]; skytimer = groundtimer = -1; break; } #endif BGFLAGS |= BGF_NOT_LIGHTNING; skytimer = groundtimer = -1; debug_gnd = *groundcolor; debug_sky = *skycolor; RedrawStatusWindow(); ThreeDRefresh(); if (screenfaded) VW_FadeIn(); #ifndef PROFILE fizzlein = true; // fizzle fade in the first refresh #endif /*TimeCount = */lasttimecount = lastnuke = 0; SD_SetTimeCount(0); PollControls (); // center mouse // StartMusic (); do { #ifndef PROFILE PollControls(); #else control.xaxis = 1; //if (++TimeCount == 300) // return; SD_AddToTimeCount(1); if (SD_GetTimeCount() == 300) return; #endif DisplayStatus(&status_flag); objnum=0; for (obj = player;obj;obj = obj->next) { if ((obj->active >= yes) && (!(FreezeTime && (obj!=player)))) { if (obj->ticcount) { obj->ticcount-=realtics; while ( obj->ticcount <= 0) { think = obj->state->thinkptr; if (think) { statetype *oldstate=obj->state; think (obj); if (!obj->state) { RemoveObj (obj); goto nextactor; } if (obj->state != oldstate) break; } obj->state = obj->state->next; if (!obj->state) { RemoveObj (obj); goto nextactor; } if (!obj->state->tictime) { obj->ticcount = 0; goto nextactor; } if (obj->state->tictime>0) obj->ticcount += obj->state->tictime; } } think = obj->state->thinkptr; if (think) { think (obj); if (!obj->state) RemoveObj (obj); } nextactor:; } // keep a list of objects around the player for radar updates // if (obj == player) { px = player->x; py = player->y; psin = sintable[player->angle]; pcos = costable[player->angle]; xl = px-((id0_long_t)RADAR_WIDTH<<TILESHIFT)/2; xh = px+((id0_long_t)RADAR_WIDTH<<TILESHIFT)/2-1; yl = py-((id0_long_t)RADAR_HEIGHT<<TILESHIFT)/2; yh = py+((id0_long_t)RADAR_HEIGHT<<TILESHIFT)/2; } if (objnum > MAX_RADAR_BLIPS-2) objnum = MAX_RADAR_BLIPS-2; ox = obj->x; oy = obj->y; if ((ox >= xl) && (ox <= xh) && (oy >= yl) && (oy <= yh)) { norm_dx = (dx = px-ox)>>TILESHIFT; norm_dy = (dy = oy-py)>>TILESHIFT; id0_int_t IntSqrt(id0_long_t va); o_radius = IntSqrt((norm_dx * norm_dx) + (norm_dy * norm_dy)); if (o_radius < RADAR_RADIUS) { newx = FixedByFrac(dy,pcos)-FixedByFrac(dx,psin); newy = FixedByFrac(dy,psin)+FixedByFrac(dx,pcos); RadarXY[objnum][0]=newx>>TILESHIFT; RadarXY[objnum][1]=newy>>TILESHIFT; // Define color to use for this object... // switch (obj->obclass) { // NO GEM NEEDED // // THE WIZARD! (YOU) // case playerobj: RadarXY[objnum++][2]=15; break; // WIZARD'S SHOTS // case pshotobj: case bigpshotobj: RadarXY[objnum++][2]=shot_color[screenpage]; break; // BATS (DK GRAY) // case batobj: if (obj->active == always) RadarXY[objnum++][2]=8; break; // RABBITS (LT GRAY) // case bunnyobj: if (obj->active == always) RadarXY[objnum++][2]=7; break; // RED GEM // // EYE, RED DEMON (DK RED) // case eyeobj: case reddemonobj: if (gamestate.gems[B_RGEM-B_RGEM]) if (obj->active == always) RadarXY[objnum++][2]=4; break; // RED MAGE (LT RED) // case mageobj: if (gamestate.gems[B_RGEM-B_RGEM]) if (obj->active == always) RadarXY[objnum++][2]=12; break; // BLUE GEM // // SUCCUBUS (LT BLUE) // case succubusobj: if (gamestate.gems[B_BGEM-B_RGEM]) if (obj->active == always) RadarXY[objnum++][2]=9; break; // WATER DRAGON (DK BLUE) // case wetobj: if (gamestate.gems[B_GGEM-B_RGEM]) if (obj->active == always) RadarXY[objnum++][2]=1; break; // GREEN GEM // // GREEN TROLL (LT GREEN) // case fatdemonobj: if (gamestate.gems[B_GGEM-B_RGEM]) if (obj->active == always) RadarXY[objnum++][2]=10; break; // GODESS (DK GREEN) // case godessobj: if (gamestate.gems[B_GGEM-B_RGEM]) if (obj->active == always) RadarXY[objnum++][2]=2; break; // YELLOW GEM // // ANT (BROWN) // case antobj: case treeobj: if (gamestate.gems[B_YGEM-B_RGEM]) if (obj->active == always) RadarXY[objnum++][2]=6; break; // SKELETON (YELLOW) // case skeletonobj: if (gamestate.gems[B_YGEM-B_RGEM]) if (obj->active == always) RadarXY[objnum++][2]=14; break; // PURPLE GEM // // ZOMBIE // case zombieobj: if (gamestate.gems[B_PGEM-B_RGEM]) if (obj->active == always) RadarXY[objnum++][2]=13; break; // ALL GEMS NEEDED // // NEMESIS // case grelmobj: if (!memcmp(gamestate.gems,allgems,sizeof(gamestate.gems))) if (obj->active == always) RadarXY[objnum++][2]=15; break; } } } }
// // Called when the dockpanel has stopped being dragged around // need to decide whether to dock/undock/leave it as it is // LRESULT DockPanel_ExitSizeMove(DOCKPANEL *dpp) { extern HWND hwndTransPanel; DestroyWindow(hwndTransPanel); hwndTransPanel = 0; DockPanel_RemoveKeyboardHook(dpp); dpp->fUndockNextMsg = FALSE; if(dpp->fDragging) { DOCKSERVER *dsp = dpp->pDockServer; DOCKPANEL *dppUnder; RECT rectDrag; POINT pt; UINT area; HWND hwnd; DestroyWindow(hwndTransPanel); hwndTransPanel = 0; dpp->fDragging = FALSE; GetCursorPos(&pt); area = GetDockTarget(dpp->pDockServer, dpp, pt, &rectDrag, &dppUnder); // did we want to dock onto anything? if(area != 0)//dpp->fDragStatus || g_dppTargetDockPanel) { ShowWindow(dpp->hwndPanel, SW_HIDE); RemoveWindowTrans(dpp->hwndPanel); // docking onto an existing DOCKPANEL (i.e. not the main window, // but becoming a tab in another panel) if(area == TAB) { // move all DOCKWNDs in the current panel to the DOCKPANEL // that we are dragging on to DOCKWND *dwp, *next = 0; for(dwp = dpp->WndListHead->flink; dwp != dpp->WndListTail; dwp = next)//dwp->flink) { next = dwp->flink; SetDockPanel(dppUnder, dwp); DockWnd_Show(dpp->hwndMain, dwp->uWndId, TRUE); } UpdateDockTabView(dppUnder); // oof! RemoveObj(dpp); hwnd = dpp->hwndPanel; dpp->hwndPanel = 0; DestroyWindow(hwnd);//dpp->hwndPanel); } // otherwise dock with the main window else { // if docking on the inside, // move to end of dock-panel list if(dppUnder == (DOCKPANEL *)1) // NASTY HACK!! WHY!??? { RemoveObj(dpp); InsertBefore(dpp, dsp->PanelListTail); } // if docking else if(dppUnder) { if( area == TOP && (dppUnder->dwStyle & BOTTOM) || area == BOTTOM && (dppUnder->dwStyle & TOP) || area == LEFT && (dppUnder->dwStyle & RIGHT) || area == RIGHT && (dppUnder->dwStyle & LEFT)) { // inside of target panel RemoveObj(dpp); InsertBefore(dpp, dppUnder->flink); if(area == TOP) area = BOTTOM; else if(area == BOTTOM) area = TOP; else if(area == LEFT) area = RIGHT; else if(area == RIGHT) area = LEFT; } else if( area == TOP && (dppUnder->dwStyle & TOP) || area == BOTTOM && (dppUnder->dwStyle & BOTTOM) || area == LEFT && (dppUnder->dwStyle & LEFT) || area == RIGHT && (dppUnder->dwStyle & RIGHT)) { // outside of target panel RemoveObj(dpp); InsertBefore(dpp, dppUnder); } } // if docking against the outside edge else { RemoveObj(dpp); InsertBefore(dpp, dsp->PanelListHead->flink); } dpp->dwStyle = (dpp->dwStyle & ~DWS_DOCKED_MASK) | area; DockWindow(dpp); } ShowWindow(dpp->hwndPanel, SW_SHOW); } dpp->fDragging = FALSE; dpp->fDragStatus = 0; } // if the dock-panel is still floating, determine if it's edges // intersect the main window, and turn on the 'sticky' flag if(dpp->fDocked == FALSE) { RECT r1, r2, r3; GetWindowRect(dpp->hwndMain, &r2); GetWindowRect(dpp->hwndPanel, &r3); dpp->fSticky = IntersectRect(&r1, &r2, &r3); } return 0; }
void PlayLoop (void) { id0_int_t give; void (*think)(struct objstruct *); // REFKEEN: C++ patch ingame = true; SD_SetTimeCount(0); playstate = (exittype)0; //playstate = TimeCount = 0; gamestate.shotpower = handheight = 0; pointcount = pointsleft = 0; DrawLevelNumber (gamestate.mapon); DrawBars (); #ifndef PROFILE fizzlein = true; // fizzle fade in the first refresh #endif /*TimeCount = */lasttimecount = lastnuke = 0; PollControls (); // center mouse StartMusic (); do { #ifndef PROFILE PollControls(); #else c.xaxis = 1; // if (++TimeCount == 300) // return; SD_SetTimeCount(SD_GetTimeCount()+1); if (SD_GetTimeCount() == 300) return; #endif for (obj = player;obj;obj = obj->next) if (obj->active) { if (obj->ticcount) { obj->ticcount-=tics; while ( obj->ticcount <= 0) { think = obj->state->thinkptr; if (think) { think (obj); if (!obj->state) { RemoveObj (obj); goto nextactor; } } obj->state = obj->state->next; if (!obj->state) { RemoveObj (obj); goto nextactor; } if (!obj->state->tictime) { obj->ticcount = 0; goto nextactor; } if (obj->state->tictime>0) obj->ticcount += obj->state->tictime; } } think = obj->state->thinkptr; if (think) { think (obj); if (!obj->state) RemoveObj (obj); } nextactor:; } if (bordertime) { bordertime -= tics; if (bordertime<=0) { bordertime = 0; VW_ColorBorder (3); } } if (pointcount) { pointcount -= tics; if (pointcount <= 0) { pointcount += POINTTICS; give = (pointsleft > 1000)? 1000 : ( (pointsleft > 100)? 100 : ((pointsleft < 20)? pointsleft : 20) ); SD_PlaySound (GETPOINTSSND); AddPoints (give); pointsleft -= give; if (!pointsleft) pointcount = 0; } } ThreeDRefresh (); CheckKeys(); // (REFKEEN) SPECIAL - Without this the game // can run very fast, even if it's not noticeable // (a lot of PlayLoop iterations and consumed CPU power) // // Notes: // 1. Should NOT be called from ThreeDRefresh/CalcTics, // because we don't always want that to be done // (e.g., FizzleFade effect right after loading C4 saved game). // 2. SHOULD be called AFTER CheckKeys. That function resets // lasttimecount (just like CalcTics) if the debug key modifier // (F10 in Cat. 3-D/Abyss, Backspace in Armageddon/Apocalypse) // is held. As a consequence, if the wait is done before the // call to CheckKeys then the game may seem to get stuck while // the debug key modifier is held. BE_ST_TimeCountWaitFromSrc(SD_GetTimeCount(), 1); // if (singlestep) { VW_WaitVBL(14); lasttimecount = SD_GetTimeCount(); } if (extravbls) VW_WaitVBL(extravbls); }while (!playstate); StopMusic (); ingame = false; if (bordertime) { bordertime = 0; VW_ColorBorder (3); } if (!abortgame) AddPoints (pointsleft); else abortgame = false; }
void DoActor (objtype *ob) { void (*think)(objtype *); objtype *actor; if (ob->flags & FL_FREEZE) return; if (ob->flags & FL_BARRIER) { actor = actorat[ob->tilex][ob->tiley]; if (BARRIER_STATE(ob) == bt_ON) { if (actor) { Sint16 damage = 0; actor->flags |= FL_BARRIER_DAMAGE; if ((US_RndT() < 0x7f) && (actor->flags & FL_SHOOTABLE)) { switch (ob->obclass) { case arc_barrierobj: // arc barrier - Mild Damage damage = 500; // 100 break; case post_barrierobj: // post barrier - Butt kicker damage = 500; break; default: break; } DamageActor(actor,damage,ob); } } } else if (actor) actor->flags &= ~FL_BARRIER_DAMAGE; } if (!ob->active && !areabyplayer[ob->areanumber]) return; if (!(ob->flags&(FL_NONMARK|FL_NEVERMARK)) ) actorat[ob->tilex][ob->tiley] = NULL; // // non transitional object // if (!ob->ticcount) { think = ob->state->think; if (think) { think (ob); if (!ob->state) { RemoveObj (ob); return; } } if (!(ob->flags&FL_NEVERMARK) ) { if (ob->flags&FL_NONMARK) { if (actorat[ob->tilex][ob->tiley]) { return; } } actorat[ob->tilex][ob->tiley] = ob; } return; } // // transitional object // ob->ticcount-=tics; while ( ob->ticcount <= 0) { think = ob->state->action; // end of state action if (think) { think (ob); if (!ob->state) { RemoveObj (ob); return; } } ob->state = ob->state->next; if (!ob->state) { RemoveObj (ob); return; } if (!ob->state->tictime) { ob->ticcount = 0; goto think; } ob->ticcount += ob->state->tictime; } think: // // think // think = ob->state->think; if (think) { think (ob); if (!ob->state) { RemoveObj (ob); return; } } if ( !(ob->flags&FL_NEVERMARK) ) { if (ob->flags&FL_NONMARK) { if (actorat[ob->tilex][ob->tiley]) { return; } } actorat[ob->tilex][ob->tiley] = ob; } return; }