diff --git a/src/game/common/globals.cpp b/src/game/common/globals.cpp index 90ec0c65..8d728fa4 100644 --- a/src/game/common/globals.cpp +++ b/src/game/common/globals.cpp @@ -82,6 +82,7 @@ void *g_TurretShapes = nullptr; void *g_SamShapes = nullptr; void *g_MGunShapes = nullptr; +#ifdef CHRONOSHIFT_DEBUG BOOL g_Debug_MotionCapture = false; BOOL g_Debug_Rotate = false; BOOL g_Debug_Quiet = false; @@ -96,6 +97,7 @@ BOOL g_Debug_Passable = false; BOOL g_Debug_Unshroud = false; BOOL g_Debug_Threat = false; BOOL g_Debug_Find_Path = false; +BOOL g_Debug_Draw_Paths = false; BOOL g_Debug_Check_Map = false; BOOL g_Debug_Playtest = false; BOOL g_Debug_Heap_Dump = false; @@ -105,9 +107,6 @@ BOOL g_Debug_Modem_Dump = false; BOOL g_Debug_Print_Events = false; BOOL g_MonoEnabled = false; // Actually a part of MonoClass. -#endif - -int g_mapBinaryVersion; // For handling C&C and Sole Survivor map formats. BOOL g_Debug_Paused = false; BOOL g_Debug_Step = false; @@ -118,13 +117,22 @@ BOOL g_Debug_GuardRange = false; BOOL g_Debug_WeaponRange = false; BOOL g_Debug_AttackFriendlies = false; BOOL g_Debug_NavList = false; +BOOL g_Debug_HeadTo = false; +BOOL g_Debug_NavCom = false; +BOOL g_Debug_TarCom = false; BOOL g_Debug_Damage = false; BOOL g_Debug_AIControl = false; BOOL g_Debug_InstantBuild = false; BOOL g_Debug_BuildCheat = false; BOOL g_Debug_CursorCoords = false; +DebugFindPathType g_Debug_Find_Path_Mode = DEBUG_PATH_NONE; +#endif + +int g_mapBinaryVersion; // For handling C&C and Sole Survivor map formats. + BOOL g_Cheat_OreCivilians = false; BOOL g_Cheat_TeslaChoppers = false; BOOL g_ConfirmExit = false; +#endif diff --git a/src/game/common/globals.h b/src/game/common/globals.h index e14f7363..8bb8ba4b 100644 --- a/src/game/common/globals.h +++ b/src/game/common/globals.h @@ -164,6 +164,7 @@ extern void *&g_TurretShapes; extern void *&g_SamShapes; extern void *&g_MGunShapes; +#ifdef CHONOSHIFT_DEBUG extern BOOL &g_Debug_MotionCapture; extern BOOL &g_Debug_Rotate; extern BOOL &g_Debug_Quiet; @@ -185,6 +186,7 @@ extern BOOL &g_Debug_Smart_Print; extern BOOL &g_Debug_Trap_Check_Heap; extern BOOL &g_Debug_Modem_Dump; extern BOOL &g_Debug_Print_Events; +#endif extern BOOL &g_MonoEnabled; #else @@ -250,6 +252,7 @@ extern void *g_TurretShapes; extern void *g_SamShapes; extern void *g_MGunShapes; +#ifdef CHRONOSHIFT_DEBUG extern BOOL g_Debug_MotionCapture; extern BOOL g_Debug_Rotate; extern BOOL g_Debug_Quiet; @@ -264,6 +267,7 @@ extern BOOL g_Debug_Passable; extern BOOL g_Debug_Unshroud; extern BOOL g_Debug_Threat; extern BOOL g_Debug_Find_Path; +extern BOOL g_Debug_Draw_Paths; extern BOOL g_Debug_Check_Map; extern BOOL g_Debug_Playtest; extern BOOL g_Debug_Heap_Dump; @@ -272,26 +276,40 @@ extern BOOL g_Debug_Trap_Check_Heap; extern BOOL g_Debug_Modem_Dump; extern BOOL g_Debug_Print_Events; -extern BOOL g_MonoEnabled; -#endif - -extern int g_mapBinaryVersion; - -extern BOOL g_Debug_Paused; -extern BOOL g_Debug_Step; -extern int g_Debug_StepCount; - extern BOOL g_Debug_SightRange; extern BOOL g_Debug_GuardRange; extern BOOL g_Debug_WeaponRange; extern BOOL g_Debug_AttackFriendlies; extern BOOL g_Debug_NavList; +extern BOOL g_Debug_HeadTo; +extern BOOL g_Debug_NavCom; +extern BOOL g_Debug_TarCom; extern BOOL g_Debug_Damage; extern BOOL g_Debug_AIControl; extern BOOL g_Debug_InstantBuild; extern BOOL g_Debug_BuildCheat; extern BOOL g_Debug_CursorCoords; +enum DebugFindPathType { + DEBUG_PATH_NONE, + DEBUG_PATH_AI, + DEBUG_PATH_PLAYER, + DEBUG_PATH_BOTH, + DEBUG_PATH_COUNT +}; +DEFINE_ENUMERATION_OPERATORS(DebugFindPathType); + +extern DebugFindPathType g_Debug_Find_Path_Mode; + +extern BOOL g_Debug_Paused; +extern BOOL g_Debug_Step; +extern int g_Debug_StepCount; + +extern BOOL g_MonoEnabled; +#endif + +extern int g_mapBinaryVersion; + extern BOOL g_Cheat_OreCivilians; extern BOOL g_Cheat_TeslaChoppers; diff --git a/src/game/common/remap.cpp b/src/game/common/remap.cpp index 03c3e9aa..3bf06e90 100644 --- a/src/game/common/remap.cpp +++ b/src/game/common/remap.cpp @@ -21,3 +21,5 @@ RemapControlType MetalScheme; RemapControlType GreyScheme; RemapControlType SidebarScheme; #endif + +RemapControlType WhiteScheme; diff --git a/src/game/common/remap.h b/src/game/common/remap.h index 86cba0b2..93252a68 100644 --- a/src/game/common/remap.h +++ b/src/game/common/remap.h @@ -76,4 +76,6 @@ extern RemapControlType GreyScheme; extern RemapControlType SidebarScheme; #endif +extern RemapControlType WhiteScheme; + #endif // REMAP_H diff --git a/src/game/debug/gamelogging.cpp b/src/game/debug/gamelogging.cpp index b453c53a..485f0342 100644 --- a/src/game/debug/gamelogging.cpp +++ b/src/game/debug/gamelogging.cpp @@ -364,7 +364,7 @@ void Debug_Log(const char *format, ...) #endif } - vsprintf(&DebugBuffer[strlen(DebugBuffer)], Prep_Buffer(format, DebugBuffer), va); + vsprintf(DebugBuffer, Prep_Buffer(format, DebugBuffer), va); if (strlen(DebugBuffer) >= DEBUG_BUFFER_SIZE) { #ifdef PLATFORM_WINDOWS diff --git a/src/game/engine/display.cpp b/src/game/engine/display.cpp index 15f3d2b5..07a3b9de 100644 --- a/src/game/engine/display.cpp +++ b/src/game/engine/display.cpp @@ -1967,6 +1967,25 @@ void DisplayClass::Center_Map(coord_t coord) } } +/** +* @brief +* +* SS: 0x0044807C +*/ +void DisplayClass::Redraw_View(BOOL force) +{ + cell_t tl_cell_x = Max((cell_t)0, (cell_t)Coord_Cell_X(DisplayPos)); + cell_t tl_cell_y = Max((cell_t)0, (cell_t)Coord_Cell_Y(DisplayPos)); + cell_t br_cell_x = Min((cell_t)(Lepton_To_Cell_Coord(DisplayWidth) + tl_cell_x), (cell_t)(MAP_MAX_WIDTH - 1)); + cell_t br_cell_y = Min((cell_t)(Lepton_To_Cell_Coord(DisplayHeight) + tl_cell_y), (cell_t)(MAP_MAX_HEIGHT - 1)); + for (cell_t x = tl_cell_x; x <= br_cell_x ; ++x) { + for (cell_t y = tl_cell_y; y <= br_cell_y; ++y) { + cell_t cellnum = Cell_From_XY(x, y); + Map[cellnum].Redraw_Objects(); + } + } +} + /** * @brief Registers the cell in the band box cursor list, calculates from mouse pos if cell is -1. * diff --git a/src/game/engine/display.h b/src/game/engine/display.h index 788e81e6..0b30daef 100644 --- a/src/game/engine/display.h +++ b/src/game/engine/display.h @@ -95,6 +95,7 @@ class DisplayClass : public MapClass void Sell_Mode_Control(int mode); void Repair_Mode_Control(int mode); void Center_Map(coord_t coord = 0); + void Redraw_View(BOOL force = false); cell_t Set_Cursor_Pos(cell_t cell); BOOL Passes_Proximity_Check(ObjectTypeClass *object, HousesType house, int16_t *list, cell_t cell) const; void Redraw_Icons(); diff --git a/src/game/engine/foot.cpp b/src/game/engine/foot.cpp index 05553fb4..eb1fe69a 100644 --- a/src/game/engine/foot.cpp +++ b/src/game/engine/foot.cpp @@ -21,8 +21,12 @@ #include "iomap.h" #include "rules.h" #include "session.h" +#include "special.h" #include "target.h" #include "team.h" +#include "keyboard.h" +#include "mouse.h" +#include "ostimer.h" #include #include @@ -30,8 +34,28 @@ #define PATH_FLAG_BITSIZE 32 #ifdef GAME_DLL -extern cell_t &StartLocation; -extern cell_t &DestLocation; +static cell_t &StartLocation = Make_Global(0x0065D7AE); +static cell_t &DestLocation = Make_Global(0x0065D7AC); + +// Maximum times to retry when met with an obstruction. +#define PATH_RETRY_COUNT 400 + +#ifdef CHRONOSHIFT_DEBUG +int Debug_X_Pos = 0; +int Debug_Y_Pos = 16; +int Debug_Width = 480; +int Debug_Height = 386; + +int Debug_Map_X_Pos = Debug_X_Pos; +int Debug_Map_Y_Pos = Debug_Y_Pos; + +BOOL Debug_Find_Path = false; +BOOL Debug_Draw_Paths = false; + +#define MAP_CELL_PIXEL_SIZE 4 // Size of the pixel representation for a cell when plotting the info on the actual map. +#define CELL_PIXEL_SIZE 3 // Size of the pixel representation for a cell when plotting the debug map. +#endif + #else static cell_t StartLocation; static cell_t DestLocation; @@ -40,6 +64,7 @@ static cell_t DestLocation; static unsigned MainOverlap[512]; // Is this perhaps some map size math? static unsigned LeftOverlap[512]; // Is this perhaps some map size math? static unsigned RightOverlap[512]; // Is this perhaps some map size math? + static int PathCount; FootClass::FootClass(RTTIType type, int id, HousesType house) : @@ -426,11 +451,25 @@ PathType *FootClass::Find_Path(cell_t dest, FacingType *buffer, int length, Move return nullptr; } - int threat; - int risk; - int threat_state = 0; + // Set up initial state of the path + cell_t current_cell = Coord_To_Cell(Get_Coord()); + +#ifdef CHRONOSHIFT_DEBUG + if (Debug_Find_Path) { + g_mouse->Hide_Mouse(); + Debug_Draw_Map("Initial Draw", current_cell, dest); + // Wait for input, gives the user time to see the final path map. + g_keyboard->Wait_For_Input(KN_RETURN); + g_mouse->Show_Mouse(); + } +#endif + ++PathCount; + int threat = 0; + int risk = 0; + int threat_state = 0; + // Are we part of a team and should that team avoid threats? if (!m_Team.Is_Valid() || !m_Team->Should_Avoid_Threats()) { // DEBUG_LOG(" Threat procesing will not be performed for final cell.\n"); @@ -447,9 +486,6 @@ PathType *FootClass::Find_Path(cell_t dest, FacingType *buffer, int length, Move threat = 0; } - // Set up initial state of the path - cell_t current_cell = Coord_To_Cell(Get_Coord()); - _path.StartCell = StartLocation = current_cell; _path.Score = 0; _path.Length = 0; @@ -472,7 +508,12 @@ PathType *FootClass::Find_Path(cell_t dest, FacingType *buffer, int length, Move cell_t adj_cell = Cell_Get_Adjacent(current_cell, direction); int cell_score = Passable_Cell(adj_cell, direction, threat, move); - if (cell_score != 0) { // Great, we have a direct move, do the next round. + if (cell_score > 0) { // Great, we have a direct move, do the next round. + + #ifdef CHRONOSHIFT_DEBUG + Debug_Plot_Cell(adj_cell, true, threat_state); + #endif + // DEBUG_LOG(" Cell passable and on direct route, registering cell.\n"); Register_Cell(&_path, adj_cell, direction, cell_score, move); current_cell = adj_cell; @@ -486,18 +527,36 @@ PathType *FootClass::Find_Path(cell_t dest, FacingType *buffer, int length, Move int left_score = 0; PathType *chosen_path = nullptr; + #ifdef CHRONOSHIFT_DEBUG + if (Debug_Find_Path) { + g_mouse->Hide_Mouse(); + Debug_Draw_Map("Walk Through Obstacle", current_cell, dest); + // Wait for input, gives the user time to see the final path map. + g_keyboard->Wait_For_Input(KN_RETURN); + g_mouse->Show_Mouse(); + } + #endif + + #ifdef CHRONOSHIFT_DEBUG + Debug_Plot_Cell(adj_cell, false, threat_state); + #endif + if (adj_cell == dest) { // Close enough. break; } int i = 0; - while (i < 5) { FacingType next_dir = Direction_To_Facing(Cell_Direction8(adj_cell, dest)); adj_cell = Cell_Get_Adjacent(adj_cell, next_dir); // If we still don't have passable, see if we are close. if (Passable_Cell(adj_cell, FACING_NONE, threat, move) == 0) { + + #ifdef CHRONOSHIFT_DEBUG + Debug_Plot_Cell(adj_cell, false, threat_state); + #endif + // If we are close, adjust the threat and try again. if (adj_cell == dest) { if (threat == -1) { @@ -528,6 +587,17 @@ PathType *FootClass::Find_Path(cell_t dest, FacingType *buffer, int length, Move } } + #ifdef CHRONOSHIFT_DEBUG + Debug_Plot_Cell(adj_cell, true, threat_state); + #endif + + #ifdef CHRONOSHIFT_DEBUG + if (Debug_Find_Path) { + g_mouse->Hide_Mouse(); + Debug_Draw_Map("Follow Left Edge", current_cell, adj_cell); + } + #endif + memcpy(&left_path, &_path, sizeof(left_path)); left_path.Moves = left_moves; left_path.Overlap = LeftOverlap; @@ -544,6 +614,22 @@ PathType *FootClass::Find_Path(cell_t dest, FacingType *buffer, int length, Move sizeof(left_moves) - 2, move); + #ifdef CHRONOSHIFT_DEBUG + if (Debug_Find_Path) { + Debug_Print_Steps("Left", left_score, left_path.Length); + // Wait for input, gives the user time to see the final path map. + g_keyboard->Wait_For_Input(KN_RETURN); + g_mouse->Show_Mouse(); + } + #endif + + #ifdef CHRONOSHIFT_DEBUG + if (Debug_Find_Path) { + g_mouse->Hide_Mouse(); + Debug_Draw_Map("Follow Right Edge", current_cell, adj_cell); + } + #endif + memcpy(&right_path, &_path, sizeof(right_path)); right_path.Moves = right_moves; right_path.Overlap = RightOverlap; @@ -560,6 +646,15 @@ PathType *FootClass::Find_Path(cell_t dest, FacingType *buffer, int length, Move sizeof(right_moves) - 2, move); + #ifdef CHRONOSHIFT_DEBUG + if (Debug_Find_Path) { + Debug_Print_Steps("Right", right_score, right_path.Length); + // Wait for input, gives the user time to see the final path map. + g_keyboard->Wait_For_Input(KN_RETURN); + g_mouse->Show_Mouse(); + } + #endif + if (left_score != 0 || right_score != 0) { // DEBUG_LOG(" Found a path following an edge.\n"); break; @@ -634,8 +729,19 @@ PathType *FootClass::Find_Path(cell_t dest, FacingType *buffer, int length, Move _path.UnravelCheckpoint = -1; current_cell = adj_cell; + + #ifdef CHRONOSHIFT_DEBUG + if (Debug_Find_Path) { + g_mouse->Hide_Mouse(); + Debug_Draw_Map("Walking To Next Obstacle", current_cell, dest); + // Wait for input, gives the user time to see the final path map. + g_keyboard->Wait_For_Input(KN_RETURN); + g_mouse->Show_Mouse(); + } + #endif + } else { - // DEBUG_LOG(" Find_Path bailing, mount cound 0 after successful follow edge.\n"); + // DEBUG_LOG(" Find_Path bailing: move count is zero after successful follow edge.\n"); break; } } else { @@ -648,9 +754,50 @@ PathType *FootClass::Find_Path(cell_t dest, FacingType *buffer, int length, Move _path.Moves[_path.Length++] = FACING_NONE; } +#ifdef CHRONOSHIFT_DEBUG + if (Debug_Find_Path) { + g_mouse->Hide_Mouse(); + Debug_Draw_Map("Final Generated Path (Before Optimization)", current_cell, dest); + Debug_Draw_Path(&_path); + // Wait for input, gives the user time to see the final path map. + g_keyboard->Wait_For_Input(KN_RETURN); + g_mouse->Show_Mouse(); + } +#endif + Optimize_Moves(&_path, move); +#ifdef CHRONOSHIFT_DEBUG + if (Debug_Find_Path) { + g_mouse->Hide_Mouse(); + Debug_Draw_Map("Final Generated Path (After Optimization)", current_cell, dest); + Debug_Draw_Path(&_path); + // Wait for input, gives the user time to see the final path map. + g_keyboard->Wait_For_Input(KN_RETURN); + g_mouse->Show_Mouse(); + } + + // perform a full redraw of the viewport. + if (Debug_Find_Path) { + Map.Flag_To_Redraw(true); + Map.Render(); + } + + // Draw the final generated path onto the tactical map using markers. + if (Debug_Draw_Paths) { + // DEBUG_LOG("Drawing final generated path to tactical map.\n"); + Debug_Draw_Path(&_path); + } + + // perform a full redraw of the viewport. + if (Debug_Find_Path || Debug_Draw_Paths) { + Map.Flag_To_Redraw(true); + Map.Render(); + } +#endif + // DEBUG_LOG("Completed Find_Path...\n"); + return &_path; } @@ -661,6 +808,29 @@ PathType *FootClass::Find_Path(cell_t dest, FacingType *buffer, int length, Move */ BOOL FootClass::Basic_Path() { + // preapre debug flags for path generation debug systems. +#ifdef CHRONOSHIFT_DEBUG + + // falsify the map path drawing flags. + Debug_Find_Path = false; + Debug_Draw_Paths = false; + + if ((g_Debug_Find_Path_Mode == DEBUG_PATH_AI || g_Debug_Find_Path_Mode == DEBUG_PATH_BOTH) && !m_OwnerHouse->Is_Human() && !m_OwnerHouse->Is_Player()) { + Debug_Find_Path = true; + Debug_Draw_Paths = m_Selected; // only draw the path when the object is selected. + } + + if ((g_Debug_Find_Path_Mode == DEBUG_PATH_PLAYER || g_Debug_Find_Path_Mode == DEBUG_PATH_BOTH) && m_OwnerHouse->Is_Player()) { + Debug_Find_Path = true; + } + + if (g_Debug_Draw_Paths) { + Debug_Draw_Paths = m_Selected; // only draw the path when the object is selected. + } + + //} +#endif + m_Paths[0] = FACING_NONE; bool havepath = false; @@ -732,7 +902,7 @@ BOOL FootClass::Basic_Path() do { path = Find_Path(navcell, facings, GEN_PATH_LENGTH, m_PathMove); - if (path != nullptr && path->Score != 0) { + if (path != nullptr && path->Score > 0) { //memcpy(&pathobj, path, sizeof(pathobj)); pathobj = *path; do_fixup = true; @@ -785,7 +955,9 @@ BOOL FootClass::Unravel_Loop(PathType *path, cell_t &cell, FacingType &facing, i facing = *(facing_ptr - 1); // field_A a pointer to facing types? path->UnravelCheckpoint = cellnum; path->Length = i; - + #ifdef CHRONOSHIFT_DEBUG + Debug_Plot_Cell(cellnum, true, -1, COLOR_CYAN); + #endif return true; } @@ -794,6 +966,9 @@ BOOL FootClass::Unravel_Loop(PathType *path, cell_t &cell, FacingType &facing, i path->Score -= Passable_Cell(cellnum, *facing_ptr, -1, move); path->Overlap[cellnum / PATH_FLAG_BITSIZE] &= ~(1 << (cellnum % PATH_FLAG_BITSIZE)); + #ifdef CHRONOSHIFT_DEBUG + Debug_Plot_Cell(cellnum, true, -1, COLOR_LTCYAN); + #endif face = *facing_ptr--; cellnum += AdjacentCell[Opposite_Facing(face)]; } @@ -826,7 +1001,9 @@ BOOL FootClass::Register_Cell(PathType *path, cell_t cell, FacingType facing, in cell_t cellnum = Cell_Get_Adjacent(cell, Opposite_Facing(facing)); path->Overlap[cellnum / PATH_FLAG_BITSIZE] &= ~(1 << (cellnum % PATH_FLAG_BITSIZE)); --path->Length; - + #ifdef CHRONOSHIFT_DEBUG + Debug_Plot_Cell(cellnum, true, -1, COLOR_BLUE); + #endif return true; } @@ -860,6 +1037,9 @@ BOOL FootClass::Register_Cell(PathType *path, cell_t cell, FacingType facing, in path->Score -= Passable_Cell(test_cell, *face_ptr, -1, move); // Sole has a -1 before the 1 << while RA doesn't here... path->Overlap[test_cell / PATH_FLAG_BITSIZE] &= ~(1 << (test_cell % PATH_FLAG_BITSIZE)); + #ifdef CHRONOSHIFT_DEBUG + Debug_Plot_Cell(test_cell, true, -1, COLOR_LTBLUE); + #endif ++count; ++face_ptr; } @@ -925,12 +1105,21 @@ BOOL FootClass::Follow_Edge(cell_t start, cell_t destination, PathType *path, Fa if (next_adj == destination) { cell_cost = Passable_Cell(next_adj, Facing_Adjust(edge_face, chirality), threat, move); - if (cell_cost != 0) { + if (cell_cost > 0) { + + #ifdef CHRONOSHIFT_DEBUG + Debug_Plot_Cell(next_adj, true, threat_state); + #endif + edge_face = Facing_Adjust(edge_face, chirality); edge_cell = Cell_Get_Adjacent(curr_cell, edge_face); break; } + + #ifdef CHRONOSHIFT_DEBUG + Debug_Plot_Cell(next_adj, false, threat_state); + #endif } cell_t chk_cell = Cell_Get_Adjacent(curr_cell, edge_face); @@ -962,11 +1151,20 @@ BOOL FootClass::Follow_Edge(cell_t start, cell_t destination, PathType *path, Fa if (!either_side_of_line) { cell_cost = Passable_Cell(edge_cell, edge_face, threat, move); - if (cell_cost != 0) { + if (cell_cost > 0) { + + #ifdef CHRONOSHIFT_DEBUG + Debug_Plot_Cell(edge_cell, true, threat_state); + #endif + break; } } + #ifdef CHRONOSHIFT_DEBUG + Debug_Plot_Cell(edge_cell, false, threat_state, (either_side_of_line ? COLOR_BROWN : COLOR_TBLACK)); + #endif + if (edge_cell == destination) { loop_finished = true; break; @@ -993,7 +1191,7 @@ BOOL FootClass::Follow_Edge(cell_t start, cell_t destination, PathType *path, Fa } // If we can't get round the obstruction in 400 moves, give up? - if (++path_count == 400) { + if (++path_count == PATH_RETRY_COUNT) { return false; } } @@ -1296,7 +1494,7 @@ PathType *FootClass::Find_Path_Wrapper(cell_t dest, FacingType *buffer, int leng if (num1 != 0) { DEBUG_LOG("ERROR: Find_Path_Wrapper Moves don't match\n"); } - int num2 = memcmp(real->Overlap, test_overlap, 2048); + int num2 = memcmp(real->Overlap, test_overlap, 512 * 4); // sizeof(OVERLAP_SIZE)? if (num2 != 0) { DEBUG_LOG("ERROR: Find_Path_Wrapper Overlaps don't match\n"); } @@ -1307,3 +1505,216 @@ PathType *FootClass::Find_Path_Wrapper(cell_t dest, FacingType *buffer, int leng DEBUG_LOG("***Find_Path_Wrapper exit***\n"); return real; } + +#ifdef CHRONOSHIFT_DEBUG +void FootClass::Debug_Draw_Map(const char *title, cell_t source, cell_t dest/*, BOOL enter_wait_for_input, BOOL exit_wait_for_input*/) +{ + //DEBUG_LOG("FootClass::Debug_Draw_Map(%s)(enter) - '%s'\n", Name(), title); + + /*if (enter_wait_for_input) { + //DEBUG_LOG("FootClass::Debug_Draw_Map(enter) - Waiting for user input...\n"); + g_keyboard->Wait_For_Input(KN_RETURN); + //DEBUG_LOG("FootClass::Debug_Draw_Map(enter) - Got user input.\n"); + }*/ + + //DEBUG_LOG("FootClass::Debug_Draw_Map() - Drawing map.\n"); + + GraphicViewPortClass *prevpage = Set_Logic_Page(g_seenBuff); + + // Clear the visible buffer. + //g_visiblePage.Clear(); + g_seenBuff.Fill_Rect(Debug_X_Pos, Debug_Y_Pos, Debug_X_Pos + Debug_Width, Debug_Y_Pos + Debug_Height, COLOR_BLACK); + + // Print the map title at top center. + Fancy_Text_Print(title, Debug_X_Pos + (Debug_Width / 2), Debug_Y_Pos + 10, &WhiteScheme, COLOR_BLACK, TPF_CENTER | TPF_8PT); + + // print current object info. + Fancy_Text_Print("Object: %s", (Debug_X_Pos + Debug_Width) - 90, Debug_Y_Pos + 260, &WhiteScheme, COLOR_BLACK, TPF_LEFT | TPF_8PT, Name()); + Fancy_Text_Print("Owner: %s", (Debug_X_Pos + Debug_Width) - 90, Debug_Y_Pos + 272, &WhiteScheme, COLOR_BLACK, TPF_LEFT | TPF_8PT, m_OwnerHouse->Is_Player() ? "PLAYER" : "AI"); + + Fancy_Text_Print("Source: %dx%d", (Debug_X_Pos + Debug_Width) - 90, Debug_Y_Pos + 296, &WhiteScheme, COLOR_BLACK, TPF_LEFT | TPF_8PT, Cell_Get_X(source), Cell_Get_Y(source)); + Fancy_Text_Print("Dest: %dx%d", (Debug_X_Pos + Debug_Width) - 90, Debug_Y_Pos + 304, &WhiteScheme, COLOR_BLACK, TPF_LEFT | TPF_8PT, Cell_Get_X(dest), Cell_Get_Y(dest)); + + for (int cell_x = 0; cell_x < MAP_MAX_WIDTH; ++cell_x) { + + for (int cell_y = 0; cell_y < MAP_MAX_HEIGHT; ++cell_y) { + + cell_t curr_cellnum = Cell_From_XY(cell_x, cell_y); + CellClass &cell = Map[curr_cellnum]; + + ColorType color = COLOR_TBLACK; + + switch (Can_Enter_Cell(curr_cellnum)) { + case MOVE_OK: // Passable cells + color = COLOR_GREEN; + break; + + case MOVE_MOVING_BLOCK: // Units, etc + color = COLOR_LTGREEN; + break; + + case MOVE_DESTROYABLE: + color = COLOR_YELLOW; + break; + + case MOVE_TEMP: + color = COLOR_BROWN; + break; + + case MOVE_CLOAK: + color = COLOR_PURPLE; + break; + + case MOVE_NO: // Impassable cells (cliffs, rocks, etc.) + // This also includes water for land objects, and + // land for ships. + color = COLOR_RED; + break; + + default: + break; + }; + + // If cell is out of current map bounds, colour it grey. + if ( !Map.In_Visible_Map(curr_cellnum) ) { + color = COLOR_LTGREY; + } + + // colour the source cell light blue. + if ( curr_cellnum == source ) { + color = COLOR_LTBLUE; + } + + // colour the destination cell blue. + if ( curr_cellnum == dest ) { + color = COLOR_BLUE; + } + + int cell_pos_x = Debug_Map_X_Pos + (cell_x * CELL_PIXEL_SIZE); + int cell_pos_y = Debug_Map_Y_Pos + (cell_y * CELL_PIXEL_SIZE); + + // plot the cell pixel. + g_seenBuff.Put_Fat_Pixel(cell_pos_x, cell_pos_y, CELL_PIXEL_SIZE, color); + } + } + + int legend_ypos = Debug_Y_Pos + 100; + + int legend_block_x_pos = (Debug_X_Pos + Debug_Width) - 14; + int legend_text_x_pos = (Debug_X_Pos + Debug_Width) - 18; + + // print the legend info. + Fancy_Text_Print("Start Cell", legend_text_x_pos, legend_ypos + 2, &WhiteScheme, COLOR_TBLACK, TPF_RIGHT | TPF_8PT); + g_seenBuff.Fill_Rect(legend_block_x_pos, legend_ypos, legend_block_x_pos + 10, legend_ypos + 12, COLOR_LTBLUE); + legend_ypos += 12; + + Fancy_Text_Print("Dest Cell", legend_text_x_pos, legend_ypos + 2, &WhiteScheme, COLOR_TBLACK, TPF_RIGHT | TPF_8PT); + g_seenBuff.Fill_Rect(legend_block_x_pos, legend_ypos, legend_block_x_pos + 10, legend_ypos + 12, COLOR_BLUE); + legend_ypos += 12; + + Fancy_Text_Print("O.O.B. Cells", legend_text_x_pos, legend_ypos + 2, &WhiteScheme, COLOR_TBLACK, TPF_RIGHT | TPF_8PT); + g_seenBuff.Fill_Rect(legend_block_x_pos, legend_ypos, legend_block_x_pos + 10, legend_ypos + 12, COLOR_LTGREY); + legend_ypos += 20; + + Fancy_Text_Print("OK", legend_text_x_pos, legend_ypos + 2, &WhiteScheme, COLOR_TBLACK, TPF_RIGHT | TPF_8PT); + g_seenBuff.Fill_Rect(legend_block_x_pos, legend_ypos, legend_block_x_pos + 10, legend_ypos + 12, COLOR_GREEN); + legend_ypos += 12; + + Fancy_Text_Print("Moving Block", legend_text_x_pos, legend_ypos + 2, &WhiteScheme, COLOR_TBLACK, TPF_RIGHT | TPF_8PT); + g_seenBuff.Fill_Rect(legend_block_x_pos, legend_ypos, legend_block_x_pos + 10, legend_ypos + 12, COLOR_LTGREEN); + legend_ypos += 12; + + Fancy_Text_Print("Destroyable", legend_text_x_pos, legend_ypos + 2, &WhiteScheme, COLOR_TBLACK, TPF_RIGHT | TPF_8PT); + g_seenBuff.Fill_Rect(legend_block_x_pos, legend_ypos, legend_block_x_pos + 10, legend_ypos + 12, COLOR_YELLOW); + legend_ypos += 12; + + Fancy_Text_Print("Temp", legend_text_x_pos, legend_ypos + 2, &WhiteScheme, COLOR_TBLACK, TPF_RIGHT | TPF_8PT); + g_seenBuff.Fill_Rect(legend_block_x_pos, legend_ypos, legend_block_x_pos + 10, legend_ypos + 12, COLOR_BROWN); + legend_ypos += 12; + + Fancy_Text_Print("Cloaked", legend_text_x_pos, legend_ypos + 2, &WhiteScheme, COLOR_TBLACK, TPF_RIGHT | TPF_8PT); + g_seenBuff.Fill_Rect(legend_block_x_pos, legend_ypos, legend_block_x_pos + 10, legend_ypos + 12, COLOR_PURPLE); + legend_ypos += 12; + + Fancy_Text_Print("No", legend_text_x_pos, legend_ypos + 2, &WhiteScheme, COLOR_TBLACK, TPF_RIGHT | TPF_8PT); + g_seenBuff.Fill_Rect(legend_block_x_pos, legend_ypos, legend_block_x_pos + 10, legend_ypos + 12, COLOR_RED); + + // print the continue button text. + Fancy_Text_Print("Press ENTER", (Debug_X_Pos + Debug_Width) - 90, (Debug_Y_Pos + Debug_Height) - 76, &WhiteScheme, COLOR_TBLACK, TPF_LEFT | TPF_8PT); + Fancy_Text_Print("to continue", (Debug_X_Pos + Debug_Width) - 90, (Debug_Y_Pos + Debug_Height) - 60, &WhiteScheme, COLOR_TBLACK, TPF_LEFT | TPF_8PT); + + /*if (exit_wait_for_input) { + //DEBUG_LOG("FootClass::Debug_Draw_Map(exit) - Waiting for user input...\n"); + g_keyboard->Wait_For_Input(KN_RETURN); + //DEBUG_LOG("FootClass::Debug_Draw_Map(exit) - Got user input.\n"); + }*/ + + Set_Logic_Page(prevpage); + + //DEBUG_LOG("FootClass::Debug_Draw_Map(exit)\n"); +} + +void FootClass::Debug_Draw_Path(PathType *path, BOOL draw_tactical) +{ + //DEBUG_LOG("FootClass::Debug_Draw_Path(%s)(enter)\n", Name()); + + if (path != nullptr) { + cell_t cellnum = path->StartCell; + for (int i = 0; i < path->Length; ++i) { + cellnum = Cell_Get_Adjacent(cellnum, path->Moves[i]); + Debug_Plot_Cell(cellnum, true); + } + } +} + +void FootClass::Debug_Plot_Cell(cell_t cell, BOOL a2, int threat_state, uint8_t color) +{ + //DEBUG_LOG("FootClass::Debug_Plot_Map_Cell(%s)(enter)\n", Name()); + + // draw the cell pixel on the debug map + if (Debug_Find_Path) { + int cell_pos_x = Debug_Map_X_Pos + (Cell_Get_X(cell) * CELL_PIXEL_SIZE) + 1; + int cell_pos_y = Debug_Map_Y_Pos + (Cell_Get_Y(cell) * CELL_PIXEL_SIZE) + 1; + if (color != COLOR_TBLACK) { + g_seenBuff.Put_Fat_Pixel(cell_pos_x, cell_pos_y, 1, color); + } else { + g_seenBuff.Put_Fat_Pixel(cell_pos_x, cell_pos_y, 1, (a2 ? COLOR_WHITE : COLOR_BLACK)); + } + } + + // draw the cell pixel on the tactical map. + if (Debug_Draw_Paths) { + int x_pos = 0; + int y_pos = 0; + coord_t coord = Coord_Centered(Cell_To_Coord(cell)); + if ( Map.Coord_To_Pixel(coord, x_pos, y_pos) ) { + if (threat_state <= 2) { + g_seenBuff.Put_Fat_Pixel(x_pos, y_pos, MAP_CELL_PIXEL_SIZE, (a2 ? (threat_state + 9) : COLOR_BLACK)); + g_seenBuff.Put_Fat_Pixel(x_pos + 1, y_pos + 1, MAP_CELL_PIXEL_SIZE - 1, (a2 ? (threat_state + 9) : COLOR_RED)); + } else { + g_seenBuff.Put_Fat_Pixel(x_pos, y_pos, MAP_CELL_PIXEL_SIZE, (a2 ? (threat_state + 9) : COLOR_BLACK)); + g_seenBuff.Put_Fat_Pixel(x_pos + 1, y_pos + 1, MAP_CELL_PIXEL_SIZE - 1, (a2 ? COLOR_LTGREEN : COLOR_RED)); + } + } + } +} + +void FootClass::Debug_Print_Steps(const char *text, int score, int steps) +{ + //DEBUG_LOG("FootClass::Debug_Print_Steps(%s)(enter)\n", Name()); + + int text_x_pos = (Debug_X_Pos + Debug_Width) - 100; + int text_y_pos = Debug_Y_Pos + 40; + + Fancy_Text_Print(text, text_x_pos, text_y_pos, &WhiteScheme, COLOR_TBLACK, TPF_LEFT | TPF_8PT); + + text_y_pos += 12; + + if (score > 0) { + Fancy_Text_Print("Total Steps: %d", text_x_pos, text_y_pos, &WhiteScheme, COLOR_TBLACK, TPF_LEFT | TPF_8PT, steps); + } else { + Fancy_Text_Print("Total Steps: FAIL!", text_x_pos, text_y_pos, &WhiteScheme, COLOR_TBLACK, TPF_LEFT | TPF_8PT); + } +} + +#endif diff --git a/src/game/engine/foot.h b/src/game/engine/foot.h index 63640a67..c8c3c33a 100644 --- a/src/game/engine/foot.h +++ b/src/game/engine/foot.h @@ -123,11 +123,21 @@ class FootClass : public TechnoClass static int Point_Relative_To_Line(int px, int py, int sx, int sy, int ex, int ey); PathType *Find_Path_Wrapper(cell_t dest, FacingType *buffer, int length, MoveType move); + static int Max_Path_Length() { return PATH_LENGTH; } + #ifdef GAME_DLL BOOL Hook_Can_Demolish() { return FootClass::Can_Demolish(); } coord_t Hook_Sort_Y() { return FootClass::Sort_Y(); } #endif +#ifdef CHRONOSHIFT_DEBUG +private: + void Debug_Draw_Map(const char *title, cell_t source, cell_t dest/*, BOOL enter_wait_for_input = false, BOOL exit_wait_for_input = false*/); + void Debug_Draw_Path(PathType *path, BOOL draw_tactical = false); + void Debug_Plot_Cell(cell_t cell, BOOL a2 = false, int threat_state = -1, uint8_t color = COLOR_TBLACK); + void Debug_Print_Steps(const char *text, int score, int steps); +#endif + protected: #ifndef CHRONOSHIFT_NO_BITFIELDS BOOL m_Bit1_1 : 1; // 1 diff --git a/src/game/engine/gamekeyboard.cpp b/src/game/engine/gamekeyboard.cpp index 79f54999..50535d1f 100644 --- a/src/game/engine/gamekeyboard.cpp +++ b/src/game/engine/gamekeyboard.cpp @@ -113,11 +113,13 @@ void Debug_Keyboard_Process(KeyNumType &key) g_ChronalVortex.Set_Target(nullptr); Sound_Effect(VOC_TESLA1, coord); _vortex_active = true; + Session.Get_Messages().Add_Simple_Message("Debug", "Spawned chronal vortex.", PLAYER_COLOR_LIGHT_BLUE); } } else { g_ChronalVortex.Set_Target(nullptr); g_ChronalVortex.Disappear(); _vortex_active = false; + Session.Get_Messages().Add_Simple_Message("Debug", "Chronal vortex removed.", PLAYER_COLOR_LIGHT_BLUE); } key = KN_NONE; } @@ -131,6 +133,7 @@ void Debug_Keyboard_Process(KeyNumType &key) if (justkey == Options.Get_DebugKeyRandomCrate()) { Map.Place_Random_Crate(); + Session.Get_Messages().Add_Simple_Message("Debug", "Placed random crate.", PLAYER_COLOR_LIGHT_BLUE); key = KN_NONE; } @@ -203,11 +206,62 @@ void Debug_Keyboard_Process(KeyNumType &key) if (justkey == Options.Get_DebugKeyNavList()) { g_Debug_NavList = !g_Debug_NavList; + Session.Get_Messages().Add_Simple_Message("Debug", g_Debug_NavList ? "NavList debug lines enabled." : "NavList debug lines disabled.", PLAYER_COLOR_LIGHT_BLUE); + key = KN_NONE; + } + + if (justkey == Options.Get_DebugKeyHeadTo()) { + g_Debug_HeadTo = !g_Debug_HeadTo; + Session.Get_Messages().Add_Simple_Message("Debug", g_Debug_HeadTo ? "HeadTo debug lines enabled." : "HeadTo debug lines disabled.", PLAYER_COLOR_LIGHT_BLUE); + key = KN_NONE; + } + + if (justkey == Options.Get_DebugKeyNavCom()) { + g_Debug_NavCom = !g_Debug_NavCom; + Session.Get_Messages().Add_Simple_Message("Debug", g_Debug_NavCom ? "NavCom debug lines enabled." : "NavCom debug lines disabled.", PLAYER_COLOR_LIGHT_BLUE); + key = KN_NONE; + } + + if (justkey == Options.Get_DebugKeyTarCom()) { + g_Debug_TarCom = !g_Debug_TarCom; + Session.Get_Messages().Add_Simple_Message("Debug", g_Debug_TarCom ? "TarCom debug lines enabled." : "TarCom debug lines disabled.", PLAYER_COLOR_LIGHT_BLUE); key = KN_NONE; } if (justkey == Options.Get_DebugKeyFindPath()) { - g_Debug_Find_Path = !g_Debug_Find_Path; + static bool _debug_find_path = true; + DEBUG_LOG("Key DebugKeyFindPath pressed.\n"); + if (_debug_find_path) { + ++g_Debug_Find_Path_Mode; + if (g_Debug_Find_Path_Mode >= DEBUG_PATH_COUNT) { + g_Debug_Find_Path_Mode = DEBUG_PATH_NONE; + _debug_find_path = false; + } + switch (g_Debug_Find_Path_Mode) { + default: + Session.Get_Messages().Add_Simple_Message("Debug", "Find path debug disabled.", PLAYER_COLOR_LIGHT_BLUE); + break; + case DEBUG_PATH_AI: + Session.Get_Messages().Add_Simple_Message("Debug", "Find path debug mode is AI only.", PLAYER_COLOR_LIGHT_BLUE); + break; + case DEBUG_PATH_PLAYER: + Session.Get_Messages().Add_Simple_Message("Debug", "Find path debug mode is PLAYER only.", PLAYER_COLOR_LIGHT_BLUE); + break; + case DEBUG_PATH_BOTH: + Session.Get_Messages().Add_Simple_Message("Debug", "Find path debug mode is both AI and PLAYER.", PLAYER_COLOR_LIGHT_BLUE); + break; + } + } else { + _debug_find_path = true; + g_Debug_Find_Path_Mode = DEBUG_PATH_NONE; + } + key = KN_NONE; + } + + if (justkey == Options.Get_DebugKeyDrawPaths()) { + DEBUG_LOG("Key DebugKeyDrawPaths pressed.\n"); + g_Debug_Draw_Paths = !g_Debug_Draw_Paths; + Session.Get_Messages().Add_Simple_Message("Debug", g_Debug_Draw_Paths ? "Draw paths enabled." : "Draw paths disabled.", PLAYER_COLOR_LIGHT_BLUE); key = KN_NONE; } @@ -217,10 +271,12 @@ void Debug_Keyboard_Process(KeyNumType &key) } if (justkey == Options.Get_DebugKeyPrevMonoPage()) { + Session.Get_Messages().Add_Simple_Message("Debug", "Previous mono page.", PLAYER_COLOR_LIGHT_BLUE); key = KN_NONE; } if (justkey == Options.Get_DebugKeyNextMonoPage()) { + Session.Get_Messages().Add_Simple_Message("Debug", "Previous next page.", PLAYER_COLOR_LIGHT_BLUE); key = KN_NONE; } @@ -264,7 +320,10 @@ void Debug_Keyboard_Process(KeyNumType &key) /*UnitClass *uptr = new UnitClass(UNIT_MCV, g_PlayerPtr->What_Type()); DEBUG_ASSERT(uptr != nullptr); if ( uptr != nullptr ) { - uptr->Unlimbo(Map.Pixel_To_Coord(g_wwmouse->Get_Mouse_X(), g_wwmouse->Get_Mouse_Y())); + uptr->Unlimbo(coord); + char textbuff[32]; + snprintf(textbuff, sizeof(textbuff), "Spawned MCV at Coord:%d,%d", Coord_Lepton_X(coord), Coord_Lepton_Y(coord)); + Session.Get_Messages().Add_Simple_Message("Debug", textbuff, PLAYER_COLOR_LIGHT_BLUE); }*/ } key = KN_NONE; @@ -277,7 +336,7 @@ void Debug_Keyboard_Process(KeyNumType &key) /*UnitClass *uptr = new UnitClass(UNIT_HARVESTER, g_PlayerPtr->What_Type()); DEBUG_ASSERT(uptr != nullptr); if ( uptr != nullptr ) { - uptr->Unlimbo(Map.Pixel_To_Coord(g_wwmouse->Get_Mouse_X(), g_wwmouse->Get_Mouse_Y())); + uptr->Unlimbo(coord); }*/ } key = KN_NONE; @@ -371,8 +430,11 @@ void Debug_Keyboard_Process(KeyNumType &key) DEBUG_ASSERT(objptr != nullptr); if (objptr != nullptr) { if (objptr->Is_Active() && !objptr->In_Limbo()) { + const char *obj_name = objptr->Name(); delete objptr; - Session.Get_Messages().Add_Simple_Message("Debug", "Object deleted!", PLAYER_COLOR_LIGHT_BLUE); + char textbuff[32]; + snprintf(textbuff, sizeof(textbuff), "Object '%s' deleted!", obj_name); + Session.Get_Messages().Add_Simple_Message("Debug", textbuff, PLAYER_COLOR_LIGHT_BLUE); } } } @@ -401,7 +463,7 @@ void Debug_Keyboard_Process(KeyNumType &key) RawFileClass scrnfile(filename); Write_PCX_File(scrnfile, temp_page, GamePalette); char buffer[256]; - snprintf(buffer, sizeof(buffer), "Screenshot Saved! (%s in your user home directory))", filename); + snprintf(buffer, sizeof(buffer), "Screenshot Saved (%s in your user home directory))", filename); Session.Get_Messages().Add_Simple_Message("System", buffer, PLAYER_COLOR_LIGHT_BLUE); key = KN_NONE; } @@ -425,7 +487,8 @@ void Debug_Keyboard_Process(KeyNumType &key) g_PlayerPtr->Special_Weapons(SPECIAL_SONAR_PULSE).Enable(true); g_PlayerPtr->Special_Weapons(SPECIAL_SONAR_PULSE).Forced_Charge(); Map.Add(RTTI_SPECIAL, SPECIAL_SONAR_PULSE); - // Map.Right_Strip_Flag_To_Redraw(); + Session.Get_Messages().Add_Simple_Message("Debug", "Granted SONAR_PULSE special.", PLAYER_COLOR_LIGHT_BLUE); + //Map.Right_Strip_Flag_To_Redraw(); key = KN_NONE; } @@ -433,7 +496,8 @@ void Debug_Keyboard_Process(KeyNumType &key) g_PlayerPtr->Special_Weapons(SPECIAL_ATOM_BOMB).Enable(true); g_PlayerPtr->Special_Weapons(SPECIAL_ATOM_BOMB).Forced_Charge(); Map.Add(RTTI_SPECIAL, SPECIAL_ATOM_BOMB); - // Map.Right_Strip_Flag_To_Redraw(); + Session.Get_Messages().Add_Simple_Message("Debug", "Granted ATOM_BOMB special.", PLAYER_COLOR_LIGHT_BLUE); + //Map.Right_Strip_Flag_To_Redraw(); key = KN_NONE; } @@ -441,7 +505,8 @@ void Debug_Keyboard_Process(KeyNumType &key) g_PlayerPtr->Special_Weapons(SPECIAL_WARP_SPHERE).Enable(true); g_PlayerPtr->Special_Weapons(SPECIAL_WARP_SPHERE).Forced_Charge(); Map.Add(RTTI_SPECIAL, SPECIAL_WARP_SPHERE); - // Map.Right_Strip_Flag_To_Redraw(); + Session.Get_Messages().Add_Simple_Message("Debug", "Granted WARP_SPHERE special.", PLAYER_COLOR_LIGHT_BLUE); + //Map.Right_Strip_Flag_To_Redraw(); key = KN_NONE; } @@ -449,7 +514,8 @@ void Debug_Keyboard_Process(KeyNumType &key) g_PlayerPtr->Special_Weapons(SPECIAL_PARA_BOMB).Enable(true); g_PlayerPtr->Special_Weapons(SPECIAL_PARA_BOMB).Forced_Charge(); Map.Add(RTTI_SPECIAL, SPECIAL_PARA_BOMB); - // Map.Right_Strip_Flag_To_Redraw(); + Session.Get_Messages().Add_Simple_Message("Debug", "Granted PARA_BOMB special.", PLAYER_COLOR_LIGHT_BLUE); + //Map.Right_Strip_Flag_To_Redraw(); key = KN_NONE; } @@ -457,7 +523,8 @@ void Debug_Keyboard_Process(KeyNumType &key) g_PlayerPtr->Special_Weapons(SPECIAL_PARA_INFANTRY).Enable(true); g_PlayerPtr->Special_Weapons(SPECIAL_PARA_INFANTRY).Forced_Charge(); Map.Add(RTTI_SPECIAL, SPECIAL_PARA_INFANTRY); - // Map.Right_Strip_Flag_To_Redraw(); + Session.Get_Messages().Add_Simple_Message("Debug", "Granted PARA_INFANTRY special.", PLAYER_COLOR_LIGHT_BLUE); + //Map.Right_Strip_Flag_To_Redraw(); key = KN_NONE; } @@ -465,7 +532,9 @@ void Debug_Keyboard_Process(KeyNumType &key) g_PlayerPtr->Special_Weapons(SPECIAL_SPY_PLANE).Enable(true); g_PlayerPtr->Special_Weapons(SPECIAL_SPY_PLANE).Forced_Charge(); Map.Add(RTTI_SPECIAL, SPECIAL_SPY_PLANE); - // Map.Right_Strip_Flag_To_Redraw(); + Map.Add(RTTI_SPECIAL, SPECIAL_SPY_PLANE); + Session.Get_Messages().Add_Simple_Message("Debug", "Granted SPY_PLANE special.", PLAYER_COLOR_LIGHT_BLUE); + //Map.Right_Strip_Flag_To_Redraw(); key = KN_NONE; } @@ -473,7 +542,8 @@ void Debug_Keyboard_Process(KeyNumType &key) g_PlayerPtr->Special_Weapons(SPECIAL_IRON_CURTAIN).Enable(true); g_PlayerPtr->Special_Weapons(SPECIAL_IRON_CURTAIN).Forced_Charge(); Map.Add(RTTI_SPECIAL, SPECIAL_IRON_CURTAIN); - // Map.Right_Strip_Flag_To_Redraw(); + Session.Get_Messages().Add_Simple_Message("Debug", "Granted IRON_CURTAIN special.", PLAYER_COLOR_LIGHT_BLUE); + //Map.Right_Strip_Flag_To_Redraw(); key = KN_NONE; } @@ -481,17 +551,20 @@ void Debug_Keyboard_Process(KeyNumType &key) g_PlayerPtr->Special_Weapons(SPECIAL_GPS).Enable(true); g_PlayerPtr->Special_Weapons(SPECIAL_GPS).Forced_Charge(); Map.Add(RTTI_SPECIAL, SPECIAL_GPS); - // Map.Right_Strip_Flag_To_Redraw(); + Session.Get_Messages().Add_Simple_Message("Debug", "Granted GPS special.", PLAYER_COLOR_LIGHT_BLUE); + //Map.Right_Strip_Flag_To_Redraw(); key = KN_NONE; } if (justkey == Options.Get_DebugKeyInstantBuild()) { g_Debug_InstantBuild = !g_Debug_InstantBuild; + Session.Get_Messages().Add_Simple_Message("Debug", g_Debug_InstantBuild ? "Instant build enabled." : "Instant build disabled.", PLAYER_COLOR_LIGHT_BLUE); key = KN_NONE; } if (justkey == Options.Get_DebugKeyBuildCheat()) { g_Debug_BuildCheat = !g_Debug_BuildCheat; + Session.Get_Messages().Add_Simple_Message("Debug", g_Debug_InstantBuild ? "Build cheat enabled." : "Build cheat disabled.", PLAYER_COLOR_LIGHT_BLUE); key = KN_NONE; } @@ -530,15 +603,16 @@ void Debug_Keyboard_Process(KeyNumType &key) if (justkey == Options.Get_DebugKeyStealObject()) { if (CurrentObjects.Count() > 0) { - for (size_t index = 0; index < CurrentObjects.Count(); ++index) { + for (int index = 0; index < CurrentObjects.Count(); ++index) { TechnoClass *objptr = reinterpret_cast(CurrentObjects[index]); DEBUG_ASSERT(objptr != nullptr); if (objptr != nullptr) { if (objptr->Is_Active() && !objptr->In_Limbo()) { if (!objptr->Get_Owner_House()->Is_Player()) { objptr->Captured(g_PlayerPtr); - Session.Get_Messages().Add_Simple_Message( - "Debug", "Captured object!", PLAYER_COLOR_LIGHT_BLUE); + char textbuff[32]; + snprintf(textbuff, sizeof(textbuff), "Captured object '%s'.", objptr->Name()); + Session.Get_Messages().Add_Simple_Message("Debug", textbuff, PLAYER_COLOR_LIGHT_BLUE); } } } @@ -550,17 +624,25 @@ void Debug_Keyboard_Process(KeyNumType &key) if (justkey == Options.Get_DebugKeyToggleDamage()) { g_Debug_Damage = !g_Debug_Damage; + Session.Get_Messages().Add_Simple_Message("Debug", g_Debug_Damage ? "Damage disabled." : "Damage enabled.", PLAYER_COLOR_LIGHT_BLUE); key = KN_NONE; } if (justkey == Options.Get_DebugKeyToggleCloakable()) { if (CurrentObjects.Count() > 0) { - for (size_t index = 0; index < CurrentObjects.Count(); ++index) { + for (int index = 0; index < CurrentObjects.Count(); ++index) { TechnoClass *objptr = reinterpret_cast(CurrentObjects[index]); DEBUG_ASSERT(objptr != nullptr); if (objptr != nullptr) { if (objptr->Is_Active() && !objptr->In_Limbo()) { objptr->Set_Cloakable(!objptr->Is_Cloakable()); + char textbuff[32]; + if (objptr->Is_Cloakable()) { + snprintf(textbuff, sizeof(textbuff), "Object '%s' now has cloaking device.", objptr->Name()); + } else { + snprintf(textbuff, sizeof(textbuff), "Object '%s' has had cloaking device removed.", objptr->Name()); + } + Session.Get_Messages().Add_Simple_Message("Debug", textbuff, PLAYER_COLOR_LIGHT_BLUE); } } } @@ -570,13 +652,16 @@ void Debug_Keyboard_Process(KeyNumType &key) if (justkey == Options.Get_DebugKeyApplyDamage()) { if (CurrentObjects.Count() > 0) { - for (size_t index = 0; index < CurrentObjects.Count(); ++index) { + for (int index = 0; index < CurrentObjects.Count(); ++index) { TechnoClass *objptr = reinterpret_cast(CurrentObjects[index]); DEBUG_ASSERT(objptr != nullptr); if (objptr != nullptr) { if (objptr->Is_Active() && !objptr->In_Limbo()) { int damage = 50; objptr->Take_Damage(damage, 0, WARHEAD_SA); + char textbuff[32]; + snprintf(textbuff, sizeof(textbuff), "Applied damage (WARHEAD_SA, 50) to object '%s'.", objptr->Name()); + Session.Get_Messages().Add_Simple_Message("Debug", textbuff, PLAYER_COLOR_LIGHT_BLUE); } } } @@ -637,6 +722,13 @@ void Keyboard_Process(KeyNumType &key) KeyNumType justkey = (KeyNumType)(key & ~(KEY_SHIFT_BIT | KEY_CTRL_BIT | KEY_ALT_BIT | KEY_VK_BIT)); KeyNumType keynum = (KeyNumType)(key & ~(KEY_VK_BIT)); + // skip all mouse input. + if (key == KN_LMOUSE /*|| key == KN_MMOUSE*/ || key == KN_RMOUSE) { + return; + } + + DEBUG_LOG("Keyboard_Process(enter)\n"); + if (justkey == Options.Get_KeyEditorToggle()) { g_InMapEditor = !g_InMapEditor; key = KN_NONE; diff --git a/src/game/engine/init.cpp b/src/game/engine/init.cpp index 57a97714..0b6f45f3 100644 --- a/src/game/engine/init.cpp +++ b/src/game/engine/init.cpp @@ -438,6 +438,23 @@ void Init_Color_Remaps() GreyScheme.WindowPalette[6] = ColorRemaps[REMAP_5].RemapPalette[g_sysMemPage.Get_Pixel(5, 5)]; GreyScheme.WindowPalette[7] = ColorRemaps[REMAP_5].RemapPalette[g_sysMemPage.Get_Pixel(11, 5)]; + // White Scheme + for (int i = 0; i < 256; ++i ) { + WhiteScheme.RemapPalette[i] = i; + } + + // Write small gradient. + for (int i = 4; i < 10; ++i) { + WhiteScheme.FontPalette[i] = g_sysMemPage.Get_Pixel(1, 10); + } + + WhiteScheme.BrightColor = g_sysMemPage.Get_Pixel(1, 10); + WhiteScheme.MediumColor = g_sysMemPage.Get_Pixel(1, 10); + + for (int i = 0; i < 8; ++i) { + WhiteScheme.WindowPalette[i] = g_sysMemPage.Get_Pixel(1, 10); + } + // Metal Scheme memset(&MetalScheme, 4, sizeof(RemapControlType)); diff --git a/src/game/engine/map.cpp b/src/game/engine/map.cpp index 850095da..19bbb4cb 100644 --- a/src/game/engine/map.cpp +++ b/src/game/engine/map.cpp @@ -365,6 +365,29 @@ cell_t MapClass::Pick_Random_Location() const MapCellX + Scen.Get_Random_Value(0, MapCellWidth - 1), MapCellY + Scen.Get_Random_Value(0, MapCellHeight - 1)); } +/** +* @brief Check if a location is within the visable map. +* +*/ +BOOL MapClass::In_Visible_Map(cell_t cellnum) const +{ + + if (cellnum <= MAP_MAX_AREA) { + if (In_Radar(cellnum)) { + + int cell_x = Cell_Get_X(cellnum); + int cell_y = Cell_Get_Y(cellnum); + + if (((unsigned)cell_x >= (unsigned)MapCellX && (unsigned)cell_x <= (unsigned)MapCellX + (unsigned)MapCellWidth) + && ((unsigned)cell_y >= (unsigned)MapCellY && (unsigned)cell_x <= (unsigned)MapCellY + (unsigned)MapCellHeight)) { + return true; + } + } + } + + return false; +} + /** * @brief Check if a location is within the playable map. * diff --git a/src/game/engine/map.h b/src/game/engine/map.h index 314d3b3f..62c9cf10 100644 --- a/src/game/engine/map.h +++ b/src/game/engine/map.h @@ -56,6 +56,7 @@ class MapClass : public GameScreenClass BOOL Place_Random_Crate_At_Cell(cell_t cellnum); BOOL Remove_Crate(cell_t cellnum); cell_t Pick_Random_Location() const; + BOOL In_Visible_Map(cell_t cellnum) const; BOOL In_Radar(cell_t cellnum) const; cell_t Clamp_To_Radar(cell_t cellnum) const; void Sight_From(cell_t cellnum, int radius, HouseClass *house, BOOL a4); diff --git a/src/game/engine/object.cpp b/src/game/engine/object.cpp index abedd14d..fed6bdf7 100644 --- a/src/game/engine/object.cpp +++ b/src/game/engine/object.cpp @@ -27,6 +27,7 @@ #include "tracker.h" #include "foot.h" #include "target.h" +#include "display.h" #include #ifndef GAME_DLL @@ -278,10 +279,6 @@ BOOL ObjectClass::Paradrop(coord_t coord) BOOL ObjectClass::Render(BOOL force_render) { -/*#ifdef GAME_DLL - BOOL(*func)(ObjectClass *, BOOL) = reinterpret_cast(0x0051DD34); - return func(this, force_render); -#else*/ DEBUG_ASSERT(m_IsActive); coord_t render_coord = Render_Coord(); @@ -307,158 +304,146 @@ BOOL ObjectClass::Render(BOOL force_render) Draw_It(render_x_pos, render_y_pos, WINDOW_TACTICAL); - //if (/*g_Debug_Head_To*/) { +#ifdef CHRONOSHIFT_DEBUG + if (m_Selected) { - if (m_Selected) { + int pixel_size = 2; // Pixel plot size. - if (Is_Foot()) { + // TODO: Move these to FootClass::Render() standalone. + if (g_Debug_Draw_Paths) { + if (Is_Foot()) { FootClass *foot_thisptr = reinterpret_cast(this); - if (foot_thisptr->Head_To()) { - int my_x_pos = 0; - int my_y_pos = 0; + if (foot_thisptr->Get_Path_Facing(0) != FACING_NONE) { - int headto_x_pos = 0; - int headto_y_pos = 0; + int my_x_pos = 0; + int my_y_pos = 0; - int pixel_size = 3; + int prev_cell_x_pos = 0; + int prev_cell_y_pos = 0; - // Draw object coord pixel. - Map.Coord_To_Pixel(foot_thisptr->m_Coord, my_x_pos, my_y_pos); - my_y_pos += 16; - g_logicPage->Put_Fat_Pixel(my_x_pos - 1, my_y_pos - 1, pixel_size, COLOR_YELLOW); + int cell_x_pos = 0; + int cell_y_pos = 0; - // Draw HeadTo coord pixel. - Map.Coord_To_Pixel(foot_thisptr->Head_To(), headto_x_pos, headto_y_pos); - headto_y_pos += 16; - g_logicPage->Put_Fat_Pixel(headto_x_pos - 1, headto_y_pos - 1, pixel_size, COLOR_YELLOW); + for (int index = 0; index < FootClass::Max_Path_Length() && foot_thisptr->Get_Path_Facing(index) != FACING_NONE; ++index) { - // Draw connection line. - g_logicPage->Draw_Line(my_x_pos, my_y_pos, headto_x_pos, headto_y_pos, COLOR_YELLOW); - - //Map.Flag_To_Redraw(true); + FacingType path_facing = foot_thisptr->Get_Path_Facing(index); + cell_t nextcell = Coord_Get_Adjacent(foot_thisptr->Head_To(), path_facing); + coord_t nextcell_coord = Cell_To_Coord(nextcell); - } + if (Map.Coord_To_Pixel(nextcell_coord, cell_x_pos, cell_y_pos) ) { + cell_y_pos += 16; + //debug_layer.Put_Fat_Pixel(cell_x_pos - 2, cell_y_pos - 2, pixel_size, COLOR_PINK); + g_visiblePage.Draw_Line(prev_cell_x_pos, prev_cell_y_pos, cell_x_pos, cell_y_pos, COLOR_PINK); + } - } + prev_cell_x_pos = cell_x_pos; + prev_cell_y_pos = cell_y_pos; - } + /*if (Map.Coord_To_Pixel(foot_thisptr->Center_Coord(), prev_cell_x_pos, prev_cell_y_pos)) { + prev_cell_y_pos += 16; + g_visiblePage.Put_Fat_Pixel(prev_cell_x_pos - 1, prev_cell_y_pos - 1, pixel_size, COLOR_PINK); + }*/ - //} + } - //if (/*Special.Bit3_1 || g_Debug_Head_To*/) { + //Map.Flag_To_Redraw(true); - if (m_Selected) { + } + } + } + } + if (g_Debug_NavCom) { if (Is_Foot()) { - FootClass *foot_thisptr = reinterpret_cast(this); + if (Target_Legal(foot_thisptr->Nav_Com())) { - if (foot_thisptr->Head_To()) { - - if (foot_thisptr->Get_Path_Facing(0) != FACING_NONE) { - - /*int path_x_pos = 0; - int path_y_pos = 0; - - int path2_x_pos = 0; - int path2_y_pos = 0; - - int pixel_size = 3; - - for (int index = 0; index < ARRAY_SIZE(foot_thisptr->m_Paths); ++index) { - - if (foot_thisptr->m_Paths[index] == FACING_NONE) { - break; - } - - cell_t adjcell = Coord_To_Cell(foot_thisptr->Head_To()) + AdjacentCell[foot_thisptr->m_Paths[index]]; - coord_t coord = Cell_To_Coord(adjcell); - - if (Map.Coord_To_Pixel(coord, path2_x_pos, path2_y_pos) ) { - - path2_y_pos += 16; - - Fancy_Text_Print() - g_logicPage->Draw_Line(path_x_pos, path_y_pos, path2_x_pos, path2_y_pos, COLOR_YELLOW); - g_logicPage->Put_Fat_Pixel(path2_x_pos - 2, path2_y_pos - 2, pixel_size, COLOR_GREEN); + int my_x_pos = 0; + int my_y_pos = 0; - } + int navcom_x_pos = 0; + int navcom_y_pos = 0; - path_x_pos = path2_x_pos; - path_y_pos = path2_y_pos; + bool coord1_valid = false; + bool coord2_valid = false; - } + coord_t mycoord = foot_thisptr->Center_Coord(); + coord_t navcom_coord = As_Coord(foot_thisptr->Nav_Com()); - Map.Coord_To_Pixel(foot_thisptr->m_Coord, path_x_pos, path_y_pos); + if (Map.Push_Onto_TacMap(mycoord, navcom_coord)) { - path_y_pos += 16; + // Draw object coord pixel only if it is within the viewport. + Map.Coord_To_Pixel(mycoord, my_x_pos, my_y_pos); + my_y_pos += 16; + g_visiblePage.Put_Fat_Pixel(my_x_pos - 1, my_y_pos - 1, pixel_size, COLOR_BLUE); + //coord1_valid = true; - g_logicPage->Put_Fat_Pixel(path_x_pos - 1, path_y_pos - 1, pixel_size, COLOR_PINK);*/ + // Draw NavCom coord pixel only if it is within the viewport. + Map.Coord_To_Pixel(As_Coord(navcom_coord), navcom_x_pos, navcom_y_pos); + navcom_y_pos += 16; + g_visiblePage.Put_Fat_Pixel(navcom_x_pos - 1, navcom_y_pos - 1, pixel_size, COLOR_BLUE); + //coord2_valid = true; - //Map.Flag_To_Redraw(true); + // Draw connection line. + //if (coord1_valid && coord2_valid) { + g_visiblePage.Draw_Line(my_x_pos, my_y_pos, navcom_x_pos, navcom_y_pos, COLOR_BLUE); + //} + Map.Redraw_View(true); + Map.Flag_To_Redraw(true); } - } - } - } - //} - - //if (/*g_Debug_Nav_Com*/) { - - if (m_Selected) { - + if (g_Debug_HeadTo) { if (Is_Foot()) { - FootClass *foot_thisptr = reinterpret_cast(this); - - if (Target_Legal(foot_thisptr->Nav_Com())) { + if (foot_thisptr->Head_To()) { int my_x_pos = 0; int my_y_pos = 0; - int navcom_x_pos = 0; - int navcom_y_pos = 0; + int headto_x_pos = 0; + int headto_y_pos = 0; + + bool coord1_valid = false; + bool coord2_valid = false; - int pixel_size = 3; + coord_t mycoord = foot_thisptr->Center_Coord(); + coord_t headto_coord = As_Coord(foot_thisptr->Head_To()); // Draw object coord pixel. - Map.Coord_To_Pixel(foot_thisptr->m_Coord, my_x_pos, my_y_pos); - my_y_pos += 16; - g_logicPage->Put_Fat_Pixel(my_x_pos - 1, my_y_pos - 1, pixel_size, COLOR_BLUE); + if (Map.Coord_To_Pixel(mycoord, my_x_pos, my_y_pos)) { + my_y_pos += 16; + g_visiblePage.Put_Fat_Pixel(my_x_pos - 1, my_y_pos - 1, pixel_size, COLOR_YELLOW); + coord1_valid = true; + } // Draw HeadTo coord pixel. - Map.Coord_To_Pixel(As_Coord(foot_thisptr->Nav_Com()), navcom_x_pos, navcom_y_pos); - navcom_y_pos += 16; - g_logicPage->Put_Fat_Pixel(navcom_x_pos - 1, navcom_y_pos - 1, pixel_size, COLOR_BLUE); + if (Map.Coord_To_Pixel(headto_coord, headto_x_pos, headto_y_pos)) { + headto_y_pos += 16; + g_visiblePage.Put_Fat_Pixel(headto_x_pos - 1, headto_y_pos - 1, pixel_size, COLOR_YELLOW); + coord2_valid = true; + } // Draw connection line. - g_logicPage->Draw_Line(my_x_pos, my_y_pos, navcom_x_pos, navcom_y_pos, COLOR_BLUE); + if (coord1_valid && coord2_valid) { + g_visiblePage.Draw_Line(my_x_pos, my_y_pos, headto_x_pos, headto_y_pos, COLOR_YELLOW); + } + //Map.Redraw_View(true); //Map.Flag_To_Redraw(true); - } - } - } - //} - - //if (/*g_Debug_Tar_Com*/) { - - if (m_Selected) { - + if (g_Debug_TarCom) { if (Is_Foot()) { - FootClass *foot_thisptr = reinterpret_cast(this); - if (Target_Legal(foot_thisptr->Get_TarCom())) { int my_x_pos = 0; @@ -467,37 +452,44 @@ BOOL ObjectClass::Render(BOOL force_render) int tarcom_x_pos = 0; int tarcom_y_pos = 0; - int pixel_size = 3; + bool coord1_valid = false; + bool coord2_valid = false; + + coord_t mycoord = foot_thisptr->Center_Coord(); + coord_t tarcom_coord = As_Coord(foot_thisptr->Get_TarCom()); // Draw object coord pixel. - Map.Coord_To_Pixel(foot_thisptr->m_Coord, my_x_pos, my_y_pos); - my_y_pos += 16; - g_logicPage->Put_Fat_Pixel(my_x_pos - 1, my_y_pos - 1, pixel_size, COLOR_RED); + if (Map.Coord_To_Pixel(mycoord, my_x_pos, my_y_pos)) { + my_y_pos += 16; + g_visiblePage.Put_Fat_Pixel(my_x_pos - 1, my_y_pos - 1, pixel_size, COLOR_RED); + coord1_valid = true; + } - // Draw HeadTo coord pixel. - Map.Coord_To_Pixel(As_Coord(foot_thisptr->Get_TarCom()), tarcom_x_pos, tarcom_y_pos); - tarcom_y_pos += 16; - g_logicPage->Put_Fat_Pixel(tarcom_x_pos - 1, tarcom_y_pos - 1, pixel_size, COLOR_RED); + // Draw TarCom coord pixel. + if (Map.Coord_To_Pixel(tarcom_coord, tarcom_x_pos, tarcom_y_pos)) { + tarcom_y_pos += 16; + g_visiblePage.Put_Fat_Pixel(tarcom_x_pos - 1, tarcom_y_pos - 1, pixel_size, COLOR_RED); + coord2_valid = true; + } // Draw connection line. - g_logicPage->Draw_Line(my_x_pos, my_y_pos, tarcom_x_pos, tarcom_y_pos, COLOR_RED); + if (coord1_valid && coord2_valid) { + g_visiblePage.Draw_Line(my_x_pos, my_y_pos, tarcom_x_pos, tarcom_y_pos, COLOR_RED); + } + //Map.Redraw_View(true); //Map.Flag_To_Redraw(true); - } - } - } - - //} + } +#endif return true; } return false; -//#endif } const int16_t *ObjectClass::Occupy_List(BOOL a1) const diff --git a/src/game/engine/options.cpp b/src/game/engine/options.cpp index 42f2daa3..6187117e 100644 --- a/src/game/engine/options.cpp +++ b/src/game/engine/options.cpp @@ -40,7 +40,11 @@ KeyNumType OptionsClass::DebugKeyGuardRange = KN_NONE; KeyNumType OptionsClass::DebugKeyWeaponRange = KN_NONE; KeyNumType OptionsClass::DebugKeyAttackFriendlies = KN_NONE; KeyNumType OptionsClass::DebugKeyFindPath = KN_NONE; +KeyNumType OptionsClass::DebugKeyDrawPaths = KN_NONE; KeyNumType OptionsClass::DebugKeyNavList = KN_NONE; +KeyNumType OptionsClass::DebugKeyHeadTo = KN_NONE; +KeyNumType OptionsClass::DebugKeyNavCom = KN_NONE; +KeyNumType OptionsClass::DebugKeyTarCom = KN_NONE; KeyNumType OptionsClass::DebugKeyToggleMono = KN_NONE; KeyNumType OptionsClass::DebugKeyPrevMonoPage = KN_NONE; KeyNumType OptionsClass::DebugKeyNextMonoPage = KN_NONE; @@ -171,7 +175,11 @@ OptionsClass::OptionsClass() : DebugKeyWeaponRange(KN_NONE), DebugKeyAttackFriendlies(KN_NONE), DebugKeyFindPath(KN_NONE), + DebugKeyDrawPaths(KN_NONE), DebugKeyNavList(KN_NONE), + DebugKeyHeadTo(KN_NONE), + DebugKeyNavCom(KN_NONE), + DebugKeyTarCom(KN_NONE), DebugKeyToggleMono(KN_NONE), DebugKeyPrevMonoPage(KN_NONE), DebugKeyNextMonoPage(KN_NONE), @@ -347,6 +355,8 @@ void OptionsClass::Load_Settings() CounterstrikeEnabled = ini.Get_Bool("Expansions", "CounterstrikeEnabled", false); // TODO use variable as default when ctor used. AftermathEnabled = ini.Get_Bool("Expansions", "AftermathEnabled", false); // TODO use variable as default when ctor used. + DEBUG_LOG("OptionsClass::Load_Settings() - Loading hotkeys.\n"); + KeyForceMove1 = ini.Get_KeyNumType("WinHotkeys", "KeyForceMove1", KeyForceMove1); KeyForceMove2 = ini.Get_KeyNumType("WinHotkeys", "KeyForceMove2", KeyForceMove2); KeyForceAttack1 = ini.Get_KeyNumType("WinHotkeys", "KeyForceAttack1", KeyForceAttack1); @@ -400,7 +410,11 @@ void OptionsClass::Load_Settings() KeyEditorToggle = ini.Get_KeyNumType("WinHotkeys", "KeyEditorToggle", KeyEditorToggle); #if defined(CHRONOSHIFT_DEBUG) + DEBUG_LOG("OptionsClass::Load_Settings() - Loading debug hotkeys.\n"); + DebugKeyToggleDebug = ini.Get_KeyNumType("DebugHotkeys", "DebugKeyToggleDebug", DebugKeyToggleDebug); + DEBUG_LOG("OptionsClass::Load_Settings() - DebugKeyToggleDebug is '%d'.\n", DebugKeyToggleDebug); + DebugKeyToggleVortex = ini.Get_KeyNumType("DebugHotkeys", "DebugKeyToggleVortex", DebugKeyToggleVortex); DebugKeyForceRedraw = ini.Get_KeyNumType("DebugHotkeys", "DebugKeyForceRedraw", DebugKeyForceRedraw); DebugKeyRandomCrate = ini.Get_KeyNumType("DebugHotkeys", "DebugKeyRandomCrate", DebugKeyRandomCrate); @@ -417,7 +431,11 @@ void OptionsClass::Load_Settings() DebugKeyWeaponRange = ini.Get_KeyNumType("DebugHotkeys", "DebugKeyWeaponRange", DebugKeyWeaponRange); DebugKeyAttackFriendlies = ini.Get_KeyNumType("DebugHotkeys", "DebugKeyAttackFriendlies", DebugKeyAttackFriendlies); DebugKeyFindPath = ini.Get_KeyNumType("DebugHotkeys", "DebugKeyFindPath", DebugKeyFindPath); + DebugKeyDrawPaths = ini.Get_KeyNumType("DebugHotkeys", "DebugKeyDrawPaths", DebugKeyDrawPaths); DebugKeyNavList = ini.Get_KeyNumType("DebugHotkeys", "DebugKeyNavList", DebugKeyNavList); + DebugKeyHeadTo = ini.Get_KeyNumType("DebugHotkeys", "DebugKeyHeadTo", DebugKeyHeadTo); + DebugKeyNavCom = ini.Get_KeyNumType("DebugHotkeys", "DebugKeyNavCom", DebugKeyNavCom); + DebugKeyTarCom = ini.Get_KeyNumType("DebugHotkeys", "DebugKeyTarCom", DebugKeyTarCom); DebugKeyToggleMono = ini.Get_KeyNumType("DebugHotkeys", "DebugKeyToggleMono", DebugKeyToggleMono); DebugKeyPrevMonoPage = ini.Get_KeyNumType("DebugHotkeys", "DebugKeyPrevMonoPage", DebugKeyPrevMonoPage); DebugKeyNextMonoPage = ini.Get_KeyNumType("DebugHotkeys", "DebugKeyNextMonoPage", DebugKeyNextMonoPage); diff --git a/src/game/engine/options.h b/src/game/engine/options.h index 793e56e6..9215d6da 100644 --- a/src/game/engine/options.h +++ b/src/game/engine/options.h @@ -146,7 +146,11 @@ class OptionsClass KeyNumType Get_DebugKeyWeaponRange() const { return DebugKeyWeaponRange; } KeyNumType Get_DebugKeyAttackFriendlies() const { return DebugKeyAttackFriendlies; } KeyNumType Get_DebugKeyFindPath() const { return DebugKeyFindPath; } + KeyNumType Get_DebugKeyDrawPaths() const { return DebugKeyDrawPaths; } KeyNumType Get_DebugKeyNavList() const { return DebugKeyNavList; } + KeyNumType Get_DebugKeyHeadTo() const { return DebugKeyHeadTo; } + KeyNumType Get_DebugKeyNavCom() const { return DebugKeyNavCom; } + KeyNumType Get_DebugKeyTarCom() const { return DebugKeyTarCom; } KeyNumType Get_DebugKeyToggleMono() const { return DebugKeyToggleMono; } KeyNumType Get_DebugKeyPrevMonoPage() const { return DebugKeyPrevMonoPage; } KeyNumType Get_DebugKeyNextMonoPage() const { return DebugKeyNextMonoPage; } @@ -290,7 +294,11 @@ class OptionsClass static KeyNumType DebugKeyWeaponRange; static KeyNumType DebugKeyAttackFriendlies; static KeyNumType DebugKeyFindPath; + static KeyNumType DebugKeyDrawPaths; static KeyNumType DebugKeyNavList; + static KeyNumType DebugKeyHeadTo; + static KeyNumType DebugKeyNavCom; + static KeyNumType DebugKeyTarCom; static KeyNumType DebugKeyToggleMono; static KeyNumType DebugKeyPrevMonoPage; static KeyNumType DebugKeyNextMonoPage; @@ -347,7 +355,11 @@ class OptionsClass KeyNumType DebugKeyWeaponRange; KeyNumType DebugKeyAttackFriendlies; KeyNumType DebugKeyFindPath; + KeyNumType DebugKeyDrawPaths; KeyNumType DebugKeyNavList; + KeyNumType DebugKeyHeadTo; + KeyNumType DebugKeyNavCom; + KeyNumType DebugKeyTarCom; KeyNumType DebugKeyToggleMono; KeyNumType DebugKeyPrevMonoPage; KeyNumType DebugKeyNextMonoPage; diff --git a/src/game/platform/keyboard.cpp b/src/game/platform/keyboard.cpp index 9d91c0a0..a9ee69e1 100644 --- a/src/game/platform/keyboard.cpp +++ b/src/game/platform/keyboard.cpp @@ -15,6 +15,7 @@ */ #include "keyboard.h" #include "gamedebug.h" +#include "ostimer.h" #include using std::memset; @@ -395,6 +396,14 @@ uint16_t KeyboardClass::Buff_Get() return key_val; } +void KeyboardClass::Wait_For_Input(KeyNumType key) +{ + // wait until the user has hit the desired key. + while (g_keyboard->Get() != key) { + PlatformTimer->Sleep(1); + } +} + BOOL KeyboardClass::Is_Buffer_Full() const { return (m_ElementPutPos + 1) % KEYBOARD_BUFFER_SIZE == m_ElementGetPos; diff --git a/src/game/platform/keyboard.h b/src/game/platform/keyboard.h index abf330ca..aa420c8d 100644 --- a/src/game/platform/keyboard.h +++ b/src/game/platform/keyboard.h @@ -346,6 +346,7 @@ class KeyboardClass KeyASCIIType To_ASCII(uint16_t keycode); BOOL Down(uint16_t keycode); BOOL Up(uint16_t keycode); + void Wait_For_Input(KeyNumType key); void Clear(); void Set_Initialised(BOOL initialised) { m_Initialised = initialised; } int Get_MouseQX() { return m_MouseQX; }