Added the ability to place new light objects in the world, lights don't work yet.

This commit is contained in:
Justin Marshall
2020-07-11 14:19:34 -07:00
parent 37b8b475c9
commit 3185e48ccd
11 changed files with 274 additions and 37 deletions
+2 -2
View File
@@ -631,7 +631,7 @@ set(src_redalert
./redalert/mapscript.cpp
./redalert/txtprnt.cpp
./redalert/tilesetxml.cpp
"redalert/sidebareditor.cpp")
"redalert/sidebareditor.cpp" "redalert/light.cpp")
set(src_external
#glew
@@ -731,7 +731,7 @@ if (UNIX)
add_definitions(-D RA_AF -DCHEAT_KEYS -DIMGUI_IMPL_OPENGL_LOADER_GLEW -DSCENARIO_EDITOR -DTRUE_FALSE_DEFINED -DENGLISH -D_USRDLL -DREDALERT_EXPORTS)
endif(UNIX)
add_executable(RedAlert ${src_io} ${src_win32lib} ${src_redalert} ${src_external})
add_executable(RedAlert ${src_io} ${src_win32lib} ${src_redalert} ${src_external} "redalert/light.cpp")
if (MSVC)
set_target_properties(RedAlert PROPERTIES OUTPUT_NAME "RedAlert" LINK_FLAGS "/PDB:\"RedAlert.pdb\" /SUBSYSTEM:WINDOWS" RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/../" )
+2
View File
@@ -2230,6 +2230,8 @@ ObjectClass * DisplayClass::Cell_Object(CELL cell, int x, int y) const
HidPage.Unlock();
}
lightManager.RenderLights();
#ifndef WIN32
/*
** Once the icons are drawn, duplicate the bottom line of the screen into the phantom
+1
View File
@@ -234,6 +234,7 @@ struct NoInitClass {
#include "crcstraw.h"
#include "shastraw.h"
#include "rndstraw.h"
#include "light.h"
// Should be part of WWLIB.H. This is used in JSHELL.CPP.
typedef struct {
+129
View File
@@ -0,0 +1,129 @@
// light.cpp
//
#include "function.h"
#include "image.h"
void Light_t::PlaceLight(int screenx, int screeny) {
isPending = false;
COORDINATE lightCoord;
CellClass::ConvertIsoCoordsToScreen(screenx, screeny);
position = Map.Closest_Free_Spot(Map.Pixel_To_Coord(screenx, screeny));
}
bool Light_t::GetRenderPosition(int& x, int& y) {
Map.Coord_To_Pixel(position, x, y);
CellClass::ConvertCoordsToIsometric(x, y);
return true;
}
LightManager lightManager;
LightManager::LightManager() {
FreeAllLights();
}
void LightManager::Init(void) {
lightEditorIcon = Image_LoadImage("ui/edwin/lightbulb.png");
}
void LightManager::RenderLights(void) {
for(int i = 0; i < MAX_WORLD_LIGHTS; i++) {
if (!lights[i].active) {
continue;
}
if(!lights[i].isPending) {
int screenx, screeny;
lights[i].GetRenderPosition(screenx, screeny);
GL_RenderImage(lightEditorIcon, screenx, screeny, 30, 30);
}
}
}
void LightManager::FreeAllLights(void) {
memset(lights, 0, sizeof(lights));
}
Light_t* LightManager::AllocateLight(void) {
for(int i = 0; i < MAX_WORLD_LIGHTS; i++) {
if(!lights[i].active) {
lights[i].active = true;
lights[i].lightNum = i;
return &lights[i];
}
}
assert(!"Too many lights in the scene!");
return NULL;
}
Light_t *LightManager::PlaceLight(char *name, int x, int y, float r, float g, float b, float radius, LightType_t type) {
Light_t* light = AllocateLight();
if(!light) {
return NULL;
}
if(name == NULL) {
sprintf(light->name, "light%d", light->lightNum);
}
else {
strcpy(light->name, name);
}
light->position = XYP_Coord(x, y);
light->color.x = r;
light->color.y = g;
light->color.z = b;
light->radius = radius;
light->type = type;
return light;
}
void LightManager::FreeLight(Light_t* light) {
light->active = false;
}
void LightManager::Write_Scenerio_Lights(CCINIClass* ini) {
ini->Clear("Lights");
// Write out the lights.
for (int i = 0; i < MAX_WORLD_LIGHTS; i++) {
if (lights[i].active == false) {
continue;
}
char buffer[2048];
char name[256];
sprintf(buffer, "%s,%d,%f,%f,%f,%f,%d", lights[i].name, lights[i].position, lights[i].color.x, lights[i].color.y, lights[i].color.z, lights[i].radius, lights[i].type);
sprintf(name, "%d", i);
ini->Put_String("Lights",name,buffer);
}
}
void LightManager::Read_Scenerio_Lights(CCINIClass* ini) {
char buf[2048];
int len = ini->Entry_Count("Lights");
for (int index = 0; index < len; index++) {
char const* entry = ini->Get_Entry("Lights", index);
/*
** Get a lighting entry.
*/
ini->Get_String("Lights", entry, NULL, buf, sizeof(buf));
Light_t* light = AllocateLight();
strcpy(light->name, strtok(buf, ","));
light->position = atoi(strtok(NULL, ","));
light->color.x = atof(strtok(NULL, ","));
light->color.y = atof(strtok(NULL, ","));
light->color.z = atof(strtok(NULL, ","));
light->radius = atof(strtok(NULL, ","));
light->type = (LightType_t)atoi(strtok(NULL, ","));
}
}
+59
View File
@@ -0,0 +1,59 @@
// light.h
//
#include <vector>
#include "vectormath.h"
class CCINIClass;
struct Image_t;
#define MAX_WORLD_LIGHTS 6556
enum LightType_t {
LIGHT_AMBIENT = 0,
LIGHT_POINT,
LIGHT_SPOT
};
class Light_t {
friend class LightManager;
public:
int GetLightNum(void) { return lightNum; }
void PlaceLight(int screenx, int screeny);
bool GetRenderPosition(int& x, int& y);
char name[512];
unsigned long position;
float3 color;
float radius;
bool isPending;
LightType_t type;
protected:
int lightNum;
bool active;
};
class LightManager {
public:
LightManager();
void Init(void);
Light_t* AllocateLight(void);
Light_t* PlaceLight(char *name, int x, int y, float r, float g, float b, float radius, LightType_t type);
void FreeLight(Light_t* light);
void FreeAllLights(void);
void Read_Scenerio_Lights(CCINIClass* ini);
void Write_Scenerio_Lights(CCINIClass* ini);
public:
Image_t* GetLightEditorIcon(void) { return lightEditorIcon; }
void RenderLights(void);
private:
Light_t lights[MAX_WORLD_LIGHTS];
int numLights;
Image_t* lightEditorIcon;
};
extern LightManager lightManager;
+61 -34
View File
@@ -107,6 +107,7 @@ MapEditClass::MapEditClass(void)
// ScenVar = SCEN_VAR_A;
LastHouse = HOUSE_GOOD;
GrabbedObject = 0;
GrabbedLight = nullptr;
Scen.Waypoint[WAYPT_HOME] = 0;
CurrentCell = 0;
CurTeam = NULL;
@@ -545,25 +546,33 @@ void MapEditClass::AI(KeyNumType & input, int x, int y)
rc = Mouse_Moved();
if (Keyboard->Down(KN_LMOUSE) && rc) {
/*
** "Paint" mode: place current object, and restart placement
*/
if (PendingObject) {
Flag_To_Redraw(true);
if (Place_Object() == 0) {
Changed = 1;
Start_Placement();
}
} else {
if (GrabbedLight)
{
GrabbedLight->PlaceLight(Get_Mouse_X(), Get_Mouse_Y());
GrabbedLight = nullptr;
}
else
{
/*
** Move the currently-grabbed object
** "Paint" mode: place current object, and restart placement
*/
if (GrabbedObject) {
GrabbedObject->Mark(MARK_CHANGE);
if (Move_Grabbed_Object() == 0) {
if (PendingObject) {
Flag_To_Redraw(true);
if (Place_Object() == 0) {
Changed = 1;
Start_Placement();
}
}
else {
/*
** Move the currently-grabbed object
*/
if (GrabbedObject) {
GrabbedObject->Mark(MARK_CHANGE);
if (Move_Grabbed_Object() == 0) {
Changed = 1;
}
}
}
}
@@ -1466,27 +1475,40 @@ bool MapEditClass::Mouse_Moved(void)
const ObjectTypeClass * objtype = NULL;
bool retcode = false;
/*
** Return if no motion
*/
if (old_mx == Get_Mouse_X() && old_my == Get_Mouse_Y()) {
return(false);
if (GrabbedLight != NULL)
{
GL_RenderImage(lightManager.GetLightEditorIcon(), Get_Mouse_X(), Get_Mouse_Y(), 32, 32);
old_mx = Get_Mouse_X();
old_my = Get_Mouse_Y();
old_zonecell = ZoneCell;
return true;
}
/*
** Get a ptr to ObjectTypeClass
*/
if (PendingObject) {
objtype = PendingObject;
} else {
if (GrabbedObject) {
objtype = &GrabbedObject->Class_Of();
} else {
old_mx = Get_Mouse_X();
old_my = Get_Mouse_Y();
old_zonecell = ZoneCell;
else
{
/*
** Return if no motion
*/
if (old_mx == Get_Mouse_X() && old_my == Get_Mouse_Y()) {
return(false);
}
/*
** Get a ptr to ObjectTypeClass
*/
if (PendingObject) {
objtype = PendingObject;
}
else {
if (GrabbedObject) {
objtype = &GrabbedObject->Class_Of();
}
else {
old_mx = Get_Mouse_X();
old_my = Get_Mouse_Y();
old_zonecell = ZoneCell;
return(false);
}
}
}
/*
@@ -1659,6 +1681,11 @@ void MapEditClass::Main_Menu(void)
process = false;
break;
case 8:
GrabbedLight = lightManager.PlaceLight(NULL, 0, 0, 1.0f, 1.0f, 1.0f, 100, LIGHT_POINT);
GrabbedLight->isPending = true;
break;
/*
** Test-drive this scenario
*/
+4
View File
@@ -49,6 +49,8 @@
#include <vector>
#include "sidebareditor.h"
class Light_t;
/*
** This is the maximum # of ObjectTypeClasses the editor has to deal with.
*/
@@ -270,6 +272,8 @@ class MapEditClass : public MouseClass
//int LastChoice; // index of item user picked last
HousesType LastHouse; // house of last item picked
Light_t *GrabbedLight;
/*
** Variables for grabbing/moving objects
*/
+5
View File
@@ -820,6 +820,8 @@ void Clear_Scenario(void)
{
// TCTCTC -- possibly just use in-place new of scenario object?
lightManager.FreeAllLights();
Scen.MissionTimer = 0;
Scen.MissionTimer.Stop();
Scen.Timer = 0;
@@ -2289,6 +2291,8 @@ bool Read_Scenario_INI(char * fname, bool )
Scen.IsMoneyTiberium = ini.Get_Bool(BASIC, "FillSilos", Scen.IsMoneyTiberium);
Scen.Percent = ini.Get_Int(BASIC, "Percent", Scen.Percent);
lightManager.Read_Scenerio_Lights(&ini);
/*
** Read in the specific information for each of the house types. This creates
** the houses of different types.
@@ -2659,6 +2663,7 @@ void Write_Scenario_INI(char * fname)
ini.Put_Bool(BASIC, "TruckCrate", Scen.IsTruckCrate);
ini.Put_Int(BASIC, "Percent", Scen.Percent);
lightManager.Write_Scenerio_Lights(&ini);
HouseClass::Write_INI(ini);
TeamTypeClass::Write_INI(ini);
TriggerTypeClass::Write_INI(ini);
+9 -1
View File
@@ -57,7 +57,8 @@ void SidebarEditor::draw_it(void) {
if (ImGui::MenuItem("Scenario Options")) { mainmenu_selection = 5; }
if (ImGui::MenuItem("AI Options")) { mainmenu_selection = 6; }
ImGui::EndMenu();
}
}
if (ImGui::BeginMenu("Objects"))
{
Debug_LockScroll = true;
@@ -65,6 +66,13 @@ void SidebarEditor::draw_it(void) {
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Lights"))
{
Debug_LockScroll = true;
if (ImGui::MenuItem("Add Light")) { mainmenu_selection = 8; }
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Run"))
{
Debug_LockScroll = true;
+2
View File
@@ -859,6 +859,8 @@ void Create_Main_Window ( HANDLE instance , int command_show , int width , int h
io.Fonts->AddFontFromFileTTF("fonts/Arial.ttf", 16.0f);
ImGui_NewFrame();
lightManager.Init();
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB