| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275 |
- /*
- ** Command & Conquer(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /* $Header: F:\projects\c&c\vcs\code\logic.cpv 2.17 16 Oct 1995 16:50:52 JOE_BOSTIC $ */
- /***********************************************************************************************
- *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
- ***********************************************************************************************
- * *
- * Project Name : Command & Conquer *
- * *
- * File Name : LOGIC.CPP *
- * *
- * Programmer : Joe L. Bostic *
- * *
- * Start Date : September 27, 1993 *
- * *
- * Last Update : December 23, 1994 [JLB] *
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * LogicClass::AI -- Handles AI logic processing for game objects. *
- * LogicClass::Debug_Dump -- Displays logic class status to the mono screen. *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "function.h"
- #include "logic.h"
- static unsigned FramesPerSecond=0;
- #ifdef CHEAT_KEYS
- static unsigned TotalFrames;
- static unsigned FPSDivider = 1;
- static unsigned AverageFramesPerSecond;
- /***********************************************************************************************
- * LogicClass::Debug_Dump -- Displays logic class status to the mono screen. *
- * *
- * This is a debugging support routine. It displays the current state of the logic class *
- * to the monochrome monitor. It assumes that it is being called once per second. *
- * *
- * INPUT: none *
- * *
- * OUTPUT: none *
- * *
- * WARNINGS: Call this routine only once per second. *
- * *
- * HISTORY: *
- * 05/31/1994 JLB : Created. *
- *=============================================================================================*/
- void LogicClass::Debug_Dump(MonoClass *mono) const
- {
- #define RECORDCOUNT 40
- #define RECORDHEIGHT 21
- static struct {
- int Graphic;
- } _record[RECORDCOUNT];
- static int _framecounter = 0;
- TotalFrames+= FramesPerSecond;
- AverageFramesPerSecond = TotalFrames/FPSDivider++;
- mono->Set_Cursor(21, 9);
- mono->Print(
- "ÚÄÄÄÄÄÄÄÄÄÄÂÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\r"
- "³Units.....³ ³Frame Rate: Avg: Frame: ³\r"
- "³Infantry..³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´\r"
- "³Aircraft..³ ³ ³\r"
- "³Buildings.³ ³ ³\r"
- "³Terrain...³ Ã ´\r"
- "³Bullets...³ ³ ³\r"
- "³Anims.....³ ³ ³\r"
- "³Teams.....³ Ã Ä´\r"
- "³Triggers..³ ³ ³\r"
- "³Factories.³ ³ ³\r"
- "³ ³ Ã ´\r"
- "³ ³ ³ ³\r"
- "ÀÄÄÄÄÄÄÄÄÄÄÁÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄ´Spare CPU TimeÃÄÄÄÄÄÄÄÄÄÄÄÄÙ\r");
- _framecounter++;
- mono->Set_Cursor(70, 10);mono->Printf("%ld", Frame);
- if (ScenarioInit) {
- mono->Set_Cursor(21, 9);mono->Printf("%d", ScenarioInit);
- }
- mono->Set_Cursor(33, 10);mono->Printf("%3d", Units.Count());
- mono->Set_Cursor(33, 11);mono->Printf("%3d", Infantry.Count());
- mono->Set_Cursor(33, 12);mono->Printf("%3d", Aircraft.Count());
- mono->Set_Cursor(33, 13);mono->Printf("%3d", Buildings.Count());
- mono->Set_Cursor(33, 14);mono->Printf("%3d", Terrains.Count());
- mono->Set_Cursor(33, 15);mono->Printf("%3d", Bullets.Count());
- mono->Set_Cursor(33, 16);mono->Printf("%3d", Anims.Count());
- mono->Set_Cursor(33, 17);mono->Printf("%3d", Teams.Count());
- mono->Set_Cursor(33, 18);mono->Printf("%3d", Triggers.Count());
- mono->Set_Cursor(33, 19);mono->Printf("%3d", Factories.Count());
- mono->Set_Cursor(48, 10);mono->Printf("%d", FramesPerSecond);
- mono->Set_Cursor(58, 10);mono->Printf("%d", AverageFramesPerSecond);
- /*
- ** Advance to the next recorded performance record. If the record buffer
- ** is full then throw out the oldest record.
- */
- memcpy(&_record[0], &_record[1], sizeof(_record[0])*(RECORDCOUNT-1));
- /*
- ** Fill in the data for the current frame's performance record.
- */
- SpareTicks = MIN((long)SpareTicks, (long)TIMER_SECOND);
- _record[RECORDCOUNT-1].Graphic = Fixed_To_Cardinal(RECORDHEIGHT, Cardinal_To_Fixed(TIMER_SECOND, SpareTicks));
- /*
- ** Draw the bars across the performance record screen.
- */
- for (int column = 0; column < RECORDCOUNT; column++) {
- for (int row = 1; row < RECORDHEIGHT; row += 2) {
- static char _barchar[4] = {' ', 220, 0, 219};
- char str[2];
- int index = 0;
- index |= (_record[column].Graphic >= row) ? 0x01 : 0x00;
- index |= (_record[column].Graphic >= row+1) ? 0x02: 0x00;
- str[1] = '\0';
- str[0] = _barchar[index];
- mono->Text_Print(str, 37+column, 21-(row/2));
- }
- }
- SpareTicks = 0;
- FramesPerSecond = 0;
- }
- #endif
- /***********************************************************************************************
- * LogicClass::AI -- Handles AI logic processing for game objects. *
- * *
- * This routine is used to perform the AI processing for all game objects. This includes *
- * all houses, factories, objects, and teams. *
- * *
- * INPUT: none *
- * *
- * OUTPUT: none *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 05/29/1994 JLB : Created. *
- * 12/17/1994 JLB : Must perform one complete pass rather than bailing early. *
- * 12/23/1994 JLB : Esures that no object gets skipped if it was deleted. *
- *=============================================================================================*/
- void LogicClass::AI(void)
- {
- int index;
- FramesPerSecond++;
- /*
- ** Crate regeneration is handled here.
- */
- if (GameToPlay != GAME_NORMAL && CrateMaker && CrateTimer.Expired()) {
- Map.Place_Random_Crate();
- CrateTimer = TICKS_PER_MINUTE * Random_Pick(7, 15);
- }
- /*
- ** Team AI is processed.
- */
- for (index = 0; index < Teams.Count(); index++) {
- Teams.Ptr(index)->AI();
- }
- // Heap_Dump_Check( "After Team AI" );
- /*
- ** AI for all sentient objects is processed.
- */
- for (index = 0; index < Count(); index++) {
- ObjectClass * obj = (*this)[index];
- obj->AI();
- /*
- ** If the object was destroyed in the process of performing its AI, then
- ** adjust the index so that no object gets skipped.
- */
- if (obj != (*this)[index]) {
- // if (!obj->IsActive) {
- index--;
- }
- }
- // Heap_Dump_Check( "After Object AI" );
- /*
- ** A second pass through the sentient objects is required so that the appropriate scan
- ** bits will be set for the owner house.
- */
- for (index = 0; index < Units.Count(); index++) {
- UnitClass const * unit = Units.Ptr(index);
- if (unit->IsLocked && (GameToPlay != GAME_NORMAL || !unit->House->IsHuman || unit->IsDiscoveredByPlayer)) {
- unit->House->NewUScan |= (1L << unit->Class->Type);
- if (!unit->IsInLimbo) unit->House->NewActiveUScan |= (1L << unit->Class->Type);
- }
- }
- for (index = 0; index < Infantry.Count(); index++) {
- InfantryClass const * infantry = Infantry.Ptr(index);
- if (infantry->IsLocked && (GameToPlay != GAME_NORMAL || !infantry->House->IsHuman || infantry->IsDiscoveredByPlayer)) {
- infantry->House->NewIScan |= (1L << infantry->Class->Type);
- if (!infantry->IsInLimbo) infantry->House->NewActiveIScan |= (1L << infantry->Class->Type);
- }
- }
- for (index = 0; index < Aircraft.Count(); index++) {
- AircraftClass const * aircraft = Aircraft.Ptr(index);
- if (aircraft->IsLocked && (GameToPlay != GAME_NORMAL || !aircraft->House->IsHuman || aircraft->IsDiscoveredByPlayer)) {
- aircraft->House->NewAScan |= (1L << aircraft->Class->Type);
- if (!aircraft->IsInLimbo) aircraft->House->NewActiveAScan |= (1L << aircraft->Class->Type);
- }
- }
- for (index = 0; index < Buildings.Count(); index++) {
- BuildingClass const * building = Buildings.Ptr(index);
- if (building->IsLocked && (GameToPlay != GAME_NORMAL || !building->House->IsHuman || building->IsDiscoveredByPlayer)) {
- building->House->NewBScan |= (1L << building->Class->Type);
- if (!building->IsInLimbo) building->House->NewActiveBScan |= (1L << building->Class->Type);
- }
- }
- // Heap_Dump_Check( "After Object AI 2" );
- /*
- ** Map related logic is performed.
- */
- Map.Logic();
- // Heap_Dump_Check( "After Map.Logic" );
- /*
- ** Factory processing is performed.
- */
- for (index = 0; index < Factories.Count(); index++) {
- Factories.Ptr(index)->AI();
- }
- // Heap_Dump_Check( "After Factory AI" );
- /*
- ** House processing is performed.
- */
- for (HousesType house = HOUSE_FIRST; house < HOUSE_COUNT; house++) {
- HouseClass * hptr = HouseClass::As_Pointer(house);
- if (hptr && hptr->IsActive) {
- hptr->AI();
- }
- }
- // Heap_Dump_Check( "After House AI" );
- }
|