303 lines
9.2 KiB
C
303 lines
9.2 KiB
C
|
/*
|
||
|
** Command & Conquer Renegade(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/>.
|
||
|
*/
|
||
|
|
||
|
/***********************************************************************************************
|
||
|
*** 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 : Combat *
|
||
|
* *
|
||
|
* $Archive:: /Commando/Code/Combat/mapmgr.h $*
|
||
|
* *
|
||
|
* Author:: Patrick Smith *
|
||
|
* *
|
||
|
* $Modtime:: 1/10/02 10:31a $*
|
||
|
* *
|
||
|
* $Revision:: 8 $*
|
||
|
* *
|
||
|
*---------------------------------------------------------------------------------------------*
|
||
|
* Functions: *
|
||
|
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||
|
|
||
|
#if defined(_MSC_VER)
|
||
|
#pragma once
|
||
|
#endif
|
||
|
|
||
|
#ifndef __MAP_MGR_H
|
||
|
#define __MAP_MGR_H
|
||
|
|
||
|
#include "vector2.h"
|
||
|
#include "vector3.h"
|
||
|
#include "wwstring.h"
|
||
|
#include "bittype.h"
|
||
|
#include "saveloadsubsystem.h"
|
||
|
#include "combatchunkid.h"
|
||
|
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////
|
||
|
// Global singleton instance
|
||
|
///////////////////////////////////////////////////////////////////////
|
||
|
extern class MapMgrClass _TheMapMgrSaveLoadSubsystem;
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// MapMgrClass
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////
|
||
|
class MapMgrClass : public SaveLoadSubSystemClass
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
////////////////////////////////////////////////////////////////
|
||
|
// Public constants
|
||
|
////////////////////////////////////////////////////////////////
|
||
|
enum
|
||
|
{
|
||
|
CLOUD_WIDTH = 20,
|
||
|
CLOUD_HEIGHT = 20,
|
||
|
CLOUD_VECTOR_SIZE = ((CLOUD_WIDTH * CLOUD_HEIGHT) / 32) + 1,
|
||
|
};
|
||
|
|
||
|
////////////////////////////////////////////////////////////////
|
||
|
// Public methods
|
||
|
////////////////////////////////////////////////////////////////
|
||
|
|
||
|
//
|
||
|
// This is the texture that will be used to display the map
|
||
|
//
|
||
|
static void Set_Map_Texture (const char *filename);
|
||
|
static void Get_Map_Texture_Filename (StringClass &filename);
|
||
|
static const char * Get_Map_Texture_Pathname (void) { return MapTextureName; }
|
||
|
|
||
|
//
|
||
|
// Map centering and scale.
|
||
|
//
|
||
|
// Note: The scale means "how many pixels (of map) per meter (of world space)".
|
||
|
// This value can differ in the X and Y axes.
|
||
|
//
|
||
|
// The map center is the pixel position (x,y) where world space (0, 0, 0) is.
|
||
|
//
|
||
|
|
||
|
static const Vector2 & Get_Map_Scale (void) { return MapScale; }
|
||
|
static void Set_Map_Scale (const Vector2 &scale) { MapScale = scale; }
|
||
|
|
||
|
static const Vector2 & Get_Map_Center (void) { return MapCenterPoint; }
|
||
|
static void Set_Map_Center (const Vector2 &pos) { MapCenterPoint = pos; }
|
||
|
|
||
|
//
|
||
|
// Cloud support
|
||
|
//
|
||
|
static void Clear_Cloud_Cell (const Vector3 &pos);
|
||
|
static void Clear_Cloud_Cells (const Vector3 &pos, int pixel_radius);
|
||
|
static void Clear_Cloud_Cell (int x_pos, int y_pos);
|
||
|
static void Clear_Cloud_Cell_By_Pixel (int x_pos, int y_pos);
|
||
|
static void Clear_All_Cloud_Cells (void) { ::memset (CloudVector, 0, sizeof (CloudVector)); }
|
||
|
static void Cloud_All_Cells (void) { ::memset (CloudVector, 0xFF, sizeof (CloudVector)); }
|
||
|
static bool Is_Cell_Visible (int x_pos, int y_pos);
|
||
|
|
||
|
//
|
||
|
// VTOL Support. Some maps do not support VTOL aircraft.
|
||
|
//
|
||
|
static void Enable_VTOL_Vehicles(bool onoff) { EnableVTOL = onoff; }
|
||
|
static bool Are_VTOL_Vehicles_Enabled(void) { return EnableVTOL; }
|
||
|
|
||
|
//
|
||
|
// From SaveLoadSubSystemClass
|
||
|
//
|
||
|
uint32 Chunk_ID (void) const { return CHUNKID_MAPMGR; }
|
||
|
|
||
|
//
|
||
|
// Title support
|
||
|
//
|
||
|
static void Set_Map_Title (int string_id) { MapTitleID = string_id; }
|
||
|
static int Get_Map_Title (void) { return MapTitleID; }
|
||
|
|
||
|
//
|
||
|
// Player marker control
|
||
|
//
|
||
|
static bool Is_Player_Marker_Visible (void) { return IsPlayerMarkerVisible; }
|
||
|
static void Show_Player_Marker (bool onoff) { IsPlayerMarkerVisible = onoff; }
|
||
|
|
||
|
protected:
|
||
|
|
||
|
//
|
||
|
// From SaveLoadSubSystemClass
|
||
|
//
|
||
|
bool Save (ChunkSaveClass &csave);
|
||
|
bool Load (ChunkLoadClass &cload);
|
||
|
void On_Post_Load (void);
|
||
|
const char * Name (void) const { return "MapMgrClass"; }
|
||
|
|
||
|
//
|
||
|
// Save load support
|
||
|
//
|
||
|
void Load_Variables (ChunkLoadClass &cload);
|
||
|
|
||
|
private:
|
||
|
|
||
|
////////////////////////////////////////////////////////////////
|
||
|
// Private member data
|
||
|
////////////////////////////////////////////////////////////////
|
||
|
static bool IsPlayerMarkerVisible;
|
||
|
static int MapTitleID;
|
||
|
static StringClass MapTextureName;
|
||
|
static Vector2 MapCenterPoint;
|
||
|
static Vector2 MapScale;
|
||
|
static Vector2 MapSize;
|
||
|
static uint32 CloudVector[CLOUD_VECTOR_SIZE];
|
||
|
static bool EnableVTOL;
|
||
|
};
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////
|
||
|
// Clear_Cloud_Cell
|
||
|
////////////////////////////////////////////////////////////////
|
||
|
inline void
|
||
|
MapMgrClass::Clear_Cloud_Cell (const Vector3 &pos)
|
||
|
{
|
||
|
if (MapSize.X <= 0 || MapSize.Y <= 0) {
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Calculate where (in map pixels) this position lies
|
||
|
//
|
||
|
float map_x_pos = MapCenterPoint.X + (pos.X * MapScale.X);
|
||
|
float map_y_pos = MapCenterPoint.Y - (pos.Y * MapScale.Y);
|
||
|
|
||
|
//
|
||
|
// Convert this map coordinate into a cell coordinate
|
||
|
//
|
||
|
int cell_x = int((map_x_pos / MapSize.X) * CLOUD_WIDTH);
|
||
|
int cell_y = int((map_y_pos / MapSize.Y) * CLOUD_HEIGHT);
|
||
|
|
||
|
//
|
||
|
// Clamp the cells
|
||
|
//
|
||
|
cell_x = max (cell_x, 0);
|
||
|
cell_y = max (cell_y, 0);
|
||
|
cell_x = min (cell_x, CLOUD_WIDTH - 1);
|
||
|
cell_y = min (cell_y, CLOUD_HEIGHT - 1);
|
||
|
|
||
|
//
|
||
|
// Determine which bit we need to clear
|
||
|
//
|
||
|
int bit_offset = (cell_y * CLOUD_WIDTH) + cell_x;
|
||
|
int index = bit_offset / 32;
|
||
|
int bit = (bit_offset - (index * 32)) + 1;
|
||
|
|
||
|
//
|
||
|
// Clear the bit
|
||
|
//
|
||
|
CloudVector[index] &= ~(1 << bit);
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////
|
||
|
// Clear_Cloud_Cell
|
||
|
////////////////////////////////////////////////////////////////
|
||
|
inline void
|
||
|
MapMgrClass::Clear_Cloud_Cell (int x_pos, int y_pos)
|
||
|
{
|
||
|
if (MapSize.X <= 0 || MapSize.Y <= 0) {
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Clamp the cells
|
||
|
//
|
||
|
int cell_x = max (x_pos, 0);
|
||
|
int cell_y = max (y_pos, 0);
|
||
|
cell_x = min (x_pos, CLOUD_WIDTH - 1);
|
||
|
cell_y = min (y_pos, CLOUD_HEIGHT - 1);
|
||
|
|
||
|
//
|
||
|
// Determine which bit we need to clear
|
||
|
//
|
||
|
int bit_offset = (cell_y * CLOUD_WIDTH) + cell_x;
|
||
|
int index = bit_offset / 32;
|
||
|
int bit = (bit_offset - (index * 32)) + 1;
|
||
|
|
||
|
//
|
||
|
// Clear the bit
|
||
|
//
|
||
|
CloudVector[index] &= ~(1 << bit);
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////
|
||
|
// Clear_Cloud_Cell_By_Pixel
|
||
|
////////////////////////////////////////////////////////////////
|
||
|
inline void
|
||
|
MapMgrClass::Clear_Cloud_Cell_By_Pixel (int x_pos, int y_pos)
|
||
|
{
|
||
|
if (MapSize.X <= 0 || MapSize.Y <= 0) {
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Convert this map coordinate into a cell coordinate
|
||
|
//
|
||
|
int cell_x = int((x_pos / MapSize.X) * CLOUD_WIDTH);
|
||
|
int cell_y = int((y_pos / MapSize.Y) * CLOUD_HEIGHT);
|
||
|
|
||
|
//
|
||
|
// Clamp the cells
|
||
|
//
|
||
|
cell_x = max (cell_x, 0);
|
||
|
cell_y = max (cell_y, 0);
|
||
|
cell_x = min (cell_x, CLOUD_WIDTH - 1);
|
||
|
cell_y = min (cell_y, CLOUD_HEIGHT - 1);
|
||
|
|
||
|
//
|
||
|
// Determine which bit we need to clear
|
||
|
//
|
||
|
int bit_offset = (cell_y * CLOUD_WIDTH) + cell_x;
|
||
|
int index = bit_offset / 32;
|
||
|
int bit = (bit_offset - (index * 32)) + 1;
|
||
|
|
||
|
//
|
||
|
// Clear the bit
|
||
|
//
|
||
|
CloudVector[index] &= ~(1 << bit);
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////
|
||
|
// Is_Cell_Visible
|
||
|
////////////////////////////////////////////////////////////////
|
||
|
inline bool
|
||
|
MapMgrClass::Is_Cell_Visible (int x_pos, int y_pos)
|
||
|
{
|
||
|
int bit_offset = (y_pos * CLOUD_WIDTH) + x_pos;
|
||
|
int index = bit_offset / 32;
|
||
|
int bit = (bit_offset - (index * 32)) + 1;
|
||
|
|
||
|
//
|
||
|
// Index into the vector to see if this cell is clouded or not
|
||
|
//
|
||
|
return ((CloudVector[index] & (1 << bit)) == 0);
|
||
|
}
|
||
|
|
||
|
#endif //__MAP_MGR_H
|
||
|
|