Merge remote-tracking branch 'origin/master' into liquid_container

liquid_container
Mark 2016-04-03 20:16:55 +02:00
commit 1f303ac331
95 changed files with 2244 additions and 1943 deletions

View File

@ -12,6 +12,11 @@
# for the above references.
cmake_minimum_required (VERSION 3.0.2)
# Don't allow people to build "Release" builds because there's no reason to do that.
# Use one of RelWithDebInfo or MinSizeRel instead.
set(CMAKE_CONFIGURATION_TYPES Debug RelWithDebInfo MinSizeRel CACHE STRING "List of supported configuration types." FORCE)
project (openclonk CXX C)
# CMP0054: Only interpret if() arguments as variables or keywords when unquoted
@ -45,96 +50,116 @@ set_property(GLOBAL PROPERTY USE_FOLDERS ${PROJECT_FOLDERS})
############################################################################
include(CheckCXXCompilerFlag)
set(OC_CXX_FLAGS ${CMAKE_CXX_FLAGS})
separate_arguments(OC_CXX_FLAGS)
set(OC_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
separate_arguments(OC_CXX_FLAGS_DEBUG)
set(OC_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS})
separate_arguments(OC_EXE_LINKER_FLAGS)
set(OC_EXE_LINKER_FLAGS_DEBUG ${CMAKE_EXE_LINKER_FLAGS_DEBUG})
separate_arguments(OC_EXE_LINKER_FLAGS_DEBUG)
CHECK_CXX_COMPILER_FLAG("-std=gnu++14" USE_GCC_STD_14)
if(USE_GCC_STD_14)
list(APPEND OC_CXX_FLAGS "-std=gnu++14")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++14")
endif()
# Enable link-time code generation. We have to do this manually because while
# there is a INTERPROCEDURAL_OPTIMIZATION cmake flag, it's only implemented
# for icc so far; https://cmake.org/Bug/view.php?id=15939
function(add_linker_flags)
include(CMakeParseArguments)
set(options optimized debug)
set(oneValueArgs FLAGS)
set(multiValueArgs MODULES)
cmake_parse_arguments(_alf "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
# Adds some linker flags to all optimized build configurations
set(_configurations "")
if(_alf_optimized)
list(APPEND _configurations MINSIZEREL RELWITHDEBINFO RELEASE)
endif()
if(_alf_debug)
list(APPEND _configurations DEBUG)
endif()
foreach(_module ${_alf_MODULES})
string(TOUPPER "${_module}" _obj_type)
foreach(_config ${_configurations})
set(CMAKE_${_obj_type}_LINKER_FLAGS_${_config} "${CMAKE_${_obj_type}_LINKER_FLAGS_${_config}} ${_alf_FLAGS}" PARENT_SCOPE)
endforeach()
endforeach()
endfunction()
CHECK_CXX_COMPILER_FLAG("-flto" USE_GCC_STYLE_LTCG)
if(USE_GCC_STYLE_LTCG)
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -flto")
set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -flto")
add_linker_flags(optimized MODULES exe shared FLAGS -flto)
# Use GCC's ar and ranlib wrappers if necessary, because the plain ones
# don't understand lto objects without an explicit plugin parameter
if(CMAKE_C_COMPILER MATCHES "gcc$")
set(LTCG_NEEDS_AR_WRAPPER 1)
set(LTCG_AR_WRAPPER_PREFIX "${CMAKE_C_COMPILER}")
elseif(CMAKE_C_COMPILER MATCHES "cc$")
set(LTCG_NEEDS_AR_WRAPPER 1)
set(LTCG_AR_WRAPPER_PREFIX "gcc")
else()
set(LTCG_NEEDS_AR_WRAPPER 0)
endif()
if(LTCG_NEEDS_AR_WRAPPER)
find_program(AR_WRAPPER "${LTCG_AR_WRAPPER_PREFIX}-ar")
if (AR_WRAPPER)
message("Using ${AR_WRAPPER} instead of ${CMAKE_AR} to support lto objects.")
set(CMAKE_AR "${AR_WRAPPER}" CACHE FILEPATH "Path to an ar that supports lto objects." FORCE)
endif()
find_program(RANLIB_WRAPPER "${LTCG_AR_WRAPPER_PREFIX}-ranlib")
if (RANLIB_WRAPPER)
message("Using ${RANLIB_WRAPPER} instead of ${CMAKE_RANLIB} to support lto objects.")
set(CMAKE_RANLIB "${RANLIB_WRAPPER}" CACHE FILEPATH "Path to a ranlib that supports lto objects." FORCE)
endif()
endif()
endif()
if(MSVC)
# Disable non-standard conversion from string literal to (nonconst) char*
list(APPEND OC_CXX_FLAGS /Zc:strictStrings)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zc:strictStrings")
list(APPEND OC_CXX_FLAGS /MP)
list(REMOVE_ITEM OC_CXX_FLAGS_DEBUG /Gm)
# Enable multi-core builds
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
# Enable LTCG for release builds
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Ob2 /GL")
set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} /Ob2 /GL")
add_linker_flags(optimized MODULES exe shared static FLAGS /LTCG)
# Activate edit-and-continue
list(REMOVE_ITEM OC_CXX_FLAGS_DEBUG /Zi)
list(APPEND OC_CXX_FLAGS_DEBUG /ZI /Gy)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /ZI /Gy")
# do not link the release CRT in debug builds
list(APPEND OC_EXE_LINKER_FLAGS_DEBUG "/NODEFAULTLIB:MSVCRT")
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /NODEFAULTLIB:MSVCRT")
set(HAVE_PRECOMPILED_HEADERS ON CACHE INTERNAL "Compiler supports precompiled headers")
# Suppress warnings about "non-secure" functions
add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS)
# Disable warning C4244: 'conversion' conversion from 'type1' to 'type2', possible loss of data
list(APPEND OC_CXX_FLAGS "/wd4244")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4244")
# Disable warning C4267: 'var' : conversion from 'size_t' to 'type', possible loss of data (64 bit build only)
list(APPEND OC_CXX_FLAGS "/wd4267")
endif()
if(CMAKE_COMPILER_IS_GNUCXX)
list(APPEND OC_CXX_FLAGS -Wall -Wextra -Wredundant-decls -Wendif-labels -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -Winit-self -Wsign-promo -Wno-reorder -Wno-unused-parameter -Wnon-virtual-dtor -Woverloaded-virtual)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4267")
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
list(APPEND OC_CXX_FLAGS -Wall -Wextra -Wextra-tokens -Wpointer-arith -Wno-cast-align -Wno-reorder -Wno-unused-parameter -Wnon-virtual-dtor -Woverloaded-virtual)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wextra-tokens -Wpointer-arith -Wno-cast-align -Wno-reorder -Wno-unused-parameter -Wnon-virtual-dtor -Woverloaded-virtual")
elseif(CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wredundant-decls -Wendif-labels -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -Winit-self -Wsign-promo -Wno-reorder -Wno-unused-parameter -Wnon-virtual-dtor -Woverloaded-virtual")
endif()
if(WIN32 AND MINGW)
# Activate DEP and ASLR
list(APPEND OC_EXE_LINKER_FLAGS -Wl,--nxcompat -Wl,--dynamicbase)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--nxcompat -Wl,--dynamicbase")
endif()
if(UNIX)
# Don't put this into CMAKE_CXX_FLAGS because otherwise it is cached,
# and when the path is changed both the old and new definition appears
# in the list of flags.
add_definitions("-DOC_SYSTEM_DATA_DIR=\"${CMAKE_INSTALL_PREFIX}/share/games/openclonk\"")
endif()
if(APPLE)
list(APPEND OC_CXX_FLAGS -fobjc-arc)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fobjc-arc")
endif()
if(OC_CXX_FLAGS)
list(REMOVE_DUPLICATES OC_CXX_FLAGS)
endif()
set(CMAKE_CXX_FLAGS "" CACHE STRING "C++ compiler flags" FORCE)
foreach(FLAG ${OC_CXX_FLAGS})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAG}" CACHE STRING "C++ compiler flags" FORCE)
endforeach()
if(OC_CXX_FLAGS_DEBUG)
list(REMOVE_DUPLICATES OC_CXX_FLAGS_DEBUG)
endif()
set(CMAKE_CXX_FLAGS_DEBUG "" CACHE STRING "Flags used by the compiler during debug builds." FORCE)
foreach(FLAG ${OC_CXX_FLAGS_DEBUG})
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${FLAG}" CACHE STRING "Flags used by the compiler during debug builds." FORCE)
endforeach()
if(OC_EXE_LINKER_FLAGS)
list(REMOVE_DUPLICATES OC_EXE_LINKER_FLAGS)
endif()
set(CMAKE_EXE_LINKER_FLAGS "" CACHE STRING "Flags used by the linker." FORCE)
foreach(FLAG ${OC_EXE_LINKER_FLAGS})
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FLAG}" CACHE STRING "Flags used by the linker." FORCE)
endforeach()
if(OC_EXE_LINKER_FLAGS_DEBUG)
list(REMOVE_DUPLICATES OC_EXE_LINKER_FLAGS_DEBUG)
endif()
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "" CACHE STRING "Flags used by the linker during debug builds." FORCE)
foreach(FLAG ${OC_EXE_LINKER_FLAGS_DEBUG})
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${FLAG}" CACHE STRING "Flags used by the linker during debug builds." FORCE)
endforeach()
############################################################################
# Check for compiler quirks and features
############################################################################
@ -588,7 +613,6 @@ set(OC_CLONK_SOURCES
src/landscape/fow/C4FoWBeamTriangle.h
src/landscape/C4Landscape.cpp
src/landscape/C4Landscape.h
src/landscape/C4LandscapeRenderClassic.cpp
src/landscape/C4LandscapeRender.cpp
src/landscape/C4LandscapeRender.h
src/landscape/C4Map.cpp

View File

@ -8,10 +8,7 @@ func Initialize()
SetProperty("LineColors", [RGB(20, 20, 50), RGB(20, 20, 50)]);
}
public func IsCableLine()
{
return GetAction() == "Connect";
}
public func IsCableLine() { return GetAction() == "Connect"; }
/** Returns whether this cable is connected to an object. */
public func IsConnectedTo(object obj)
@ -19,41 +16,76 @@ public func IsConnectedTo(object obj)
return GetActionTarget(0) == obj || GetActionTarget(1) == obj;
}
/** Returns the object which is connected to obj through this pipe. */
/** Connects this cable to obj1 and obj2. */
public func SetConnectedObjects(obj1, obj2)
{
if (GetActionTarget(0)) GetActionTarget(0)->~CableDeactivation(activations);
if (GetActionTarget(1)) GetActionTarget(1)->~CableDeactivation(activations);
SetVertexXY(0, obj1->GetX(), obj1->GetY());
SetVertexXY(1, obj2->GetX(), obj2->GetY());
SetActionTargets(obj1, obj2);
obj1->AddCableConnection(this);
}
/** Returns the object which is connected to obj through this cable. */
public func GetConnectedObject(object obj)
{
if (GetActionTarget(0) == obj)
return GetActionTarget(1);
if (GetActionTarget(1) == obj)
return GetActionTarget(0);
return;
}
public func SetConnectedObjects(obj1, obj2)
{
SetActionTargets(obj1, obj2);
obj1->AddCableConnection(this);
}
/* Breaking */
protected func LineBreak(bool no_msg)
func LineBreak(bool no_msg)
{
Sound("Objects::Connect");
if (!no_msg)
if (GetActionTarget(0)) GetActionTarget(0)->~CableDeactivation(activations);
if (GetActionTarget(1)) GetActionTarget(1)->~CableDeactivation(activations);
if (!no_msg)
BreakMessage();
return;
}
private func BreakMessage()
func BreakMessage()
{
var line_end = GetActionTarget(0);
if (line_end->GetID() != CableLorryReel)
if (line_end->GetID() != CableLorryReel)
line_end = GetActionTarget(1);
if (line_end->Contained()) line_end = line_end->Contained();
line_end->Message("$TxtLinebroke$");
return;
}
/* Activation */
local activations = 0;
/** Called by cable cars whenever one proceeds onto this cable. Will be forwarded to connected objects.
count increases the activation value. Stations will stop animation only if all activations are deactivated. */
public func Activation(int count)
{
// Count must be > 0
if (count < 1) return FatalError("Cable Line: Activation() was called with count < 1.");
activations += count;
if (GetActionTarget(0)) GetActionTarget(0)->~CableActivation(count);
if (GetActionTarget(1)) GetActionTarget(1)->~CableActivation(count);
}
/** Called by cable cars whenever one proceeds off this cable. Will be forwarded to connected objects.
count decreases the activation value. Stations will stop animation only if all activations are deactivated. */
public func Deactivation(int count)
{
// Count must be > 0
if (count < 1) return FatalError("Cable Line: Deactivation() was called with count < 1.");
activations -= count;
if (GetActionTarget(0)) GetActionTarget(0)->~CableDeactivation(count);
if (GetActionTarget(1)) GetActionTarget(1)->~CableDeactivation(count);
}
/* Saving */
public func SaveScenarioObject(props)
{
if (!inherited(props, ...)) return false;

View File

@ -38,7 +38,7 @@ func Disengaged() {}
func GetCableOffset(array position, int prec) {}
// To add custom interaction menu entries after the regular cable car entries
// custom_entry is prototype for proper spacing of buttons
// custom_entry is a prototype for proper spacing of buttons
// Use priorities > 2000 just to be sure
func GetCableCarExtraMenuEntries(array menu_entries, proplist custom_entry, object clonk) {}
@ -78,6 +78,7 @@ public func DoMovement()
var position = CreateArray(2);
if (lib_ccar_progress >= lib_ccar_max_progress)
{
lib_ccar_rail->~Deactivation(1);
lib_ccar_rail = lib_ccar_rail->GetActionTarget(end);
lib_ccar_rail->GetCablePosition(position);
GetCableOffset(position);
@ -135,13 +136,15 @@ public func GetCableCarMenuEntries(object clonk)
{
BackgroundColor = { Std = 0, Selected = RGB(100, 30, 30) },
OnMouseIn = GuiAction_SetTag("Selected"),
OnMouseOut = GuiAction_SetTag("Std")
OnMouseOut = GuiAction_SetTag("Std"),
Right = "2em"
};
var custom_entry =
{
Right = "3em", Bottom = "2em",
image = { Prototype = control_prototype }
image = { Prototype = control_prototype },
icon = { Left = "2em" }
};
var menu_entries = [];
@ -158,9 +161,10 @@ public func GetCableCarMenuEntries(object clonk)
var engage = new custom_entry {
Priority = 1000 + i,
Tooltip = "$TooltipEngage$",
OnClick = GuiAction_Call(this, "EngageRail", station)
OnClick = GuiAction_Call(this, "EngageRail", station),
image = { Prototype = custom_entry.image, Symbol = station },
icon = { Prototype = custom_entry.icon, Symbol = Icon_LibraryCableCar, GraphicsName = "Engage" }
};
engage.image.Symbol = station;
PushBack(menu_entries, { symbol = station, extra_data = "Engage", custom = engage });
i++;
}
@ -181,10 +185,19 @@ public func GetCableCarMenuEntries(object clonk)
var go = new custom_entry {
Priority = 1000,
Tooltip = "$TooltipGo$",
OnClick = GuiAction_Call(this, "OpenDestinationSelection", clonk)
OnClick = GuiAction_Call(this, "OpenDestinationSelection", clonk),
image = { Prototype = custom_entry.image, Symbol = Icon_Play }
};
go.image.Symbol = Icon_Play;
PushBack(menu_entries, { symbol = this, extra_data = "Go", custom = go });
var disengage = new custom_entry {
Priority = 1001,
Tooltip = "$TooltipDisengage$",
OnClick = GuiAction_Call(this, "DisengageRail"),
image = { Prototype = custom_entry.image, Symbol = GetRailTarget() },
icon = { Prototype = custom_entry.icon, Symbol = Icon_LibraryCableCar, GraphicsName = "Disengage" }
};
PushBack(menu_entries, { symbol = GetRailTarget(), extra_data = "Disengage", custom = disengage });
}
}
// Add custom entries
@ -329,6 +342,7 @@ func MoveTo(dest)
var origin = CreateArray(2), ending = CreateArray(2);
rail->GetActionTarget(0)->GetCablePosition(origin);
rail->GetActionTarget(1)->GetCablePosition(ending);
rail->~Activation(1);
lib_ccar_max_progress = Distance(origin[0], origin[1], ending[0], ending[1]);
lib_ccar_rail = rail;
}

View File

@ -14,6 +14,15 @@
// This function is called whenever a change in the cable network occured, i.e. destinations have been added / removed.
private func DestinationsUpdated() { }
// Called by cable lines whenever a car starts travelling along a connected cable.
// Can be used to start animation or sounds or similar.
// count is a value indicating the amount of activations.
public func CableActivation(int count) { }
// Called likewise as Activation() whenever a car leaves the cable.
// count is a value indicating the amount of deactivations (e.g. a cable with more than one car broke).
public func CableDeactivation(int count) { }
/*--- Callbacks ---*/
// Be sure to always call these via _inherited();

View File

@ -9,6 +9,14 @@
#include Library_CableStation
local turn_anim;
func Initialize()
{
turn_anim = PlayAnimation("Engine", 1, Anim_Const(0), Anim_Const(1000));
return _inherited(...);
}
// Prevents the automatic change of the station status when manually set to station mode
local manual_setting = false;
@ -112,6 +120,22 @@ func CheckStationStatus()
SetMeshMaterial("CableCarStation_Sign", 1);
}
local activations = 0;
func CableActivation(int count)
{
if (activations <= 0)
SetAnimationPosition(turn_anim, Anim_Linear(GetAnimationPosition(turn_anim), 0, GetAnimationLength("Engine"), 175, ANIM_Loop));
activations += count;
}
func CableDeactivation(int count)
{
activations -= count;
if (activations <= 0)
SetAnimationPosition(turn_anim, Anim_Const(GetAnimationPosition(turn_anim)));
}
public func NoConstructionFlip() { return true; }
/* Saving */

View File

@ -29,11 +29,18 @@ func Engaged()
SetAction("OnRail");
}
func Disengaged()
{
SetAction("Idle");
if (pickup)
DropVehicle();
}
func GetCableCarExtraMenuEntries(array menu_entries, proplist custom_entry, object clonk)
{
if (IsTravelling()) return;
if (!pickup)
if (!pickup && GetRailTarget())
{
// Picking up vehicles
var vehicles = FindObjects(Find_AtPoint(), Find_Category(C4D_Vehicle), Find_Not(Find_Func("RejectCableHoistPickup", this)), Find_Exclude(this), Find_Func(pickup));
@ -42,22 +49,26 @@ func GetCableCarExtraMenuEntries(array menu_entries, proplist custom_entry, obje
{
if (GetEffect("CableHoistPickup", vehicle)) continue;
var pickup = new custom_entry {
var to_pickup = new custom_entry {
Priority = 2000 + i,
Tooltip = "$TooltipPickup$",
OnClick = GuiAction_Call(this, "PickupVehicle", vehicle)
OnClick = GuiAction_Call(this, "PickupVehicle", vehicle),
image = { Prototype = custom_entry.image, Symbol = vehicle },
icon = { Prototype = custom_entry.icon, Symbol = Icon_LibraryCableCar, GraphicsName = "Engage" }
};
pickup.image.Symbol = vehicle;
PushBack(menu_entries, { symbol = vehicle, extra_data = "Pickup", custom = pickup });
PushBack(menu_entries, { symbol = vehicle, extra_data = "Pickup", custom = to_pickup });
i++;
}
} else {
} else if (pickup && GetRailTarget()) {
// Drop the vehicle
var drop = new custom_entry {
Priority = 2000,
Tooltip = "$TooltipDrop$",
OnClick = GuiAction_Call(this, "DropVehicle")
OnClick = GuiAction_Call(this, "DropVehicle"),
image = { Prototype = custom_entry.image, Symbol = pickup },
icon = { Prototype = custom_entry.icon, Symbol = Icon_LibraryCableCar, GraphicsName = "Disengage" }
};
PushBack(menu_entries, { symbol = pickup, extra_data = "Drop", custom = drop });
}
}

View File

@ -111,6 +111,9 @@ public func SetPrecipitation(string mat, int amount)
rain = BoundBy(amount * rain_max / 100, 0, 960);
// Store snow/water conversion
rain_mat_freeze_temp = GetMaterialVal("BelowTempConvert", "Material", Material(rain_mat));
// Hack: material val does not return nil for materials that do not freeze, so fix those explicitly.
if (mat == "Snow" || mat == "Ice")
rain_mat_freeze_temp = nil;
rain_mat_frozen = GetMaterialVal("BelowTempConvertTo", "Material", Material(rain_mat));
if (rain_mat_frozen == "Ice") rain_mat_frozen = "Snow";
}

View File

@ -97,7 +97,6 @@ void C4ConfigGraphics::CompileFunc(StdCompiler *pComp)
pComp->Value(mkNamingAdapt(RefreshRate, "RefreshRate", 0 ));
pComp->Value(mkNamingAdapt(SplitscreenDividers, "SplitscreenDividers", 1 ));
pComp->Value(mkNamingAdapt(ShowStartupMessages, "ShowStartupMessages", 1 ,false, true));
pComp->Value(mkNamingAdapt(HighResLandscape, "HighResLandscape", 1 ,false, true));
pComp->Value(mkNamingAdapt(VerboseObjectLoading, "VerboseObjectLoading", 0 ));
pComp->Value(mkNamingAdapt(MenuTransparency, "MenuTransparency", 1 ,false, true));
pComp->Value(mkNamingAdapt(UpperBoard, "UpperBoard", 1 ,false, true));

View File

@ -96,7 +96,6 @@ public:
int32_t SplitscreenDividers;
int32_t ShowStartupMessages;
int32_t VerboseObjectLoading;
int32_t HighResLandscape;
int32_t MenuTransparency;
int32_t UpperBoard;
int32_t ShowClock;

View File

@ -37,11 +37,13 @@
#include <C4GameMessage.h>
#include <C4Landscape.h>
#include <C4Game.h>
#include "game/C4GameScript.h"
#include <C4PlayerList.h>
#include <C4GameObjects.h>
#include <C4GameControl.h>
#include <C4ScriptGuiWindow.h>
#include "gui/C4MessageInput.h"
#include "object/C4Def.h"
#include "object/C4DefList.h"
#ifndef NOAULDEBUG
@ -1373,7 +1375,7 @@ void C4ControlEMMoveObject::CompileFunc(StdCompiler *pComp)
// *** C4ControlEMDrawTool
C4ControlEMDrawTool::C4ControlEMDrawTool(C4ControlEMDrawAction eAction, int32_t iMode,
C4ControlEMDrawTool::C4ControlEMDrawTool(C4ControlEMDrawAction eAction, LandscapeMode iMode,
int32_t iX, int32_t iY, int32_t iX2, int32_t iY2, int32_t iGrade,
const char *szMaterial, const char *szTexture, const char *szBackMaterial, const char *szBackTexture)
: eAction(eAction), iMode(iMode), iX(iX), iY(iY), iX2(iX2), iY2(iY2), iGrade(iGrade),
@ -1392,8 +1394,8 @@ void C4ControlEMDrawTool::Execute() const
return;
}
// check current mode
assert(::Landscape.Mode == iMode);
if (::Landscape.Mode != iMode) return;
assert(::Landscape.GetMode() == iMode);
if (::Landscape.GetMode() != iMode) return;
// assert validity of parameters
if (!Material.getSize()) return;
const char *szMaterial = Material.getData(),
@ -1436,7 +1438,7 @@ void C4ControlEMDrawTool::Execute() const
void C4ControlEMDrawTool::CompileFunc(StdCompiler *pComp)
{
pComp->Value(mkNamingAdapt(mkIntAdaptT<uint8_t>(eAction), "Action"));
pComp->Value(mkNamingAdapt(mkIntPackAdapt(iMode), "Mode", 0));
pComp->Value(mkNamingAdapt(mkIntAdaptT<uint8_t>(iMode), "Mode", LandscapeMode::Undefined));
pComp->Value(mkNamingAdapt(iX, "X", 0));
pComp->Value(mkNamingAdapt(iY, "Y", 0));
pComp->Value(mkNamingAdapt(iX2, "X2", 0));

View File

@ -486,17 +486,18 @@ enum C4ControlEMDrawAction
EMDT_Rect // drawing tool
};
enum class LandscapeMode;
class C4ControlEMDrawTool : public C4ControlPacket // sync
{
public:
C4ControlEMDrawTool() : eAction(EMDT_SetMode), iX(0), iY(0), iX2(0), iY2(0), iGrade(0) { }
C4ControlEMDrawTool(C4ControlEMDrawAction eAction, int32_t iMode,
C4ControlEMDrawTool(C4ControlEMDrawAction eAction, LandscapeMode iMode,
int32_t iX=-1, int32_t iY=-1, int32_t iX2=-1, int32_t iY2=-1, int32_t iGrade=-1,
const char *szMaterial=NULL, const char *szTexture=NULL,
const char *szBackMaterial=NULL, const char *szBackTexture=NULL);
protected:
C4ControlEMDrawAction eAction; // action to be performed
int32_t iMode; // new mode, or mode action was performed in (action will fail if changed)
LandscapeMode iMode; // new mode, or mode action was performed in (action will fail if changed)
int32_t iX,iY,iX2,iY2,iGrade; // drawing parameters
StdStrBuf Material; // used material
StdStrBuf Texture; // used texture

View File

@ -139,12 +139,12 @@ bool C4GameSave::SaveScenarioSections()
bool C4GameSave::SaveLandscape()
{
// exact?
if (::Landscape.Mode == C4LSC_Exact || GetForceExactLandscape())
if (::Landscape.GetMode() == LandscapeMode::Exact || GetForceExactLandscape())
{
C4DebugRecOff DBGRECOFF;
// Landscape
bool fSuccess;
if (::Landscape.Mode == C4LSC_Exact)
if (::Landscape.GetMode() == LandscapeMode::Exact)
fSuccess = !!::Landscape.Save(*pSaveGroup);
else
fSuccess = !!::Landscape.SaveDiff(*pSaveGroup, !IsSynced());
@ -160,7 +160,7 @@ bool C4GameSave::SaveLandscape()
if (!::MaterialMap.SaveEnumeration(*pSaveGroup)) return false;
}
// static / dynamic
if (::Landscape.Mode == C4LSC_Static)
if (::Landscape.GetMode() == LandscapeMode::Static)
{
// static map
// remove old-style landscape.bmp
@ -174,7 +174,7 @@ bool C4GameSave::SaveLandscape()
if (!::Landscape.SaveTextures(*pSaveGroup)) return false;
}
}
else if (::Landscape.Mode != C4LSC_Exact)
else if (::Landscape.GetMode() != LandscapeMode::Exact)
{
// dynamic map by landscape.txt or scenario core: nothing to save
// in fact, it doesn't even make much sense to save the Objects.txt

View File

@ -32,6 +32,7 @@
#include "C4Viewport.h"
#include "C4Object.h"
#include "C4ObjectMenu.h"
#include "script/C4Aul.h"
#include <algorithm>

View File

@ -20,6 +20,7 @@
#include <C4Player.h>
#include <C4Game.h>
#include "object/C4Def.h"
#include <C4Object.h>
#include <C4PlayerList.h>
#include <C4GameObjects.h>

View File

@ -189,7 +189,7 @@ bool C4Console::SaveScenario(const char * path)
SetCursor(C4ConsoleGUI::CURSOR_Wait);
bool fOkay=true;
C4GameSave *pGameSave = new C4GameSaveScenario(!Console.Active || ::Landscape.Mode==C4LSC_Exact, false);
C4GameSave *pGameSave = new C4GameSaveScenario(!Console.Active || ::Landscape.GetMode() == LandscapeMode::Exact, false);
if (!pGameSave->Save(Game.ScenarioFile, false))
{ Out("Game::Save failed"); fOkay=false; }
delete pGameSave;

View File

@ -26,6 +26,7 @@
#include <C4Language.h>
#include <C4Player.h>
#include <C4Landscape.h>
#include "landscape/C4Sky.h"
#include <C4GraphicsSystem.h>
#include <C4PlayerList.h>
#include <C4GameControl.h>
@ -221,7 +222,7 @@ void C4ToolsDlg::UpdateTextures()
[texturesPopup removeAllItems];
// bottom-most: any invalid textures
bool fAnyEntry = false; int32_t cnt; const char *szTexture;
if (::Landscape.Mode!=C4LSC_Exact)
if (::Landscape.GetMode()!=LandscapeMode::Exact)
for (cnt=0; (szTexture=::TextureMap.GetTexture(cnt)); cnt++)
{
if (!::TextureMap.GetIndex(Material, szTexture, false))
@ -240,7 +241,7 @@ void C4ToolsDlg::UpdateTextures()
for (cnt=0; (szTexture=::TextureMap.GetTexture(cnt)); cnt++)
{
// Current material-texture valid? Always valid for exact mode
if (::TextureMap.GetIndex(Material,szTexture,false) || ::Landscape.Mode==C4LSC_Exact)
if (::TextureMap.GetIndex(Material,szTexture,false) || ::Landscape.GetMode()==LandscapeMode::Exact)
{
[texturesPopup insertItemWithTitle:[NSString stringWithUTF8String:szTexture] atIndex:0];
}
@ -295,7 +296,7 @@ CGImageRef C4ToolsDlg::State::CreatePreviewImage()
// Sky material: sky as pattern only
if (SEqual(GetOwner()->Material,C4TLS_MatSky))
{
Pattern.Set(::Landscape.Sky.Surface, 0);
Pattern.Set(::Landscape.GetSky().Surface, 0);
}
// Material-Texture
else

View File

@ -32,6 +32,7 @@
#include <C4Object.h>
#include <C4Player.h>
#include <C4Landscape.h>
#include "landscape/C4Sky.h"
#include <C4GraphicsSystem.h>
#include <C4PlayerList.h>
#include <C4GameControl.h>
@ -1266,7 +1267,7 @@ void C4ToolsDlg::UpdateTextures()
// bottom-most: any invalid textures
bool fAnyEntry = false; int32_t cnt; const char *szTexture;
if (::Landscape.Mode!=C4LSC_Exact)
if (::Landscape.GetMode()!=LandscapeMode::Exact)
for (cnt=0; (szTexture=::TextureMap.GetTexture(cnt)); cnt++)
{
if (!::TextureMap.GetIndex(material, szTexture, false))
@ -1285,7 +1286,7 @@ void C4ToolsDlg::UpdateTextures()
for (cnt=0; (szTexture=::TextureMap.GetTexture(cnt)); cnt++)
{
// Current material-texture valid? Always valid for exact mode
if (::TextureMap.GetIndex(material,szTexture,false) || ::Landscape.Mode==C4LSC_Exact)
if (::TextureMap.GetIndex(material,szTexture,false) || ::Landscape.GetMode()==LandscapeMode::Exact)
{
gtk_combo_box_text_prepend_text(GTK_COMBO_BOX_TEXT(box), szTexture);
}
@ -1324,7 +1325,7 @@ void C4ToolsDlg::State::UpdatePreview()
// Sky material: sky as pattern only
if (SEqual(dlg->Material,C4TLS_MatSky))
{
Pattern.Set(::Landscape.Sky.Surface, 0);
Pattern.Set(::Landscape.GetSky().Surface, 0);
}
// Material-Texture
else
@ -1373,24 +1374,24 @@ void C4ToolsDlg::UpdateLandscapeModeCtrls()
void C4ToolsDlg::State::UpdateLandscapeModeCtrls()
{
int32_t iMode = ::Landscape.Mode;
LandscapeMode iMode = ::Landscape.GetMode();
g_signal_handler_block(landscape_dynamic, handlerDynamic);
g_signal_handler_block(landscape_static, handlerStatic);
g_signal_handler_block(landscape_exact, handlerExact);
gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(landscape_dynamic), iMode==C4LSC_Dynamic);
gtk_widget_set_sensitive(landscape_dynamic, iMode==C4LSC_Dynamic);
gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(landscape_dynamic), iMode==LandscapeMode::Dynamic);
gtk_widget_set_sensitive(landscape_dynamic, iMode==LandscapeMode::Dynamic);
gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(landscape_static), iMode==C4LSC_Static);
gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(landscape_static), iMode==LandscapeMode::Static);
gtk_widget_set_sensitive(landscape_static, ::Landscape.HasMap());
gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(landscape_exact), iMode==C4LSC_Exact);
gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(landscape_exact), iMode==LandscapeMode::Exact);
g_signal_handler_unblock(landscape_dynamic, handlerDynamic);
g_signal_handler_unblock(landscape_static, handlerStatic);
g_signal_handler_unblock(landscape_exact, handlerExact);
C4DevmodeDlg::SetTitle(hbox, LoadResStr(iMode==C4LSC_Dynamic ? "IDS_DLG_DYNAMIC" : iMode==C4LSC_Static ? "IDS_DLG_STATIC" : "IDS_DLG_EXACT"));
C4DevmodeDlg::SetTitle(hbox, LoadResStr(iMode==LandscapeMode::Dynamic ? "IDS_DLG_DYNAMIC" : iMode==LandscapeMode::Static ? "IDS_DLG_STATIC" : "IDS_DLG_EXACT"));
}
void C4ToolsDlg::UpdateIFTControls()
@ -1441,18 +1442,18 @@ void C4ConsoleGUI::SetCaptionToFileName(const char* file_name)
void C4ToolsDlg::EnableControls()
{
int32_t iLandscapeMode=::Landscape.Mode;
gtk_widget_set_sensitive(state->brush, iLandscapeMode>=C4LSC_Static);
gtk_widget_set_sensitive(state->line, iLandscapeMode>=C4LSC_Static);
gtk_widget_set_sensitive(state->rect, iLandscapeMode>=C4LSC_Static);
gtk_widget_set_sensitive(state->fill, iLandscapeMode>=C4LSC_Exact);
gtk_widget_set_sensitive(state->picker, iLandscapeMode>=C4LSC_Static);
gtk_widget_set_sensitive(state->fg_materials, iLandscapeMode>=C4LSC_Static);
gtk_widget_set_sensitive(state->fg_textures, iLandscapeMode >= C4LSC_Static && !SEqual(Material,C4TLS_MatSky));
gtk_widget_set_sensitive(state->bg_materials, iLandscapeMode>=C4LSC_Static && !SEqual(Material,C4TLS_MatSky));
gtk_widget_set_sensitive(state->bg_textures, iLandscapeMode >= C4LSC_Static && !SEqual(Material,C4TLS_MatSky) && !SEqual(BackMaterial, C4TLS_MatSky));
gtk_widget_set_sensitive(state->scale, iLandscapeMode>=C4LSC_Static);
gtk_widget_set_sensitive(state->preview, iLandscapeMode>=C4LSC_Static);
LandscapeMode iLandscapeMode=::Landscape.GetMode();
gtk_widget_set_sensitive(state->brush, iLandscapeMode>=LandscapeMode::Static);
gtk_widget_set_sensitive(state->line, iLandscapeMode>=LandscapeMode::Static);
gtk_widget_set_sensitive(state->rect, iLandscapeMode>=LandscapeMode::Static);
gtk_widget_set_sensitive(state->fill, iLandscapeMode>=LandscapeMode::Exact);
gtk_widget_set_sensitive(state->picker, iLandscapeMode>=LandscapeMode::Static);
gtk_widget_set_sensitive(state->fg_materials, iLandscapeMode>=LandscapeMode::Static);
gtk_widget_set_sensitive(state->fg_textures, iLandscapeMode >= LandscapeMode::Static && !SEqual(Material,C4TLS_MatSky));
gtk_widget_set_sensitive(state->bg_materials, iLandscapeMode>=LandscapeMode::Static && !SEqual(Material,C4TLS_MatSky));
gtk_widget_set_sensitive(state->bg_textures, iLandscapeMode >= LandscapeMode::Static && !SEqual(Material,C4TLS_MatSky) && !SEqual(BackMaterial, C4TLS_MatSky));
gtk_widget_set_sensitive(state->scale, iLandscapeMode>=LandscapeMode::Static);
gtk_widget_set_sensitive(state->preview, iLandscapeMode>=LandscapeMode::Static);
NeedPreviewUpdate();
}
@ -1588,17 +1589,17 @@ void C4ConsoleGUI::State::OnNetClient(GtkWidget* item, gpointer data)
void C4ToolsDlg::State::OnButtonModeDynamic(GtkWidget* widget, gpointer data)
{
static_cast<C4ToolsDlg::State*>(data)->GetOwner()->SetLandscapeMode(C4LSC_Dynamic);
static_cast<C4ToolsDlg::State*>(data)->GetOwner()->SetLandscapeMode(LandscapeMode::Dynamic);
}
void C4ToolsDlg::State::OnButtonModeStatic(GtkWidget* widget, gpointer data)
{
static_cast<C4ToolsDlg::State*>(data)->GetOwner()->SetLandscapeMode(C4LSC_Static);
static_cast<C4ToolsDlg::State*>(data)->GetOwner()->SetLandscapeMode(LandscapeMode::Static);
}
void C4ToolsDlg::State::OnButtonModeExact(GtkWidget* widget, gpointer data)
{
static_cast<C4ToolsDlg::State*>(data)->GetOwner()->SetLandscapeMode(C4LSC_Exact);
static_cast<C4ToolsDlg::State*>(data)->GetOwner()->SetLandscapeMode(LandscapeMode::Exact);
}
void C4ToolsDlg::State::OnButtonBrush(GtkWidget* widget, gpointer data)

View File

@ -31,6 +31,7 @@
#include "C4Viewport.h"
#include <StdRegistry.h>
#include "lib/StdColors.h"
#include "landscape/C4Sky.h"
#include <C4windowswrapper.h>
#include <mmsystem.h>
@ -630,15 +631,15 @@ INT_PTR CALLBACK ToolsDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
return true;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
case IDC_BUTTONMODEDYNAMIC:
Console.ToolsDlg.SetLandscapeMode(C4LSC_Dynamic);
Console.ToolsDlg.SetLandscapeMode(LandscapeMode::Dynamic);
return true;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
case IDC_BUTTONMODESTATIC:
Console.ToolsDlg.SetLandscapeMode(C4LSC_Static);
Console.ToolsDlg.SetLandscapeMode(LandscapeMode::Static);
return true;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
case IDC_BUTTONMODEEXACT:
Console.ToolsDlg.SetLandscapeMode(C4LSC_Exact);
Console.ToolsDlg.SetLandscapeMode(LandscapeMode::Exact);
return true;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
case IDC_BUTTONBRUSH:
@ -1251,7 +1252,7 @@ void C4ToolsDlg::UpdateTextures()
SendDlgItemMessage(state->hDialog, box, CB_RESETCONTENT, 0, (LPARAM)0);
// bottom-most: any invalid textures
bool fAnyEntry = false; int32_t cnt; const char *szTexture;
if (::Landscape.Mode != C4LSC_Exact)
if (::Landscape.GetMode() != LandscapeMode::Exact)
for (cnt = 0; (szTexture = ::TextureMap.GetTexture(cnt)); cnt++)
{
if (!::TextureMap.GetIndex(material, szTexture, false))
@ -1275,7 +1276,7 @@ void C4ToolsDlg::UpdateTextures()
for (cnt = 0; (szTexture = ::TextureMap.GetTexture(cnt)); cnt++)
{
// Current material-texture valid? Always valid for exact mode
if (::TextureMap.GetIndex(material, szTexture, false) || ::Landscape.Mode == C4LSC_Exact)
if (::TextureMap.GetIndex(material, szTexture, false) || ::Landscape.GetMode() == LandscapeMode::Exact)
{
SendDlgItemMessage(state->hDialog, box, CB_INSERTSTRING, 0, GetWideLPARAM(szTexture));
}
@ -1311,7 +1312,7 @@ void C4ToolsDlg::NeedPreviewUpdate()
// Sky material: sky as pattern only
if (SEqual(Material,C4TLS_MatSky))
{
Pattern.Set(::Landscape.Sky.Surface, 0);
Pattern.Set(::Landscape.GetSky().Surface, 0);
}
// Material-Texture
else
@ -1375,52 +1376,52 @@ void C4ToolsDlg::UpdateIFTControls()
void C4ToolsDlg::UpdateLandscapeModeCtrls()
{
int32_t iMode = ::Landscape.Mode;
LandscapeMode iMode = ::Landscape.GetMode();
// Dynamic: enable only if dynamic anyway
SendDlgItemMessage(state->hDialog,IDC_BUTTONMODEDYNAMIC,BM_SETSTATE,(iMode==C4LSC_Dynamic),0);
EnableWindow(GetDlgItem(state->hDialog,IDC_BUTTONMODEDYNAMIC),(iMode==C4LSC_Dynamic));
SendDlgItemMessage(state->hDialog,IDC_BUTTONMODEDYNAMIC,BM_SETSTATE,(iMode==LandscapeMode::Dynamic),0);
EnableWindow(GetDlgItem(state->hDialog,IDC_BUTTONMODEDYNAMIC),(iMode==LandscapeMode::Dynamic));
UpdateWindow(GetDlgItem(state->hDialog,IDC_BUTTONMODEDYNAMIC));
// Static: enable only if map available
SendDlgItemMessage(state->hDialog,IDC_BUTTONMODESTATIC,BM_SETSTATE,(iMode==C4LSC_Static),0);
SendDlgItemMessage(state->hDialog,IDC_BUTTONMODESTATIC,BM_SETSTATE,(iMode==LandscapeMode::Static),0);
EnableWindow(GetDlgItem(state->hDialog,IDC_BUTTONMODESTATIC),(::Landscape.HasMap()));
UpdateWindow(GetDlgItem(state->hDialog,IDC_BUTTONMODESTATIC));
// Exact: enable always
SendDlgItemMessage(state->hDialog,IDC_BUTTONMODEEXACT,BM_SETSTATE,(iMode==C4LSC_Exact),0);
SendDlgItemMessage(state->hDialog,IDC_BUTTONMODEEXACT,BM_SETSTATE,(iMode==LandscapeMode::Exact),0);
UpdateWindow(GetDlgItem(state->hDialog,IDC_BUTTONMODEEXACT));
// Set dialog caption
SetWindowTextW(state->hDialog,LoadResStrW(iMode==C4LSC_Dynamic ? "IDS_DLG_DYNAMIC" : iMode==C4LSC_Static ? "IDS_DLG_STATIC" : "IDS_DLG_EXACT"));
SetWindowTextW(state->hDialog,LoadResStrW(iMode==LandscapeMode::Dynamic ? "IDS_DLG_DYNAMIC" : iMode==LandscapeMode::Static ? "IDS_DLG_STATIC" : "IDS_DLG_EXACT"));
}
void C4ToolsDlg::EnableControls()
{
HWND hDialog = state->hDialog;
int32_t iLandscapeMode=::Landscape.Mode;
LandscapeMode iLandscapeMode = ::Landscape.GetMode();
// Set bitmap buttons
SendDlgItemMessage(hDialog,IDC_BUTTONBRUSH,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)((iLandscapeMode>=C4LSC_Static) ? state->hbmBrush : state->hbmBrush2));
SendDlgItemMessage(hDialog,IDC_BUTTONLINE,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)((iLandscapeMode>=C4LSC_Static) ? state->hbmLine : state->hbmLine2));
SendDlgItemMessage(hDialog,IDC_BUTTONRECT,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)((iLandscapeMode>=C4LSC_Static) ? state->hbmRect : state->hbmRect2));
SendDlgItemMessage(hDialog,IDC_BUTTONFILL,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)((iLandscapeMode>=C4LSC_Exact) ? state->hbmFill : state->hbmFill2));
SendDlgItemMessage(hDialog,IDC_BUTTONPICKER,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)((iLandscapeMode>=C4LSC_Static) ? state->hbmPicker : state->hbmPicker2));
SendDlgItemMessage(hDialog,IDC_BUTTONBRUSH,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)((iLandscapeMode>=LandscapeMode::Static) ? state->hbmBrush : state->hbmBrush2));
SendDlgItemMessage(hDialog,IDC_BUTTONLINE,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)((iLandscapeMode>=LandscapeMode::Static) ? state->hbmLine : state->hbmLine2));
SendDlgItemMessage(hDialog,IDC_BUTTONRECT,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)((iLandscapeMode>=LandscapeMode::Static) ? state->hbmRect : state->hbmRect2));
SendDlgItemMessage(hDialog,IDC_BUTTONFILL,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)((iLandscapeMode>=LandscapeMode::Exact) ? state->hbmFill : state->hbmFill2));
SendDlgItemMessage(hDialog,IDC_BUTTONPICKER,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)((iLandscapeMode>=LandscapeMode::Static) ? state->hbmPicker : state->hbmPicker2));
SendDlgItemMessage(hDialog,IDC_BUTTONMODEDYNAMIC,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)state->hbmDynamic);
SendDlgItemMessage(hDialog,IDC_BUTTONMODESTATIC,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)state->hbmStatic);
SendDlgItemMessage(hDialog,IDC_BUTTONMODEEXACT,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)state->hbmExact);
// Enable drawing controls
EnableWindow(GetDlgItem(hDialog,IDC_BUTTONBRUSH),(iLandscapeMode>=C4LSC_Static));
EnableWindow(GetDlgItem(hDialog,IDC_BUTTONLINE),(iLandscapeMode>=C4LSC_Static));
EnableWindow(GetDlgItem(hDialog,IDC_BUTTONRECT),(iLandscapeMode>=C4LSC_Static));
EnableWindow(GetDlgItem(hDialog,IDC_BUTTONFILL),(iLandscapeMode>=C4LSC_Exact));
EnableWindow(GetDlgItem(hDialog,IDC_BUTTONPICKER),(iLandscapeMode>=C4LSC_Static));
EnableWindow(GetDlgItem(hDialog,IDC_COMBOFGMATERIAL),(iLandscapeMode>=C4LSC_Static));
EnableWindow(GetDlgItem(hDialog,IDC_COMBOFGTEXTURE),(iLandscapeMode>=C4LSC_Static) && !SEqual(Material,C4TLS_MatSky));
EnableWindow(GetDlgItem(hDialog,IDC_COMBOBGMATERIAL), (iLandscapeMode >= C4LSC_Static) && !SEqual(Material, C4TLS_MatSky));
EnableWindow(GetDlgItem(hDialog, IDC_COMBOBGTEXTURE), (iLandscapeMode >= C4LSC_Static) && !SEqual(Material, C4TLS_MatSky) && !SEqual(BackMaterial, C4TLS_MatSky));
EnableWindow(GetDlgItem(hDialog,IDC_STATICMATERIAL),(iLandscapeMode>=C4LSC_Static));
EnableWindow(GetDlgItem(hDialog,IDC_STATICTEXTURE),(iLandscapeMode>=C4LSC_Static) && !SEqual(Material,C4TLS_MatSky));
EnableWindow(GetDlgItem(hDialog,IDC_STATICFOREGROUND), (iLandscapeMode >= C4LSC_Static));
EnableWindow(GetDlgItem(hDialog,IDC_STATICBACKGROUND), (iLandscapeMode >= C4LSC_Static));
EnableWindow(GetDlgItem(hDialog,IDC_SLIDERGRADE),(iLandscapeMode>=C4LSC_Static));
EnableWindow(GetDlgItem(hDialog,IDC_PREVIEW),(iLandscapeMode>=C4LSC_Static));
EnableWindow(GetDlgItem(hDialog,IDC_BUTTONBRUSH),(iLandscapeMode>=LandscapeMode::Static));
EnableWindow(GetDlgItem(hDialog,IDC_BUTTONLINE),(iLandscapeMode>=LandscapeMode::Static));
EnableWindow(GetDlgItem(hDialog,IDC_BUTTONRECT),(iLandscapeMode>=LandscapeMode::Static));
EnableWindow(GetDlgItem(hDialog,IDC_BUTTONFILL),(iLandscapeMode>=LandscapeMode::Exact));
EnableWindow(GetDlgItem(hDialog,IDC_BUTTONPICKER),(iLandscapeMode>=LandscapeMode::Static));
EnableWindow(GetDlgItem(hDialog,IDC_COMBOFGMATERIAL),(iLandscapeMode>=LandscapeMode::Static));
EnableWindow(GetDlgItem(hDialog,IDC_COMBOFGTEXTURE),(iLandscapeMode>=LandscapeMode::Static) && !SEqual(Material,C4TLS_MatSky));
EnableWindow(GetDlgItem(hDialog,IDC_COMBOBGMATERIAL), (iLandscapeMode >= LandscapeMode::Static) && !SEqual(Material, C4TLS_MatSky));
EnableWindow(GetDlgItem(hDialog, IDC_COMBOBGTEXTURE), (iLandscapeMode >= LandscapeMode::Static) && !SEqual(Material, C4TLS_MatSky) && !SEqual(BackMaterial, C4TLS_MatSky));
EnableWindow(GetDlgItem(hDialog,IDC_STATICMATERIAL),(iLandscapeMode>=LandscapeMode::Static));
EnableWindow(GetDlgItem(hDialog,IDC_STATICTEXTURE),(iLandscapeMode>=LandscapeMode::Static) && !SEqual(Material,C4TLS_MatSky));
EnableWindow(GetDlgItem(hDialog,IDC_STATICFOREGROUND), (iLandscapeMode >= LandscapeMode::Static));
EnableWindow(GetDlgItem(hDialog,IDC_STATICBACKGROUND), (iLandscapeMode >= LandscapeMode::Static));
EnableWindow(GetDlgItem(hDialog,IDC_SLIDERGRADE),(iLandscapeMode>=LandscapeMode::Static));
EnableWindow(GetDlgItem(hDialog,IDC_PREVIEW),(iLandscapeMode>=LandscapeMode::Static));
NeedPreviewUpdate();
}

View File

@ -702,7 +702,7 @@ void C4EditCursor::ApplyToolBrush()
if (!EditingOK()) return;
C4ToolsDlg *pTools=&Console.ToolsDlg;
// execute/send control
EMControl(CID_EMDrawTool, new C4ControlEMDrawTool(EMDT_Brush, ::Landscape.Mode, X,Y,0,0, pTools->Grade, pTools->Material, pTools->Texture, pTools->BackMaterial, pTools->BackTexture));
EMControl(CID_EMDrawTool, new C4ControlEMDrawTool(EMDT_Brush, ::Landscape.GetMode(), X,Y,0,0, pTools->Grade, pTools->Material, pTools->Texture, pTools->BackMaterial, pTools->BackTexture));
}
void C4EditCursor::ApplyToolLine()
@ -710,7 +710,7 @@ void C4EditCursor::ApplyToolLine()
if (!EditingOK()) return;
C4ToolsDlg *pTools=&Console.ToolsDlg;
// execute/send control
EMControl(CID_EMDrawTool, new C4ControlEMDrawTool(EMDT_Line, ::Landscape.Mode, X,Y,X2,Y2, pTools->Grade, pTools->Material,pTools->Texture, pTools->BackMaterial, pTools->BackTexture));
EMControl(CID_EMDrawTool, new C4ControlEMDrawTool(EMDT_Line, ::Landscape.GetMode(), X,Y,X2,Y2, pTools->Grade, pTools->Material,pTools->Texture, pTools->BackMaterial, pTools->BackTexture));
}
void C4EditCursor::ApplyToolRect()
@ -718,7 +718,7 @@ void C4EditCursor::ApplyToolRect()
if (!EditingOK()) return;
C4ToolsDlg *pTools=&Console.ToolsDlg;
// execute/send control
EMControl(CID_EMDrawTool, new C4ControlEMDrawTool(EMDT_Rect, ::Landscape.Mode, X,Y,X2,Y2, pTools->Grade, pTools->Material, pTools->Texture, pTools->BackMaterial, pTools->BackTexture));
EMControl(CID_EMDrawTool, new C4ControlEMDrawTool(EMDT_Rect, ::Landscape.GetMode(), X,Y,X2,Y2, pTools->Grade, pTools->Material, pTools->Texture, pTools->BackMaterial, pTools->BackTexture));
}
void C4EditCursor::ApplyToolFill()
@ -726,7 +726,7 @@ void C4EditCursor::ApplyToolFill()
if (!EditingOK()) return;
C4ToolsDlg *pTools=&Console.ToolsDlg;
// execute/send control
EMControl(CID_EMDrawTool, new C4ControlEMDrawTool(EMDT_Fill, ::Landscape.Mode, X,Y,0,Y2, pTools->Grade, pTools->Material, NULL, NULL, NULL));
EMControl(CID_EMDrawTool, new C4ControlEMDrawTool(EMDT_Fill, ::Landscape.GetMode(), X,Y,0,Y2, pTools->Grade, pTools->Material, NULL, NULL, NULL));
}
void C4EditCursor::AppendMenuItem(int num, const StdStrBuf & label)
@ -756,9 +756,9 @@ bool C4EditCursor::DoContextMenu(DWORD dwKeyState)
#ifdef USE_WIN32_WINDOWS
POINT point; GetCursorPos(&point);
HMENU hContext = GetSubMenu(hMenu,0);
SetMenuItemEnable( hContext, IDM_VIEWPORT_DELETE, fObjectSelected && Console.Editing);
SetMenuItemEnable( hContext, IDM_VIEWPORT_DUPLICATE, fObjectSelected && Console.Editing);
SetMenuItemEnable( hContext, IDM_VIEWPORT_CONTENTS, fObjectSelected && Selection.GetObject()->Contents.ObjectCount() && Console.Editing);
SetMenuItemEnable(hContext, IDM_VIEWPORT_DELETE, fObjectSelected && Console.Editing);
SetMenuItemEnable(hContext, IDM_VIEWPORT_DUPLICATE, fObjectSelected && Console.Editing);
SetMenuItemEnable(hContext, IDM_VIEWPORT_CONTENTS, fObjectSelected && Selection.GetObject()->Contents.ObjectCount() && Console.Editing);
SetMenuItemText(hContext,IDM_VIEWPORT_DELETE,LoadResStr("IDS_MNU_DELETE"));
SetMenuItemText(hContext,IDM_VIEWPORT_DUPLICATE,LoadResStr("IDS_MNU_DUPLICATE"));
SetMenuItemText(hContext,IDM_VIEWPORT_CONTENTS,LoadResStr("IDS_MNU_CONTENTS"));
@ -946,13 +946,13 @@ void C4EditCursor::ApplyToolPicker()
{
int32_t iMaterial;
BYTE byIndex;
switch (::Landscape.Mode)
switch (::Landscape.GetMode())
{
case C4LSC_Static:
case LandscapeMode::Static:
{
bool material_set = false;
int32_t x = X/::Landscape.MapZoom;
int32_t y = Y/::Landscape.MapZoom;
int32_t x = X/::Landscape.GetMapZoom();
int32_t y = Y/::Landscape.GetMapZoom();
// Material-texture from map
if ((byIndex = ::Landscape.GetMapIndex(x, y)))
{
@ -989,7 +989,7 @@ void C4EditCursor::ApplyToolPicker()
if (!material_set) Console.ToolsDlg.SelectMaterial(C4TLS_MatSky);
break;
}
case C4LSC_Exact:
case LandscapeMode::Exact:
// Material only from landscape
if (MatValid(iMaterial=GBackMat(X,Y)))
{

View File

@ -160,7 +160,7 @@ int indexFromSender(id sender)
- (IBAction) selectLandscapeMode:(id)sender
{
// add one since 0 is "undefined"
Console.ToolsDlg.SetLandscapeMode([sender selectedSegment]+1, NO);
Console.ToolsDlg.SetLandscapeMode((LandscapeMode)([sender selectedSegment]+1), NO);
}
- (IBAction) setGrade:(id)sender

View File

@ -61,7 +61,7 @@ void C4ToolsDlg::SetMaterial(const char *szMaterial)
SCopy(szMaterial,Material,C4M_MaxName);
AssertValidTexture();
EnableControls();
if (::Landscape.Mode==C4LSC_Static) UpdateTextures();
if (::Landscape.GetMode() == LandscapeMode::Static) UpdateTextures();
NeedPreviewUpdate();
if (ModeBack && SEqual(szMaterial, C4TLS_MatSky))
SelectBackMaterial(C4TLS_MatSky);
@ -109,7 +109,7 @@ void C4ToolsDlg::SetBackMaterial(const char *szMaterial)
SCopy(szMaterial,BackMaterial,C4M_MaxName);
AssertValidBackTexture();
EnableControls();
if (::Landscape.Mode==C4LSC_Static) UpdateTextures();
if (::Landscape.GetMode() == LandscapeMode::Static) UpdateTextures();
}
void C4ToolsDlg::SetBackTexture(const char *szTexture)
@ -177,30 +177,30 @@ bool C4ToolsDlg::ChangeGrade(int32_t iChange)
return true;
}
bool C4ToolsDlg::SetLandscapeMode(int32_t iMode, bool fThroughControl)
bool C4ToolsDlg::SetLandscapeMode(LandscapeMode mode, bool fThroughControl)
{
int32_t iLastMode=::Landscape.Mode;
auto last_mode = ::Landscape.GetMode();
// Exact to static: confirm data loss warning
if (iLastMode==C4LSC_Exact)
if (iMode==C4LSC_Static)
if (last_mode == LandscapeMode::Exact)
if (mode == LandscapeMode::Static)
if (!fThroughControl)
if (!Console.Message(LoadResStr("IDS_CNS_EXACTTOSTATIC"),true))
if (!Console.Message(LoadResStr("IDS_CNS_EXACTTOSTATIC"), true))
return false;
// send as control
if (!fThroughControl)
{
::Control.DoInput(CID_EMDrawTool, new C4ControlEMDrawTool(EMDT_SetMode, iMode), CDT_Decide);
::Control.DoInput(CID_EMDrawTool, new C4ControlEMDrawTool(EMDT_SetMode, mode), CDT_Decide);
return true;
}
// Set landscape mode
::Landscape.SetMode(iMode);
::Landscape.SetMode(mode);
// Exact to static: redraw landscape from map
if (iLastMode==C4LSC_Exact)
if (iMode==C4LSC_Static)
if (last_mode == LandscapeMode::Exact)
if (mode == LandscapeMode::Static)
::Landscape.MapToLandscape();
// Assert valid tool
if (iMode!=C4LSC_Exact)
if (SelectedTool==C4TLS_Fill)
if (mode != LandscapeMode::Exact)
if (SelectedTool == C4TLS_Fill)
SetTool(C4TLS_Brush, false);
// Update controls
UpdateLandscapeModeCtrls();
@ -213,7 +213,7 @@ bool C4ToolsDlg::SetLandscapeMode(int32_t iMode, bool fThroughControl)
void C4ToolsDlg::AssertValidTexture()
{
// Static map mode only
if (::Landscape.Mode!=C4LSC_Static) return;
if (::Landscape.GetMode() != LandscapeMode::Static) return;
// Ignore if sky
if (SEqual(Material,C4TLS_MatSky)) return;
// Current material-texture valid
@ -231,7 +231,7 @@ void C4ToolsDlg::AssertValidTexture()
void C4ToolsDlg::AssertValidBackTexture()
{
// Static map mode only
if (::Landscape.Mode!=C4LSC_Static) return;
if (::Landscape.GetMode() != LandscapeMode::Static) return;
// Ignore if not enabled
if (!ModeBack) return;
// Ignore if sky

View File

@ -25,6 +25,7 @@
#endif
#include "C4Constants.h"
#include "landscape/C4Landscape.h"
const int32_t
C4TLS_Brush = 0,
@ -40,6 +41,7 @@ const int32_t
#define C4TLS_MatSky "Sky"
enum class LandscapeMode;
class C4ToolsDlg
{
friend class C4ConsoleGUI;
@ -70,7 +72,7 @@ public:
bool SetGrade(int32_t iGrade);
bool SetTool(int32_t iTool, bool fTemp);
bool ToggleTool() { return !!SetTool((Tool+1)%4, false); }
bool SetLandscapeMode(int32_t iMode, bool fThroughControl=false);
bool SetLandscapeMode(LandscapeMode iMode, bool fThroughControl=false);
bool SetIFT(bool fIFT);
bool ToggleIFT() { return !!SetIFT(!ModeIFT); }
bool SelectTexture(const char *szTexture);

View File

@ -83,14 +83,14 @@ bool C4Viewport::ScrollBarsByViewPosition()
// Vertical
scroll.fMask=SIF_ALL;
scroll.nMin=0;
scroll.nMax = GBackHgt * Zoom;
scroll.nMax = ::Landscape.GetHeight() * Zoom;
scroll.nPage=ViewHgt;
scroll.nPos=int(GetViewY() * Zoom);
SetScrollInfo(pWindow->hWindow,SB_VERT,&scroll,true);
// Horizontal
scroll.fMask=SIF_ALL;
scroll.nMin=0;
scroll.nMax=GBackWdt * Zoom;
scroll.nMax=::Landscape.GetWidth() * Zoom;
scroll.nPage=ViewWdt;
scroll.nPos = int(GetViewX() * Zoom);
SetScrollInfo(pWindow->hWindow,SB_HORZ,&scroll,true);
@ -129,7 +129,7 @@ bool C4Viewport::ScrollBarsByViewPosition()
gtk_adjustment_configure(adjustment,
GetViewX(), // value
0, // lower
GBackWdt, // upper
::Landscape.GetWidth(), // upper
ViewportScrollSpeed, // step_increment
allocation.width / Zoom, // page_increment
allocation.width / Zoom // page_size
@ -139,7 +139,7 @@ bool C4Viewport::ScrollBarsByViewPosition()
gtk_adjustment_configure(adjustment,
GetViewY(), // value
0, // lower
GBackHgt, // upper
::Landscape.GetHeight(), // upper
ViewportScrollSpeed, // step_increment
allocation.height / Zoom, // page_increment
allocation.height / Zoom // page_size

View File

@ -21,6 +21,7 @@
#include <C4Game.h>
#include <C4AulDebug.h>
#include "object/C4Def.h"
#include <C4DefList.h>
#include <C4Effect.h>
#include <C4FileMonitor.h>
@ -65,6 +66,7 @@
#include <C4GraphicsSystem.h>
#include <C4Texture.h>
#include <C4Landscape.h>
#include "landscape/C4Sky.h"
#include <C4PlayerList.h>
#include <C4GameObjects.h>
#include <C4GameControl.h>
@ -913,7 +915,7 @@ void C4Game::ClearPointers(C4Object * pObj)
TransferZones.ClearPointers(pObj);
if (pGlobalEffects)
pGlobalEffects->ClearPointers(pObj);
if (::Landscape.pFoW) ::Landscape.pFoW->Remove(pObj);
::Landscape.ClearPointers(pObj);
}
bool C4Game::TogglePause()
@ -1680,7 +1682,7 @@ void C4Game::CompileFunc(StdCompiler *pComp, CompileSettings comp, C4ValueNumber
{
pComp->Value(mkNamingAdapt(Weather, "Weather"));
pComp->Value(mkNamingAdapt(Landscape, "Landscape"));
pComp->Value(mkNamingAdapt(Landscape.Sky, "Sky"));
pComp->Value(mkNamingAdapt(Landscape.GetSky(), "Sky"));
// save custom GUIs only if a real savegame and not for editor-scenario-saves or section changes
if (!comp.fScenarioSection)
@ -2011,7 +2013,7 @@ bool C4Game::QuickSave(const char *strFilename, const char *strTitle, bool fForc
bool LandscapeFree(int32_t x, int32_t y)
{
if (!Inside<int32_t>(x,0,GBackWdt-1) || !Inside<int32_t>(y,0,GBackHgt-1)) return false;
if (!Inside<int32_t>(x,0,::Landscape.GetWidth()-1) || !Inside<int32_t>(y,0,::Landscape.GetHeight()-1)) return false;
return !DensitySolid(GBackDensity(x,y));
}
@ -2243,7 +2245,7 @@ bool C4Game::InitGame(C4Group &hGroup, bool fLoadSection, bool fLoadSky, C4Value
if (fLoadSection && fLandscapeLoaded) { PXS.Clear(); MassMover.Clear(); }
SetInitProgress(89);
// Init main object list
Objects.Init(Landscape.Width, Landscape.Height);
Objects.Init(Landscape.GetWidth(), Landscape.GetHeight());
// Pathfinder
if (!fLoadSection) PathFinder.Init( &LandscapeFree, &TransferZones );
@ -2618,7 +2620,7 @@ bool C4Game::PlaceInEarth(C4ID id)
int32_t cnt,tx,ty;
for (cnt=0; cnt<35; cnt++) // cheap trys
{
tx=Random(GBackWdt); ty=Random(GBackHgt);
tx=Random(::Landscape.GetWidth()); ty=Random(::Landscape.GetHeight());
if (GBackMat(tx,ty)==MEarth)
if (CreateObject(id,NULL,NO_OWNER,tx,ty,Random(360)))
return true;
@ -2687,7 +2689,7 @@ C4Object* C4Game::PlaceVegetation(C4PropList * PropList, int32_t iX, int32_t iY,
// Above tunnel
while ((iTy>0) && Landscape.GetBackPix(iTx,iTy) == 0) iTy--;
// Above semi solid
if (!AboveSemiSolid(iTx,iTy) || !Inside<int32_t>(iTy,50,GBackHgt-50))
if (!AboveSemiSolid(iTx,iTy) || !Inside<int32_t>(iTy,50,::Landscape.GetHeight()-50))
continue;
// Still inside bounds?
if (!PlaceVegetation_IsPosInBounds(iTx, iTy, iX, iY, iWdt, iHgt, shape_proplist)) continue;
@ -2756,7 +2758,7 @@ C4Object* C4Game::PlaceVegetation(C4PropList * PropList, int32_t iX, int32_t iY,
// Random hit within target area
if (!PlaceVegetation_GetRandomPoint(iX, iY, iWdt, iHgt, shape_proplist, out_pos_proplist, &iTx, &iTy)) break;
// Above semi solid
if (!AboveSemiSolid(iTx,iTy) || !Inside<int32_t>(iTy,50,GBackHgt-50))
if (!AboveSemiSolid(iTx,iTy) || !Inside<int32_t>(iTy,50,::Landscape.GetHeight()-50))
continue;
// Free above
if (GBackSemiSolid(iTx,iTy-pDef->Shape.Hgt) || GBackSemiSolid(iTx,iTy-pDef->Shape.Hgt/2))
@ -2793,12 +2795,12 @@ C4Object* C4Game::PlaceAnimal(C4PropList* PropList)
{
// Running free
case C4D_Place_Surface:
iX=Random(GBackWdt); iY=Random(GBackHgt);
iX=Random(::Landscape.GetWidth()); iY=Random(::Landscape.GetHeight());
if (!FindSolidGround(iX,iY,pDef->Shape.Wdt)) return NULL;
break;
// In liquid
case C4D_Place_Liquid:
iX=Random(GBackWdt); iY=Random(GBackHgt);
iX=Random(::Landscape.GetWidth()); iY=Random(::Landscape.GetHeight());
if (!FindSurfaceLiquid(iX,iY,pDef->Shape.Wdt,pDef->Shape.Hgt))
if (!FindLiquid(iX,iY,pDef->Shape.Wdt,pDef->Shape.Hgt))
return NULL;
@ -2806,8 +2808,8 @@ C4Object* C4Game::PlaceAnimal(C4PropList* PropList)
break;
// Floating in air
case C4D_Place_Air:
iX=Random(GBackWdt);
for (iY=0; (iY<GBackHgt) && !GBackSemiSolid(iX,iY); iY++) {}
iX=Random(::Landscape.GetWidth());
for (iY=0; (iY<::Landscape.GetHeight()) && !GBackSemiSolid(iX,iY); iY++) {}
if (iY<=0) return NULL;
iY=Random(iY);
break;
@ -2824,7 +2826,7 @@ void C4Game::InitInEarth()
int32_t cnt,vidnum;
C4ID vidlist[maxvid];
// Amount
int32_t amt=(GBackWdt*GBackHgt/5000)*C4S.Landscape.InEarthLevel.Evaluate()/100;
int32_t amt=(::Landscape.GetWidth()*::Landscape.GetHeight()/5000)*C4S.Landscape.InEarthLevel.Evaluate()/100;
// List all valid IDs from C4S
vidnum=ListExpandValids(C4S.Landscape.InEarth,vidlist,maxvid);
// Place
@ -2840,13 +2842,13 @@ void C4Game::InitVegetation()
int32_t cnt,vidnum;
C4ID vidlist[maxvid];
// Amount
int32_t amt=(GBackWdt/50)*C4S.Landscape.VegLevel.Evaluate()/100;
int32_t amt=(::Landscape.GetWidth()/50)*C4S.Landscape.VegLevel.Evaluate()/100;
// Get percentage vidlist from C4S
vidnum=ListExpandValids(C4S.Landscape.Vegetation,vidlist,maxvid);
// Place vegetation
if (vidnum>0)
for (cnt=0; cnt<amt; cnt++)
PlaceVegetation(C4Id2Def(vidlist[Random(vidnum)]),0,0,GBackWdt,GBackHgt,-1,NULL,NULL);
PlaceVegetation(C4Id2Def(vidlist[Random(vidnum)]),0,0,::Landscape.GetWidth(),::Landscape.GetHeight(),-1,NULL,NULL);
}
void C4Game::InitAnimals()

View File

@ -43,6 +43,8 @@
#include <C4Weather.h>
#include <C4Viewport.h>
#include <C4FoW.h>
#include "landscape/C4Landscape.h"
#include "landscape/C4Sky.h"
// undocumented!
static bool FnIncinerateLandscape(C4PropList * _this, long iX, long iY, long caused_by_plr)
@ -53,12 +55,12 @@ static bool FnIncinerateLandscape(C4PropList * _this, long iX, long iY, long cau
static void FnSetGravity(C4PropList * _this, long iGravity)
{
::Landscape.Gravity = C4REAL100(Clamp<long>(iGravity,-1000,1000));
::Landscape.SetGravity(C4REAL100(Clamp<long>(iGravity,-1000,1000)));
}
static long FnGetGravity(C4PropList * _this)
{
return fixtoi(::Landscape.Gravity * 100);
return fixtoi(::Landscape.GetGravity() * 100);
}
static C4String *FnGetPlayerName(C4PropList * _this, long iPlayer)
@ -364,9 +366,9 @@ static long FnGetMaterialCount(C4PropList * _this, long iMaterial, bool fReal)
{
if (!MatValid(iMaterial)) return -1;
if (fReal || !::MaterialMap.Map[iMaterial].MinHeightCount)
return ::Landscape.MatCount[iMaterial];
return ::Landscape.GetMatCount(iMaterial);
else
return ::Landscape.EffectiveMatCount[iMaterial];
return ::Landscape.GetEffectiveMatCount(iMaterial);
}
static long FnGetMaterial(C4PropList * _this, long x, long y)
@ -386,7 +388,7 @@ static C4String *FnGetTexture(C4PropList * _this, long x, long y)
if (Object(_this)) { x+=Object(_this)->GetX(); y+=Object(_this)->GetY(); }
// Get texture
int32_t iTex = PixCol2Tex(GBackPix(x, y));
int32_t iTex = PixCol2Tex(::Landscape.GetPix(x, y));
if (!iTex) return NULL;
// Get material-texture mapping
const C4TexMapEntry *pTex = ::TextureMap.GetEntry(iTex);
@ -1211,15 +1213,15 @@ static long FnGetTemperature(C4PropList * _this)
static void FnSetAmbientBrightness(C4PropList * _this, long iBrightness)
{
if (::Landscape.pFoW)
::Landscape.pFoW->Ambient.SetBrightness(iBrightness / 100.);
if (::Landscape.HasFoW())
::Landscape.GetFoW()->Ambient.SetBrightness(iBrightness / 100.);
}
static long FnGetAmbientBrightness(C4PropList * _this)
{
if (!::Landscape.pFoW)
if (!::Landscape.HasFoW())
return 100;
return static_cast<long>(::Landscape.pFoW->Ambient.GetBrightness() * 100. + 0.5);
return static_cast<long>(::Landscape.GetFoW()->Ambient.GetBrightness() * 100. + 0.5);
}
static void FnSetSeason(C4PropList * _this, long iSeason)
@ -1244,12 +1246,12 @@ static long FnGetClimate(C4PropList * _this)
static long FnLandscapeWidth(C4PropList * _this)
{
return GBackWdt;
return ::Landscape.GetWidth();
}
static long FnLandscapeHeight(C4PropList * _this)
{
return GBackHgt;
return ::Landscape.GetHeight();
}
static void FnShakeFree(C4PropList * _this, long x, long y, long rad)
@ -1663,7 +1665,7 @@ static C4String *FnMaterialName(C4PropList * _this, long iMat)
static bool FnSetSkyAdjust(C4PropList * _this, long dwAdjust, long dwBackClr)
{
// set adjust
::Landscape.Sky.SetModulation(dwAdjust, dwBackClr);
::Landscape.GetSky().SetModulation(dwAdjust, dwBackClr);
// success
return true;
}
@ -1679,7 +1681,7 @@ static bool FnSetMatAdjust(C4PropList * _this, long dwAdjust)
static long FnGetSkyAdjust(C4PropList * _this, bool fBackColor)
{
// get adjust
return ::Landscape.Sky.GetModulation(!!fBackColor);
return ::Landscape.GetSky().GetModulation(!!fBackColor);
}
static long FnGetMatAdjust(C4PropList * _this)
@ -1936,13 +1938,13 @@ static bool FnSetSkyParallax(C4PropList * _this, Nillable<long> iMode, Nillable<
{
// set all parameters that aren't nil
if (!iMode.IsNil())
if (Inside<long>(iMode, 0, 1)) ::Landscape.Sky.ParallaxMode = iMode;
if (!iParX.IsNil() && iParX) ::Landscape.Sky.ParX = iParX;
if (!iParY.IsNil() && iParY) ::Landscape.Sky.ParY = iParY;
if (!iXDir.IsNil()) ::Landscape.Sky.xdir = itofix(iXDir);
if (!iYDir.IsNil()) ::Landscape.Sky.ydir = itofix(iYDir);
if (!iX.IsNil()) ::Landscape.Sky.x = itofix(iX);
if (!iY.IsNil()) ::Landscape.Sky.y = itofix(iY);
if (Inside<long>(iMode, 0, 1)) ::Landscape.GetSky().ParallaxMode = iMode;
if (!iParX.IsNil() && iParX) ::Landscape.GetSky().ParX = iParX;
if (!iParY.IsNil() && iParY) ::Landscape.GetSky().ParY = iParY;
if (!iXDir.IsNil()) ::Landscape.GetSky().xdir = itofix(iXDir);
if (!iYDir.IsNil()) ::Landscape.GetSky().ydir = itofix(iYDir);
if (!iX.IsNil()) ::Landscape.GetSky().x = itofix(iX);
if (!iY.IsNil()) ::Landscape.GetSky().y = itofix(iY);
// success
return true;
}

View File

@ -28,6 +28,7 @@
#include <C4LoaderScreen.h>
#include <C4GraphicsResource.h>
#include <C4Landscape.h>
#include "landscape/C4Sky.h"
#include <C4Network2.h>
#include <C4Game.h>
#include <C4GameObjects.h>
@ -229,7 +230,7 @@ bool C4GraphicsSystem::DoSaveScreenshot(bool fSaveAll, const char *szFilename, f
C4Viewport *pVP=::Viewports.GetFirstViewport(); if (!pVP) return false;
// create image large enough to hold the landscape
std::unique_ptr<CPNGFile> png(new CPNGFile());
int32_t lWdt = GBackWdt * zoom, lHgt = GBackHgt * zoom;
int32_t lWdt = ::Landscape.GetWidth() * zoom, lHgt = ::Landscape.GetHeight() * zoom;
if (!png->Create(lWdt, lHgt, false)) return false;
// get backbuffer size
int32_t bkWdt=C4GUI::GetScreenWdt(), bkHgt=C4GUI::GetScreenHgt();
@ -241,8 +242,8 @@ bool C4GraphicsSystem::DoSaveScreenshot(bool fSaveAll, const char *szFilename, f
// draw on one big viewport
pVP->SetOutputSize(0,0,0,0, bkWdt, bkHgt);
// backup and clear sky parallaxity
int32_t iParX=::Landscape.Sky.ParX; ::Landscape.Sky.ParX=10;
int32_t iParY=::Landscape.Sky.ParY; ::Landscape.Sky.ParY=10;
int32_t iParX=::Landscape.GetSky().ParX; ::Landscape.GetSky().ParX=10;
int32_t iParY=::Landscape.GetSky().ParY; ::Landscape.GetSky().ParY=10;
// backup and clear viewport borders
FLOAT_RECT vp_borders = { pVP->BorderLeft, pVP->BorderRight, pVP->BorderTop, pVP->BorderBottom };
pVP->BorderLeft = pVP->BorderRight = pVP->BorderTop = pVP->BorderBottom = 0.0f;
@ -288,8 +289,8 @@ bool C4GraphicsSystem::DoSaveScreenshot(bool fSaveAll, const char *szFilename, f
pVP->BorderRight = vp_borders.right;
pVP->BorderBottom = vp_borders.bottom;
// restore parallaxity
::Landscape.Sky.ParX=iParX;
::Landscape.Sky.ParY=iParY;
::Landscape.GetSky().ParX=iParX;
::Landscape.GetSky().ParY=iParY;
// restore viewport size
::Viewports.RecalculateViewports();
// save!

View File

@ -26,7 +26,7 @@ const int StableRange=10;
const int AttachRange=5;
const int CornerRange=AttachRange+2;
#define GravAccel (::Landscape.Gravity)
#define GravAccel ::Landscape.GetGravity()
extern const C4Real HitSpeed1,HitSpeed2,HitSpeed3,HitSpeed4;
extern const C4Real FloatFriction;

View File

@ -22,6 +22,7 @@
#include <C4ViewportWindow.h>
#include <C4Console.h>
#include "object/C4Def.h"
#include <C4Object.h>
#include <C4FullScreen.h>
#include <C4Stat.h>
@ -34,6 +35,7 @@
#include <C4GraphicsResource.h>
#include <C4GraphicsSystem.h>
#include <C4Landscape.h>
#include "landscape/C4Sky.h"
#include <C4PlayerList.h>
#include <C4GameObjects.h>
#include <C4Network2.h>
@ -260,7 +262,7 @@ void C4Viewport::Draw(C4TargetFacet &cgo0, bool fDrawGame, bool fDrawOverlay)
pDraw->SetFoW(pFoW);
C4ST_STARTNEW(SkyStat, "C4Viewport::Draw: Sky")
::Landscape.Sky.Draw(cgo);
::Landscape.GetSky().Draw(cgo);
C4ST_STOP(SkyStat)
::Objects.Draw(cgo, Player, -2147483647 - 1 /* INT32_MIN */, 0);
@ -411,7 +413,7 @@ void C4Viewport::CalculateZoom()
if (plr)
plr->ZoomLimitsToViewport(this);
else
SetZoomLimits(0.8*std::min<float>(float(ViewWdt)/GBackWdt,float(ViewHgt)/GBackHgt), 8);
SetZoomLimits(0.8*std::min<float>(float(ViewWdt)/::Landscape.GetWidth(),float(ViewHgt)/::Landscape.GetHeight()), 8);
}
@ -424,7 +426,7 @@ void C4Viewport::InitZoom()
}
else
{
ZoomTarget = std::max<float>(float(ViewWdt)/GBackWdt, 1.0f);
ZoomTarget = std::max<float>(float(ViewWdt)/::Landscape.GetWidth(), 1.0f);
Zoom = ZoomTarget;
}
}
@ -556,13 +558,13 @@ void C4Viewport::AdjustPosition(bool immediate)
// if view is close to border, allow scrolling
if (targetCenterViewX < ViewportScrollBorder) extraBoundsX = std::min<float>(ViewportScrollBorder - targetCenterViewX, ViewportScrollBorder);
else if (targetCenterViewX >= GBackWdt - ViewportScrollBorder) extraBoundsX = std::min<float>(targetCenterViewX - GBackWdt, 0) + ViewportScrollBorder;
else if (targetCenterViewX >= ::Landscape.GetWidth() - ViewportScrollBorder) extraBoundsX = std::min<float>(targetCenterViewX - ::Landscape.GetWidth(), 0) + ViewportScrollBorder;
if (targetCenterViewY < ViewportScrollBorder) extraBoundsY = std::min<float>(ViewportScrollBorder - targetCenterViewY, ViewportScrollBorder);
else if (targetCenterViewY >= GBackHgt - ViewportScrollBorder) extraBoundsY = std::min<float>(targetCenterViewY - GBackHgt, 0) + ViewportScrollBorder;
else if (targetCenterViewY >= ::Landscape.GetHeight() - ViewportScrollBorder) extraBoundsY = std::min<float>(targetCenterViewY - ::Landscape.GetHeight(), 0) + ViewportScrollBorder;
}
extraBoundsX = std::max(extraBoundsX, (ViewWdt/Zoom - GBackWdt)/2 + 1);
extraBoundsY = std::max(extraBoundsY, (ViewHgt/Zoom - GBackHgt)/2 + 1);
extraBoundsX = std::max(extraBoundsX, (ViewWdt/Zoom - ::Landscape.GetWidth())/2 + 1);
extraBoundsY = std::max(extraBoundsY, (ViewHgt/Zoom - ::Landscape.GetHeight())/2 + 1);
// add mouse auto scroll
if (pPlr->MouseControl && ::MouseControl.InitCentered && Config.Controls.MouseAutoScroll)
@ -579,8 +581,8 @@ void C4Viewport::AdjustPosition(bool immediate)
targetCenterViewY = Clamp(targetCenterViewY, targetCenterViewY - scrollRange, targetCenterViewY + scrollRange);
}
// bounds
targetCenterViewX = Clamp(targetCenterViewX, ViewWdt/Zoom/2 - extraBoundsX, GBackWdt - ViewWdt/Zoom/2 + extraBoundsX);
targetCenterViewY = Clamp(targetCenterViewY, ViewHgt/Zoom/2 - extraBoundsY, GBackHgt - ViewHgt/Zoom/2 + extraBoundsY);
targetCenterViewX = Clamp(targetCenterViewX, ViewWdt/Zoom/2 - extraBoundsX, ::Landscape.GetWidth() - ViewWdt/Zoom/2 + extraBoundsX);
targetCenterViewY = Clamp(targetCenterViewY, ViewHgt/Zoom/2 - extraBoundsY, ::Landscape.GetHeight() - ViewHgt/Zoom/2 + extraBoundsY);
targetViewX = targetCenterViewX - ViewWdt/Zoom/2 + viewOffsX;
targetViewY = targetCenterViewY - ViewHgt/Zoom/2 + viewOffsY;
@ -610,20 +612,20 @@ void C4Viewport::CenterPosition()
{
// center viewport position on map
// set center position
SetViewX(GBackWdt/2 + ViewWdt/Zoom/2);
SetViewY(GBackHgt/2 + ViewHgt/Zoom/2);
SetViewX(::Landscape.GetWidth()/2 + ViewWdt/Zoom/2);
SetViewY(::Landscape.GetHeight()/2 + ViewHgt/Zoom/2);
}
void C4Viewport::UpdateBordersX()
{
BorderLeft = std::max(-GetViewX() * Zoom, 0.0f);
BorderRight = std::max(ViewWdt - GBackWdt * Zoom + GetViewX() * Zoom, 0.0f);
BorderRight = std::max(ViewWdt - ::Landscape.GetWidth() * Zoom + GetViewX() * Zoom, 0.0f);
}
void C4Viewport::UpdateBordersY()
{
BorderTop = std::max(-GetViewY() * Zoom, 0.0f);
BorderBottom = std::max(ViewHgt - GBackHgt * Zoom + GetViewY() * Zoom, 0.0f);
BorderBottom = std::max(ViewHgt - ::Landscape.GetHeight() * Zoom + GetViewY() * Zoom, 0.0f);
}
void C4Viewport::DrawPlayerInfo(C4TargetFacet &cgo)
@ -673,9 +675,9 @@ void C4Viewport::DisableFoW()
void C4Viewport::EnableFoW()
{
if (::Landscape.pFoW && Player != NO_OWNER)
if (::Landscape.HasFoW() && Player != NO_OWNER)
{
pFoW.reset(new C4FoWRegion(::Landscape.pFoW, ::Players.Get(Player)));
pFoW.reset(new C4FoWRegion(::Landscape.GetFoW(), ::Players.Get(Player)));
}
else
{
@ -722,13 +724,13 @@ void C4Viewport::SetViewX(float x)
if (fIsNoOwnerViewport)
{
if(GBackWdt < ViewWdt / Zoom)
if(::Landscape.GetWidth() < ViewWdt / Zoom)
{
viewX = GBackWdt/2 - ViewWdt / Zoom / 2;
viewX = ::Landscape.GetWidth()/2 - ViewWdt / Zoom / 2;
}
else
{
viewX = Clamp(x, 0.0f, GBackWdt - ViewWdt / Zoom);
viewX = Clamp(x, 0.0f, ::Landscape.GetWidth() - ViewWdt / Zoom);
}
}
@ -741,13 +743,13 @@ void C4Viewport::SetViewY(float y)
if (fIsNoOwnerViewport)
{
if(GBackHgt < ViewHgt / Zoom)
if(::Landscape.GetHeight() < ViewHgt / Zoom)
{
viewY = GBackHgt/2 - ViewHgt / Zoom / 2;
viewY = ::Landscape.GetHeight()/2 - ViewHgt / Zoom / 2;
}
else
{
viewY = Clamp(y, 0.0f, GBackHgt - ViewHgt / Zoom);
viewY = Clamp(y, 0.0f, ::Landscape.GetHeight() - ViewHgt / Zoom);
}
}

View File

@ -227,6 +227,7 @@ bool CStdGL::PrepareSpriteShader(C4Shader& shader, const char* name, int ssc, C4
uniformNames[C4SSU_MaterialShininess] = "materialShininess"; // unused
uniformNames[C4SSU_Bones] = "bones"; // unused
uniformNames[C4SSU_CullMode] = "cullMode"; // unused
uniformNames[C4SSU_FrameCounter] = "frameCounter";
uniformNames[C4SSU_Count] = NULL;
const char* attributeNames[C4SSA_Count + 1];

View File

@ -77,6 +77,8 @@ enum C4SS_Uniforms
C4SSU_Bones, // for meshes
C4SSU_CullMode, // for meshes
C4SSU_FrameCounter, // for custom shaders
C4SSU_Count
};

View File

@ -397,7 +397,7 @@ int32_t mouseButtonFromEvent(NSEvent* event, DWORD* modifierFlags)
if (Application.isEditor && viewport && !viewport->GetPlayerLock())
{
NSScrollView* scrollView = self.controller.scrollView;
NSPoint p = NSMakePoint(2*-[event deltaX]/abs(GBackWdt-viewport->ViewWdt), 2*-[event deltaY]/abs(GBackHgt-viewport->ViewHgt));
NSPoint p = NSMakePoint(2*-[event deltaX]/abs(::Landscape.GetWidth()-viewport->ViewWdt), 2*-[event deltaY]/abs(::Landscape.GetHeight()-viewport->ViewHgt));
[scrollView.horizontalScroller setDoubleValue:scrollView.horizontalScroller.doubleValue+p.x];
[scrollView.verticalScroller setDoubleValue:scrollView.verticalScroller.doubleValue+p.y];
viewport->ViewPositionByScrollBars();

View File

@ -395,7 +395,7 @@ bool CStdGL::PrepareMaterial(StdMeshMatManager& mat_manager, StdMeshMaterialLoad
{
StdStrBuf buf = GetVertexShaderCodeForPass(pass, Workarounds.LowMaxVertexUniformCount);
StdStrBuf hash = GetSHA1HexDigest(buf.getData(), buf.getLength());
pass.VertexShader.Shader = mat_manager.AddShader("auto-generated vertex shader", hash.getData(), "glsl", SMMS_VERTEX, buf.getData(), true);
pass.VertexShader.Shader = mat_manager.AddShader("auto-generated vertex shader", hash.getData(), "glsl", SMMS_VERTEX, buf.getData(), StdMeshMatManager::SMM_AcceptExisting);
custom_shader = false;
}
@ -404,7 +404,7 @@ bool CStdGL::PrepareMaterial(StdMeshMatManager& mat_manager, StdMeshMaterialLoad
// TODO: Should use shared_params once we introduce them
StdStrBuf buf = GetFragmentShaderCodeForPass(pass, pass.FragmentShader.Parameters);
StdStrBuf hash = GetSHA1HexDigest(buf.getData(), buf.getLength());
pass.FragmentShader.Shader = mat_manager.AddShader("auto-generated fragment shader", hash.getData(), "glsl", SMMS_FRAGMENT, buf.getData(), true);
pass.FragmentShader.Shader = mat_manager.AddShader("auto-generated fragment shader", hash.getData(), "glsl", SMMS_FRAGMENT, buf.getData(), StdMeshMatManager::SMM_AcceptExisting);
}
// Then, link the program, and resolve parameter locations
@ -418,7 +418,7 @@ bool CStdGL::PrepareMaterial(StdMeshMatManager& mat_manager, StdMeshMaterialLoad
{
StdStrBuf buf = GetVertexShaderCodeForPass(pass, true);
StdStrBuf hash = GetSHA1HexDigest(buf.getData(), buf.getLength());
pass.VertexShader.Shader = mat_manager.AddShader("auto-generated vertex shader", hash.getData(), "glsl", SMMS_VERTEX, buf.getData(), true);
pass.VertexShader.Shader = mat_manager.AddShader("auto-generated vertex shader", hash.getData(), "glsl", SMMS_VERTEX, buf.getData(), StdMeshMatManager::SMM_AcceptExisting);
added_program = mat_manager.AddProgram(name.getData(), loader, pass.FragmentShader, pass.VertexShader, pass.GeometryShader);
if(added_program)
@ -538,6 +538,9 @@ namespace
pFoW->getFoW()->Ambient.GetFragTransform(pFoW->getViewportRegion(), clipRect, outRect, ambientTransform);
call.SetUniformMatrix2x3fv(C4SSU_AmbientTransform, 1, ambientTransform);
}
// Current frame counter
call.SetUniform1i(C4SSU_FrameCounter, ::Game.FrameCounter);
}
bool ResolveAutoParameter(C4ShaderCall& call, StdMeshMaterialShaderParameter& parameter, StdMeshMaterialShaderParameter::Auto value, DWORD dwModClr, DWORD dwPlayerColor, DWORD dwBlitMode, const C4FoWRegion* pFoW, const C4Rect& clipRect)

View File

@ -56,6 +56,13 @@ C4Shader::~C4Shader()
Clear();
}
int C4Shader::GetSourceFileId(const char *file) const
{
auto it = std::find(SourceFiles.begin(), SourceFiles.end(), file);
if (it == SourceFiles.end()) return -1;
return std::distance(SourceFiles.begin(), it);
}
void C4Shader::AddDefine(const char* name)
{
StdStrBuf define = FormatString("#define %s", name);
@ -65,12 +72,12 @@ void C4Shader::AddDefine(const char* name)
void C4Shader::AddVertexSlice(int iPos, const char *szText)
{
AddSlice(VertexSlices, iPos, szText, NULL, 0);
AddSlice(VertexSlices, iPos, szText, NULL, 0, 0);
}
void C4Shader::AddFragmentSlice(int iPos, const char *szText, const char *szSource, int iSourceTime)
void C4Shader::AddFragmentSlice(int iPos, const char *szText)
{
AddSlice(FragmentSlices, iPos, szText, szSource, iSourceTime);
AddSlice(FragmentSlices, iPos, szText, NULL, 0, 0);
}
void C4Shader::AddVertexSlices(const char *szWhat, const char *szText, const char *szSource, int iSourceTime)
@ -93,26 +100,31 @@ bool C4Shader::LoadVertexSlices(C4GroupSet *pGroups, const char *szFile)
return LoadSlices(VertexSlices, pGroups, szFile);
}
void C4Shader::AddSlice(ShaderSliceList& slices, int iPos, const char *szText, const char *szSource, int iSourceTime)
void C4Shader::AddSlice(ShaderSliceList& slices, int iPos, const char *szText, const char *szSource, int line, int iSourceTime)
{
ShaderSlice Slice;
Slice.Position = iPos;
Slice.Text.Copy(szText);
Slice.Source = szSource;
Slice.SourceTime = iSourceTime;
Slice.SourceLine = line;
slices.push_back(Slice);
}
void C4Shader::AddSlices(ShaderSliceList& slices, const char *szWhat, const char *szText, const char *szSource, int iSourceTime)
{
if (std::find(SourceFiles.cbegin(), SourceFiles.cend(), szSource) == SourceFiles.cend())
SourceFiles.push_back(szSource);
const char *pStart = szText, *pPos = szText;
int iDepth = -1;
int iPosition = -1;
bool fGotContent = false; // Anything in the slice apart from comments and white-space?
#define SKIP_WHITESPACE do { while(isspace(*pPos)) { ++pPos; } } while (0)
// Find slices
while(*pPos) {
// Comment? Might seem silly, but we don't want to get confused by braces in comments...
if (*pPos == '/' && *(pPos + 1) == '/') {
pPos += 2;
@ -121,7 +133,10 @@ void C4Shader::AddSlices(ShaderSliceList& slices, const char *szWhat, const char
}
if (*pPos == '/' && *(pPos + 1) == '*') {
pPos += 2;
while (*pPos && (*pPos != '*' || *(pPos+1) != '/')) pPos++;
while (*pPos && (*pPos != '*' || *(pPos + 1) != '/'))
{
pPos++;
}
if (*pPos) pPos += 2;
continue;
}
@ -139,7 +154,7 @@ void C4Shader::AddSlices(ShaderSliceList& slices, const char *szWhat, const char
if (fGotContent)
{
StdStrBuf Str; Str.Copy(pStart, pPos - pStart);
AddSlice(slices, iPosition, Str.getData(), szSource, iSourceTime);
AddSlice(slices, iPosition, Str.getData(), szSource, SGetLine(szText, pStart), iSourceTime);
}
iPosition = -1;
@ -158,7 +173,7 @@ void C4Shader::AddSlices(ShaderSliceList& slices, const char *szWhat, const char
if (*pPos == '\n') {
if (SEqual2(pPos+1, "slice") && !isalnum(*(pPos+6))) {
const char *pSliceEnd = pPos; pPos += 6;
while(isspace(*pPos)) pPos++;
SKIP_WHITESPACE;
if(*pPos != '(') { pPos++; continue; }
pPos++;
@ -166,19 +181,19 @@ void C4Shader::AddSlices(ShaderSliceList& slices, const char *szWhat, const char
iPosition = ParsePosition(szWhat, &pPos);
if (iPosition != -1) {
// Make sure a closing parenthesis
while(isspace(*pPos)) pPos++;
SKIP_WHITESPACE;
if(*pPos != ')') { pPos++; continue; }
pPos++;
// Make sure an opening brace follows
while(isspace(*pPos)) pPos++;
SKIP_WHITESPACE;
if (*pPos == '{') {
// Add code before "slice" as new slice
if (fGotContent)
{
StdStrBuf Str; Str.Copy(pStart, pSliceEnd - pStart);
AddSlice(slices, -1, Str.getData(), szSource, iSourceTime);
AddSlice(slices, -1, Str.getData(), szSource, SGetLine(szText, pSliceEnd), iSourceTime);
}
iDepth = 0;
@ -202,9 +217,9 @@ void C4Shader::AddSlices(ShaderSliceList& slices, const char *szWhat, const char
if (fGotContent)
{
StdStrBuf Str; Str.Copy(pStart, pPos - pStart);
AddSlice(slices, iPosition, Str.getData(), szSource, iSourceTime);
AddSlice(slices, iPosition, Str.getData(), szSource, SGetLine(szText, pStart), iSourceTime);
}
#undef SKIP_WHITESPACE
}
int C4Shader::ParsePosition(const char *szWhat, const char **ppPos)
@ -459,7 +474,6 @@ bool C4Shader::Refresh()
StdStrBuf C4Shader::Build(const ShaderSliceList &Slices, bool fDebug)
{
// At the start of the shader set the #version and number of
// available uniforms
StdStrBuf Buf;
@ -495,9 +509,12 @@ StdStrBuf C4Shader::Build(const ShaderSliceList &Slices, bool fDebug)
if (fDebug)
{
if (pSlice->Source.getLength())
Buf.AppendFormat("\t// Slice from %s:\n", pSlice->Source.getData());
{
// GLSL below 3.30 consider the line after a #line N directive to be N + 1; 3.30 and higher consider it N
Buf.AppendFormat("\t// Slice from %s:\n#line %d %d\n", pSlice->Source.getData(), pSlice->SourceLine - (C4Shader_Version < 330), GetSourceFileId(pSlice->Source.getData()) + 1);
}
else
Buf.Append("\t// Built-in slice:\n");
Buf.Append("\t// Built-in slice:\n#line 1 0\n");
}
Buf.Append(pSlice->Text);
if (Buf[Buf.getLength()-1] != '\n')
@ -512,6 +529,10 @@ StdStrBuf C4Shader::Build(const ShaderSliceList &Slices, bool fDebug)
// Terminate
Buf.Append("}\n");
Buf.Append("// File number to name mapping:\n//\t 0: <built-in shader code>\n");
for (int i = 0; i < SourceFiles.size(); ++i)
Buf.AppendFormat("//\t%3d: %s\n", i + 1, SourceFiles[i].c_str());
return Buf;
}

View File

@ -70,10 +70,14 @@ private:
int Position;
StdCopyStrBuf Text;
StdCopyStrBuf Source;
int SourceLine;
int SourceTime;
};
typedef std::list<ShaderSlice> ShaderSliceList;
ShaderSliceList VertexSlices, FragmentSlices;
std::vector<std::string> SourceFiles;
int GetSourceFileId(const char *file) const;
// Last refresh check
C4TimeMilliseconds LastRefresh;
@ -135,7 +139,7 @@ public:
// Shader is composed from various slices
void AddDefine(const char* name);
void AddVertexSlice(int iPos, const char *szText);
void AddFragmentSlice(int iPos, const char *szText, const char *szSource = "", int iFileTime = 0);
void AddFragmentSlice(int iPos, const char *szText);
void AddVertexSlices(const char *szWhat, const char *szText, const char *szSource = "", int iFileTime = 0);
void AddFragmentSlices(const char *szWhat, const char *szText, const char *szSource = "", int iFileTime = 0);
bool LoadFragmentSlices(C4GroupSet *pGroupSet, const char *szFile);
@ -149,7 +153,7 @@ public:
void Clear();
private:
void AddSlice(ShaderSliceList& slices, int iPos, const char *szText, const char *szSource, int iFileTime);
void AddSlice(ShaderSliceList& slices, int iPos, const char *szText, const char *szSource, int line, int iFileTime);
void AddSlices(ShaderSliceList& slices, const char *szWhat, const char *szText, const char *szSource, int iFileTime);
bool LoadSlices(ShaderSliceList& slices, C4GroupSet *pGroupSet, const char *szFile);
int ParsePosition(const char *szWhat, const char **ppPos);

View File

@ -192,7 +192,7 @@ void CSurface8::MapBytes(BYTE *bpMap)
for (int cnt=0; cnt<Wdt*Hgt; cnt++) SetPix(cnt%Wdt, cnt/Wdt, bpMap[GetPix(cnt%Wdt, cnt/Wdt)]);
}
void CSurface8::GetSurfaceSize(int &irX, int &irY)
void CSurface8::GetSurfaceSize(int &irX, int &irY) const
{
// simply assign stored values
irX=Wdt;

View File

@ -62,7 +62,7 @@ public:
void NoClip();
bool Read(class CStdStream &hGroup);
bool Save(const char *szFilename, CStdPalette * = NULL);
void GetSurfaceSize(int &irX, int &irY); // get surface size
void GetSurfaceSize(int &irX, int &irY) const; // get surface size
void AllowColor(BYTE iRngLo, BYTE iRngHi, bool fAllowZero=false);
void SetBuffer(BYTE *pbyToBuf, int Wdt, int Hgt, int Pitch);
void ReleaseBuffer();

View File

@ -20,6 +20,7 @@
#include <C4Include.h>
#include <C4GameMessage.h>
#include "object/C4Def.h"
#include <C4Object.h>
#include <C4GraphicsResource.h>
#include <C4Player.h>

View File

@ -20,6 +20,7 @@
#include <C4Include.h>
#include <C4Menu.h>
#include "object/C4Def.h"
#include <C4DefList.h>
#include <C4Object.h>
#include <C4Viewport.h>

View File

@ -21,6 +21,7 @@
#include <C4MouseControl.h>
#include <C4Viewport.h>
#include "object/C4Def.h"
#include <C4Object.h>
#include <C4Application.h>
#include <C4FullScreen.h>
@ -804,7 +805,7 @@ void C4MouseControl::UpdateFogOfWar()
// Check for fog of war
// TODO: Check C4FoWRegion... should maybe be passed as a parameter?
// pDraw->GetFoW() might not be current at this time.
if (/*(pPlayer->fFogOfWar && !pPlayer->FoWIsVisible(int32_t(GameX),int32_t(GameY))) || */GameX<0 || GameY<0 || int32_t(GameX)>=GBackWdt || int32_t(GameY)>=GBackHgt)
if (/*(pPlayer->fFogOfWar && !pPlayer->FoWIsVisible(int32_t(GameX),int32_t(GameY))) || */GameX<0 || GameY<0 || int32_t(GameX)>=::Landscape.GetWidth() || int32_t(GameY)>=::Landscape.GetHeight())
{
FogOfWar=true;
// allow dragging, scrolling, region selection and manipulations of objects not affected by FoW

View File

@ -30,6 +30,7 @@
#include <C4ScriptGuiWindow.h>
#include <C4Application.h>
#include "object/C4Def.h"
#include <C4DefList.h>
#include <C4GraphicsSystem.h>
#include <C4GraphicsResource.h>

View File

@ -855,11 +855,6 @@ C4StartupOptionsDlg::C4StartupOptionsDlg() : C4StartupDlg(LoadResStrNoAmp("IDS_D
pCheck->SetToolTip(LoadResStr("IDS_MSG_FIREPARTICLES_DESC"));
pCheck->SetFont(pUseFont, C4StartupFontClr, C4StartupFontClrDisabled);
pGroupOptions->AddElement(pCheck);
// high resolution landscape
pCheck = new BoolConfig(caGroupOptions.GetGridCell(0,1,iOpt++,iNumGfxOptions,-1,iCheckHgt,true), LoadResStr("IDS_MSG_HIGHRESLANDSCAPE"), NULL, &Config.Graphics.HighResLandscape);
pCheck->SetToolTip(LoadResStr("IDS_MSG_HIGHRESLANDSCAPE_DESC"));
pCheck->SetFont(pUseFont, C4StartupFontClr, C4StartupFontClrDisabled);
pGroupOptions->AddElement(pCheck);
// automatic gfx frame skip
pCheck = new BoolConfig(caGroupOptions.GetGridCell(0,1,iOpt++,iNumGfxOptions,-1,iCheckHgt,true), LoadResStr("IDS_MSG_AUTOFRAMESKIP"), NULL, &Config.Graphics.AutoFrameSkip);
pCheck->SetToolTip(LoadResStr("IDS_DESC_AUTOFRAMESKIP"));

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,7 @@
*
* Copyright (c) 1998-2000, Matthes Bender
* Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
* Copyright (c) 2009-2013, The OpenClonk Team and contributors
* Copyright (c) 2009-2016, The OpenClonk Team and contributors
*
* Distributed under the terms of the ISC license; see accompanying file
* "COPYING" for details.
@ -20,61 +20,30 @@
#ifndef INC_C4Landscape
#define INC_C4Landscape
#include "C4Sky.h"
#include "C4Shape.h"
#include <CSurface8.h>
#include <C4Material.h>
#include "C4Prototypes.h"
#include "C4Constants.h"
const int32_t C4MaxMaterial = 125;
const int32_t C4LSC_Undefined = 0,
C4LSC_Dynamic = 1,
C4LSC_Static = 2,
C4LSC_Exact = 3;
const int32_t C4LS_MaxRelights = 50;
enum class LandscapeMode
{
Undefined = 0,
Dynamic = 1,
Static = 2,
Exact = 3
};
class C4Landscape
{
struct P;
std::unique_ptr<P> p;
public:
C4Landscape();
~C4Landscape();
public:
int32_t Mode;
int32_t Width,Height;
int32_t MapWidth,MapHeight,MapZoom;
DWORD MatCount[C4MaxMaterial]; // NoSave //
DWORD EffectiveMatCount[C4MaxMaterial]; // NoSave //
bool NoScan; // ExecuteScan() disabled
int32_t ScanX,ScanSpeed; // SyncClearance-NoSave //
int32_t LeftOpen,RightOpen,TopOpen,BottomOpen;
C4Real Gravity;
uint32_t Modulation; // landscape blit modulation; 0 means normal
int32_t MapSeed; // random seed for MapToLandscape
C4Sky Sky;
C4MapCreatorS2 *pMapCreator; // map creator for script-generated maps
bool fMapChanged;
BYTE *pInitial; // Initial landscape after creation - used for diff
BYTE *pInitialBkg; // Initial bkg landscape after creation - used for diff
class C4FoW *pFoW;
private:
CSurface8 * Surface8;
CSurface8 * Surface8Bkg; // Background material
CSurface8 * Map;
CSurface8 * MapBkg;
class C4LandscapeRender *pLandscapeRender;
uint8_t *TopRowPix, *BottomRowPix; // array size of landscape width: Filled with 0s for border pixels that are open and MCVehic for pixels that are closed
int32_t Pix2Mat[C4M_MaxTexIndex], Pix2Dens[C4M_MaxTexIndex], Pix2Place[C4M_MaxTexIndex];
bool Pix2Light[C4M_MaxTexIndex];
int32_t PixCntPitch;
uint8_t *PixCnt;
C4Rect Relights[C4LS_MaxRelights];
mutable uint8_t *BridgeMatConversion[C4M_MaxTexIndex]; // NoSave //
public:
// Use this with the various drawing functions to keep current material for
// either foreground or background map. We can use C4M_MaxTexIndex as a value
// here because this value is reserved anyway for the differential landscape
@ -85,11 +54,9 @@ public:
void Clear(bool fClearMapCreator=true, bool fClearSky=true, bool fClearRenderer=true);
void Execute();
void Synchronize();
void Draw(C4TargetFacet &cgo, class C4FoWRegion *pLight = NULL);
void Draw(C4TargetFacet &cgo, class C4FoWRegion *pLight = nullptr);
void ScenarioInit();
void ClearRectDensity(int32_t iTx, int32_t iTy, int32_t iWdt, int32_t iHgt, int32_t iOfDensity);
void ClearMatCount();
void ScanSideOpen();
void DrawMaterialRect(int32_t mat, int32_t tx, int32_t ty, int32_t wdt, int32_t hgt);
@ -105,10 +72,13 @@ public:
bool SaveInitial();
bool SaveTextures(C4Group &hGroup) const;
bool Init(C4Group &hGroup, bool fOverloadCurrent, bool fLoadSky, bool &rfLoaded, bool fSavegame);
bool HasMap() const { return Map != NULL && MapBkg != NULL; }
bool HasMap() const;
bool MapToLandscape();
bool ApplyDiff(C4Group &hGroup);
bool SetMode(int32_t iMode);
void SetMode(LandscapeMode iMode);
LandscapeMode GetMode() const;
bool SetPix2(int32_t x, int32_t y, BYTE fgPix, BYTE bgPix); // set landscape pixel (bounds checked)
bool _SetPix2(int32_t x, int32_t y, BYTE fgPix, BYTE bgPix); // set landsape pixel (bounds not checked)
void _SetPix2Tmp(int32_t x, int32_t y, BYTE fgPix, BYTE bgPix); // set landsape pixel (bounds not checked, no material count updates, no landscape relighting). Material must be reset to original value with this function before modifying landscape in any other way. Only used for temporary pixel changes by SolidMask (C4SolidMask::RemoveTemporary, C4SolidMask::PutTemporary).
@ -125,138 +95,40 @@ public:
bool DrawChunks(int32_t tx, int32_t ty, int32_t wdt, int32_t hgt, int32_t icntx, int32_t icnty, const char *szMaterial, const char *szTexture, bool bIFT);
bool DrawQuad(int32_t iX1, int32_t iY1, int32_t iX2, int32_t iY2, int32_t iX3, int32_t iY3, int32_t iX4, int32_t iY4, const char *szMaterial, const char *szBackMaterial, bool fDrawBridge);
bool DrawPolygon(int *vtcs, int length, const char *szMaterial, const char *szBackMaterial, bool fDrawBridge);
CStdPalette *GetPal() const { return Surface8 ? Surface8->pPal : NULL; }
inline BYTE _GetPix(int32_t x, int32_t y) const // get landscape pixel (bounds not checked)
{
#ifdef _DEBUG
if (x<0 || y<0 || x>=Width || y>=Height) { BREAKPOINT_HERE; }
#endif
return Surface8->_GetPix(x,y);
}
inline BYTE GetPix(int32_t x, int32_t y) const // get landscape pixel (bounds checked)
{
extern BYTE MCVehic;
// Border checks
if (x<0)
{
if (y<LeftOpen) return 0;
else return MCVehic;
}
if (static_cast<uint32_t>(x) >= static_cast<uint32_t>(Width))
{
if (y<RightOpen) return 0;
else return MCVehic;
}
if (y<0)
{
return TopRowPix[x];
}
if (static_cast<uint32_t>(y) >= static_cast<uint32_t>(Height))
{
return BottomRowPix[x];
}
return Surface8->_GetPix(x,y);
}
inline int32_t _GetMat(int32_t x, int32_t y) const // get landscape material (bounds not checked)
{
return Pix2Mat[_GetPix(x, y)];
}
inline int32_t _GetDensity(int32_t x, int32_t y) const // get landscape density (bounds not checked)
{
return Pix2Dens[_GetPix(x, y)];
}
inline int32_t _GetPlacement(int32_t x, int32_t y) const // get landscape material placement (bounds not checked)
{
return Pix2Place[_GetPix(x, y)];
}
inline int32_t GetMat(int32_t x, int32_t y) const // get landscape material (bounds checked)
{
return Pix2Mat[GetPix(x, y)];
}
inline int32_t GetDensity(int32_t x, int32_t y) const // get landscape density (bounds checked)
{
return Pix2Dens[GetPix(x, y)];
}
inline int32_t GetPlacement(int32_t x, int32_t y) const // get landscape material placement (bounds checked)
{
return Pix2Place[GetPix(x, y)];
}
CStdPalette *GetPal() const;
int32_t GetWidth() const;
int32_t GetHeight() const;
int32_t GetMapZoom() const;
C4Real GetGravity() const;
void SetGravity(C4Real g);
inline BYTE _GetBackPix(int32_t x, int32_t y) const // get landscape pixel (bounds not checked)
{
#ifdef _DEBUG
if (x<0 || y<0 || x>=Width || y>=Height) { BREAKPOINT_HERE; }
#endif
return Surface8Bkg->_GetPix(x,y);
}
inline BYTE GetBackPix(int32_t x, int32_t y) const // get landscape pixel (bounds checked)
{
// Border checks
if (x<0)
{
if (y<LeftOpen) return 0;
else return Mat2PixColDefault(MTunnel);
}
if (static_cast<uint32_t>(x) >= static_cast<uint32_t>(Width))
{
if (y<RightOpen) return 0;
else return Mat2PixColDefault(MTunnel);
}
if (y<0)
{
return DefaultBkgMat(TopRowPix[x]);
}
if (static_cast<uint32_t>(y) >= static_cast<uint32_t>(Height))
{
return DefaultBkgMat(BottomRowPix[x]);
}
BYTE _GetPix(int32_t x, int32_t y) const; // get landscape pixel (bounds not checked)
BYTE GetPix(int32_t x, int32_t y) const;
int32_t _GetMat(int32_t x, int32_t y) const;
int32_t _GetDensity(int32_t x, int32_t y) const;
int32_t _GetPlacement(int32_t x, int32_t y) const;
int32_t GetMat(int32_t x, int32_t y) const;
int32_t GetDensity(int32_t x, int32_t y) const;
int32_t GetPlacement(int32_t x, int32_t y) const;
return Surface8Bkg->_GetPix(x,y);
}
inline int32_t _GetBackMat(int32_t x, int32_t y) const // get landscape material (bounds not checked)
{
return Pix2Mat[_GetBackPix(x, y)];
}
inline int32_t _GetBackDensity(int32_t x, int32_t y) const // get landscape density (bounds not checked)
{
return Pix2Dens[_GetBackPix(x, y)];
}
inline int32_t _GetBackPlacement(int32_t x, int32_t y) const // get landscape material placement (bounds not checked)
{
return Pix2Place[_GetBackPix(x, y)];
}
inline int32_t GetBackMat(int32_t x, int32_t y) const // get landscape material (bounds checked)
{
return Pix2Mat[GetBackPix(x, y)];
}
inline int32_t GetBackDensity(int32_t x, int32_t y) const // get landscape density (bounds checked)
{
return Pix2Dens[GetBackPix(x, y)];
}
inline int32_t GetBackPlacement(int32_t x, int32_t y) const // get landscape material placement (bounds checked)
{
return Pix2Place[GetBackPix(x, y)];
}
BYTE _GetBackPix(int32_t x, int32_t y) const;
BYTE GetBackPix(int32_t x, int32_t y) const;
int32_t _GetBackMat(int32_t x, int32_t y) const;
int32_t _GetBackDensity(int32_t x, int32_t y) const;
int32_t _GetBackPlacement(int32_t x, int32_t y) const;
int32_t GetBackMat(int32_t x, int32_t y) const;
int32_t GetBackDensity(int32_t x, int32_t y) const;
int32_t GetBackPlacement(int32_t x, int32_t y) const;
inline bool GetLight(int32_t x, int32_t y)
{
return GetBackPix(x, y) == 0 || Pix2Light[GetPix(x, y)];
}
inline bool _GetLight(int32_t x, int32_t y)
{
return _GetBackPix(x, y) == 0 || Pix2Light[_GetPix(x, y)];
}
bool GetLight(int32_t x, int32_t y);
bool _GetLight(int32_t x, int32_t y);
inline bool _FastSolidCheck(int32_t x, int32_t y) const // checks whether there *might* be something solid at the point
{
return PixCnt[(x / 17) * PixCntPitch + (y / 15)] > 0;
}
static inline int32_t FastSolidCheckNextX(int32_t x)
{
return (x / 17) * 17 + 17;
}
inline int32_t GetPixMat(BYTE byPix) const { return Pix2Mat[byPix]; }
inline int32_t GetPixDensity(BYTE byPix) const { return Pix2Dens[byPix]; }
bool _FastSolidCheck(int32_t x, int32_t y) const;
static int32_t FastSolidCheckNextX(int32_t x);
int32_t GetPixMat(BYTE byPix) const;
int32_t GetPixDensity(BYTE byPix) const;
bool _PathFree(int32_t x, int32_t y, int32_t x2, int32_t y2) const; // quickly checks wether there *might* be pixel in the path.
int32_t GetMatHeight(int32_t x, int32_t y, int32_t iYDir, int32_t iMat, int32_t iMax) const;
@ -265,49 +137,25 @@ public:
bool DrawMap(int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt, const char *szMapDef, bool ignoreSky = false); // creates and draws a map section using MapCreatorS2
bool ClipRect(int32_t &rX, int32_t &rY, int32_t &rWdt, int32_t &rHgt) const; // clip given rect by landscape size; return whether anything is left unclipped
bool DrawDefMap(int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt, const char *szMapDef, bool ignoreSky = false); // creates and draws a map section using MapCreatorS2 and a map from the loaded Landscape.txt
bool SetModulation(DWORD dwWithClr) // adjust the way the landscape is blitted
{ Modulation=dwWithClr; return true; }
DWORD GetModulation() const { return Modulation; }
bool SetModulation(DWORD dwWithClr);
DWORD GetModulation() const;
bool PostInitMap(); // do script callbacks of MapCreatorS2 in finished landscape
bool ReplaceMapColor(BYTE iOldIndex, BYTE iNewIndex); // find every occurance of iOldIndex in map; replace it by new index
bool SetTextureIndex(const char *szMatTex, BYTE iNewIndex, bool fInsert); // change color index of map texture, or insert a new one
void SetMapChanged() { fMapChanged = true; }
void SetMapChanged();
void HandleTexMapUpdate();
void UpdatePixMaps();
bool DoRelights();
void RemoveUnusedTexMapEntries();
private:
void ExecuteScan();
int32_t DoScan(int32_t x, int32_t y, int32_t mat, int32_t dir);
uint32_t ChunkyRandom(uint32_t &iOffset, uint32_t iRange) const; // return static random value, according to offset and MapSeed
void DrawChunk(int32_t tx, int32_t ty, int32_t wdt, int32_t hgt, uint8_t mcol, uint8_t mcolBkg, C4MaterialCoreShape Shape, uint32_t cro);
void DrawSmoothOChunk(int32_t tx, int32_t ty, int32_t wdt, int32_t hgt, uint8_t mcol, uint8_t mcolBkg, int flip, uint32_t cro);
void ChunkOZoom(CSurface8 * sfcMap, CSurface8* sfcMapBkg, int32_t iMapX, int32_t iMapY, int32_t iMapWdt, int32_t iMapHgt, uint8_t iTexture, int32_t iOffX=0,int32_t iOffY=0);
bool GetTexUsage(CSurface8 * sfcMap, CSurface8* sfcMapBkg, int32_t iMapX, int32_t iMapY, int32_t iMapWdt, int32_t iMapHgt, DWORD *dwpTextureUsage) const;
bool TexOZoom(CSurface8 * sfcMap, CSurface8* sfcMapBkg, int32_t iMapX, int32_t iMapY, int32_t iMapWdt, int32_t iMapHgt, DWORD *dwpTextureUsage, int32_t iToX=0,int32_t iToY=0);
bool MapToSurface(CSurface8 * sfcMap, CSurface8* sfcMapBkg, int32_t iMapX, int32_t iMapY, int32_t iMapWdt, int32_t iMapHgt, int32_t iToX, int32_t iToY, int32_t iToWdt, int32_t iToHgt, int32_t iOffX, int32_t iOffY);
bool MapToLandscape(CSurface8 * sfcMap, CSurface8* sfcMapBkg, int32_t iMapX, int32_t iMapY, int32_t iMapWdt, int32_t iMapHgt, int32_t iOffsX = 0, int32_t iOffsY = 0, bool noClear = false); // zoom map segment to surface (or sector surfaces)
bool InitTopAndBottomRowPix(); // inti out-of-landscape pixels for bottom side
bool GetMapColorIndex(const char *szMaterial, const char *szTexture, BYTE &rbyCol) const;
bool SkyToLandscape(int32_t iToX, int32_t iToY, int32_t iToWdt, int32_t iToHgt, int32_t iOffX, int32_t iOffY);
bool CreateMap(CSurface8*& sfcMap, CSurface8*& sfcMapBkg); // create map by landscape attributes
bool CreateMapS2(C4Group &ScenFile, CSurface8*& sfcMap, CSurface8*& sfcMapBkg); // create map by def file
bool Mat2Pal(); // assign material colors to landscape palette
void UpdatePixCnt(const class C4Rect &Rect, bool fCheck = false);
void UpdateMatCnt(C4Rect Rect, bool fPlus);
void PrepareChange(C4Rect BoundingBox);
void FinishChange(C4Rect BoundingBox);
bool DrawLineLandscape(int32_t iX, int32_t iY, int32_t iGrade, uint8_t line_color, uint8_t line_color_bkg);
bool DrawLineMap(int32_t iX, int32_t iY, int32_t iRadius, uint8_t line_color, uint8_t line_color_bkg);
uint8_t *GetBridgeMatConversion(int32_t for_material_col) const;
bool SaveInternal(C4Group &hGroup) const;
bool SaveDiffInternal(C4Group &hGroup, bool fSyncSave) const;
class C4Sky &GetSky();
int32_t ForPolygon(int *vtcs, int length, bool (C4Landscape::*fnCallback)(int32_t, int32_t),
C4MaterialList *mats_count = NULL, uint8_t col = 0, uint8_t colBkg = 0, uint8_t *conversion_table = NULL);
bool HasFoW() const;
class C4FoW *GetFoW();
int32_t GetMatCount(int material) const;
int32_t GetEffectiveMatCount(int material) const;
public:
int32_t DigFreeShape(int *vtcs, int length, C4Object *by_object = NULL, bool no_dig2objects = false, bool no_instability_check = false);
void BlastFreeShape(int *vtcs, int length, C4Object *by_object = NULL, int32_t by_player = NO_OWNER, int32_t iMaxDensity = C4M_Vehicle);
@ -322,21 +170,8 @@ public:
bool ClearPix(int32_t tx, int32_t ty); // also used by mass mover (corrode)
private:
CSurface8* CreateDefaultBkgSurface(CSurface8& sfcFg, bool msbAsIft) const;
void DigMaterial2Objects(int32_t tx, int32_t ty, C4MaterialList *mat_list, C4Object *pCollect = NULL);
void BlastMaterial2Objects(int32_t tx, int32_t ty, C4MaterialList *mat_list, int32_t caused_by, int32_t str, C4ValueArray *out_objects);
void ClearPointers(C4Object *pObj);
bool DigFreePix(int32_t tx, int32_t ty);
bool DigFreePixNoInstability(int32_t tx, int32_t ty);
bool BlastFreePix(int32_t tx, int32_t ty);
bool ShakeFreePix(int32_t tx, int32_t ty);
C4ValueArray *PrepareFreeShape(C4Rect &BoundingBox, C4Object *by_object);
void PostFreeShape(C4ValueArray *dig_objects, C4Object *by_object);
BYTE DefaultBkgMat(BYTE fg) const;
public:
void CompileFunc(StdCompiler *pComp); // without landscape bitmaps and sky
};
@ -361,12 +196,6 @@ bool FindClosestFree(int32_t &rX, int32_t &rY, int32_t iAngle1, int32_t iAngle2,
bool ConstructionCheck(C4PropList *, int32_t iX, int32_t iY, C4Object *pByObj=NULL);
int32_t PixCol2Mat(BYTE pixc);
#define GBackWdt ::Landscape.Width
#define GBackHgt ::Landscape.Height
#define GBackPix ::Landscape.GetPix
#define ClearBackPix ::Landscape.ClearPix
#define _GBackPix ::Landscape._GetPix
inline bool DensitySolid(int32_t dens)
{
return (dens>=C4M_Solid);

View File

@ -166,25 +166,4 @@ private:
};
#endif
class C4LandscapeRenderClassic : public C4LandscapeRender
{
public:
C4LandscapeRenderClassic();
~C4LandscapeRenderClassic();
private:
C4Surface *Surface32;
public:
virtual bool ReInit(int32_t iWidth, int32_t iHeight);
virtual bool Init(int32_t iWidth, int32_t iHeight, C4TextureMap *pMap, C4GroupSet *pGraphics);
virtual void Clear();
virtual C4Rect GetAffectedRect(C4Rect Rect);
virtual void Update(C4Rect Rect, C4Landscape *pSource);
virtual void Draw(const C4TargetFacet &cgo, const C4FoWRegion *Light);
};
#endif // C4LANDSCAPE_RENDER_H

View File

@ -1,146 +0,0 @@
/*
* OpenClonk, http://www.openclonk.org
*
* Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
* Copyright (c) 2009-2015, The OpenClonk Team and contributors
*
* Distributed under the terms of the ISC license; see accompanying file
* "COPYING" for details.
*
* "Clonk" is a registered trademark of Matthes Bender, used with permission.
* See accompanying file "TRADEMARK" for details.
*
* To redistribute this file separately, substitute the full license texts
* for the above references.
*/
#include "C4Include.h"
#include "C4LandscapeRender.h"
#include "C4Landscape.h"
#include "C4Texture.h"
#include "lib/StdColors.h"
const int C4LS_MaxLightDistY = 8;
const int C4LS_MaxLightDistX = 1;
C4LandscapeRenderClassic::C4LandscapeRenderClassic()
: Surface32(NULL)
{
}
C4LandscapeRenderClassic::~C4LandscapeRenderClassic()
{
Clear();
}
bool C4LandscapeRenderClassic::ReInit(int32_t iWidth, int32_t iHeight)
{
// Create surface
delete Surface32; Surface32 = NULL;
Surface32 = new C4Surface();
// without shaders, the FoW is only as detailed as the landscape has tiles.
if (!Surface32->Create(iWidth, iHeight))
return false;
// Safe back info
this->iWidth = iWidth;
this->iHeight = iHeight;
return true;
}
bool C4LandscapeRenderClassic::Init(int32_t iWidth, int32_t iHeight, C4TextureMap *pTexs, C4GroupSet *pGraphics)
{
// Init proc
if (!ReInit(iWidth, iHeight)) return false;
this->pTexs = pTexs;
return true;
}
void C4LandscapeRenderClassic::Clear()
{
delete Surface32; Surface32 = 0;
iWidth = iHeight = 0;
pTexs = NULL;
}
C4Rect C4LandscapeRenderClassic::GetAffectedRect(C4Rect Rect)
{
Rect.Enlarge(C4LS_MaxLightDistX, C4LS_MaxLightDistY);
return Rect;
}
void C4LandscapeRenderClassic::Update(C4Rect To, C4Landscape *pSource)
{
// clip to landscape size
To.Intersect(C4Rect(0,0,iWidth,iHeight));
// everything clipped?
if (To.Wdt<=0 || To.Hgt<=0) return;
if (!Surface32->Lock()) return;
// We clear the affected region here because ClearBoxDw allocates the
// main memory buffer for the box, so that only that box needs to be
// sent to the gpu, and not the whole texture, or every pixel
// separately. It's an important optimization.
Surface32->ClearBoxDw(To.x, To.y, To.Wdt, To.Hgt);
// do lightning
for (int32_t iX=To.x; iX<To.x+To.Wdt; ++iX)
{
int AboveDensity = 0, BelowDensity = 0;
for (int i = 1; i <= 8; ++i)
{
AboveDensity += pSource->GetPlacement(iX, To.y - i - 1);
BelowDensity += pSource->GetPlacement(iX, To.y + i - 1);
}
for (int32_t iY=To.y; iY<To.y+To.Hgt; ++iY)
{
AboveDensity -= pSource->GetPlacement(iX, iY - 9);
AboveDensity += pSource->GetPlacement(iX, iY - 1);
BelowDensity -= pSource->GetPlacement(iX, iY);
BelowDensity += pSource->GetPlacement(iX, iY + 8);
BYTE pix = pSource->_GetPix(iX, iY);
// Sky
if (!pix)
{
Surface32->SetPixDw(iX, iY, 0x00ffffff);
continue;
}
// get density
int iOwnDens = pSource->_GetPlacement(iX, iY);
if (!iOwnDens) continue;
iOwnDens *= 2;
iOwnDens += pSource->GetPlacement(iX + 1, iY) + pSource->GetPlacement(iX - 1, iY);
iOwnDens /= 4;
// get texture map entry for pixel
const C4TexMapEntry *pTex = pTexs->GetEntry(PixCol2Tex(pix));
assert(pTex);
// get texture contents
DWORD dwBackClr = 0u;
if (pTex) dwBackClr = pTex->GetPattern().PatternClr(iX, iY);
// get density of surrounding materials
int iCompareDens = AboveDensity / 8;
if (iOwnDens > iCompareDens)
{
// apply light
LightenClrBy(dwBackClr, std::min(30, 2 * (iOwnDens - iCompareDens)));
}
else if (iOwnDens < iCompareDens && iOwnDens < 30)
{
DarkenClrBy(dwBackClr, std::min(30, 2 * (iCompareDens - iOwnDens)));
}
iCompareDens = BelowDensity / 8;
if (iOwnDens > iCompareDens)
{
DarkenClrBy(dwBackClr, std::min(30, 2 * (iOwnDens - iCompareDens)));
}
Surface32->SetPixDw(iX, iY, dwBackClr);
}
}
Surface32->Unlock();
}
void C4LandscapeRenderClassic::Draw(const C4TargetFacet &cgo, const C4FoWRegion *Light)
{
// Ignore light for now
pDraw->BlitLandscape(Surface32, cgo.TargetX, cgo.TargetY, cgo.Surface,
cgo.X, cgo.Y, cgo.Wdt, cgo.Hgt);
}

View File

@ -33,10 +33,7 @@ public:
void Create(CSurface8 *sfcMap,
C4SLandscape &rLScape, C4TextureMap &rTexMap,
bool fLayers=false, int32_t iPlayerNum=1);
bool Load(BYTE **pbypBuffer,
int32_t &rBufWdt, int32_t &rMapWdt, int32_t &rMapHgt,
C4Group &hGroup, const char *szEntryName,
C4TextureMap &rTexMap);
protected:
void Reset();
void SetPix(int32_t x, int32_t y, BYTE col);

View File

@ -449,7 +449,7 @@ static C4ValueArray *FnLayerCreateMatTexMask(C4PropList * _this, const C4Value &
// TODO: CreateBackMatTexMask? Or Return 512 bools?
C4MapScriptLayer::C4MapScriptLayer(C4PropList *prototype, C4MapScriptMap *map) : C4PropListNumbered(prototype), fg_surface(NULL), bg_surface(NULL), surface_owned(false), map(map)
C4MapScriptLayer::C4MapScriptLayer(C4PropList *prototype, C4MapScriptMap *map) : C4PropListNumbered(prototype), map(map)
{
// It seems like numbered PropLists need a number. I don't know why.
AcquireNumber();
@ -460,9 +460,8 @@ bool C4MapScriptLayer::CreateSurface(int32_t wdt, int32_t hgt)
// Create new surface of given size. Surface is filled with color 0
ClearSurface();
if (wdt<=0 || hgt<=0) return false;
fg_surface = new CSurface8;
bg_surface = new CSurface8;
surface_owned = true;
fg_surface = std::make_unique<CSurface8>();
bg_surface = std::make_unique<CSurface8>();
if (!fg_surface->Create(wdt, hgt) || !bg_surface->Create(wdt, hgt))
{
ClearSurface();
@ -474,10 +473,7 @@ bool C4MapScriptLayer::CreateSurface(int32_t wdt, int32_t hgt)
void C4MapScriptLayer::ClearSurface()
{
// Delete surface if owned or just set to zero if unowned
if (surface_owned) { delete fg_surface; delete bg_surface; }
fg_surface=NULL; bg_surface=NULL;
surface_owned=false;
fg_surface.reset(); bg_surface.reset();
// if there is no surface, width and height parameters are undefined. no need to update them.
}
@ -723,7 +719,7 @@ C4MapScriptMap *C4MapScriptHost::CreateMap()
return new C4MapScriptMap(MapPrototype);
}
bool C4MapScriptHost::InitializeMap(C4SLandscape *pLandscape, C4TextureMap *pTexMap, C4MaterialMap *pMatMap, uint32_t iPlayerCount, CSurface8 **pmap_fg_surface, CSurface8** pmap_bg_surface)
bool C4MapScriptHost::InitializeMap(C4SLandscape *pLandscape, C4TextureMap *pTexMap, C4MaterialMap *pMatMap, uint32_t iPlayerCount, std::unique_ptr<CSurface8> *pmap_fg_surface, std::unique_ptr <CSurface8>* pmap_bg_surface)
{
// Init scripted map by calling InitializeMap in the proper scripts. If *pmap_surface is given, it will pass the existing map to be modified by script.
assert(pmap_fg_surface);
@ -739,11 +735,12 @@ bool C4MapScriptHost::InitializeMap(C4SLandscape *pLandscape, C4TextureMap *pTex
}
// Create proplist as script context
std::unique_ptr<C4MapScriptMap> map(CreateMap());
// Drawing on existing map or create new?
if (*pmap_fg_surface && *pmap_bg_surface)
{
// Existing map
map->SetSurface(*pmap_fg_surface, *pmap_bg_surface);
map->SetSurfaces(std::move(*pmap_fg_surface), std::move(*pmap_bg_surface));
}
else
{
@ -760,7 +757,7 @@ bool C4MapScriptHost::InitializeMap(C4SLandscape *pLandscape, C4TextureMap *pTex
if (result)
{
map->ConvertSkyToTransparent();
map->ReleaseSurface(*pmap_fg_surface, *pmap_bg_surface);
std::tie(*pmap_fg_surface, *pmap_bg_surface) = map->ReleaseSurfaces();
}
return !!result;
}

View File

@ -269,9 +269,8 @@ public:
// C4M_MaxTexIndex can be used to mark Sky
class C4MapScriptLayer : public C4PropListNumbered
{
CSurface8 *fg_surface;
CSurface8 *bg_surface;
bool surface_owned;
std::unique_ptr<CSurface8> fg_surface;
std::unique_ptr<CSurface8> bg_surface;
protected:
class C4MapScriptMap *map;
@ -284,8 +283,16 @@ public:
// Surface management
bool CreateSurface(int32_t wdt, int32_t hgt);
void ClearSurface();
void ReleaseSurface(CSurface8*& fg, CSurface8*& bg) { surface_owned=false; fg = fg_surface; bg = bg_surface; } // return surface and mark it as not owned by self
void SetSurface(CSurface8 *fg, CSurface8* bg) { ClearSurface(); fg_surface=fg; bg_surface=bg; UpdateSurfaceSize(); }
void SetSurfaces(std::unique_ptr<CSurface8> fg, std::unique_ptr<CSurface8> bg)
{
fg_surface = std::move(fg);
bg_surface = std::move(bg);
UpdateSurfaceSize();
}
std::pair<std::unique_ptr<CSurface8>, std::unique_ptr<CSurface8>> ReleaseSurfaces()
{
return std::make_pair(std::move(fg_surface), std::move(bg_surface));
}
bool HasSurface() const { return fg_surface && fg_surface->Bits && bg_surface && bg_surface->Bits; }
// Size management
@ -340,7 +347,7 @@ public:
virtual bool LoadData(const char *, const char *, C4LangStringTable *);
void Clear();
virtual C4PropListStatic * GetPropList();
bool InitializeMap(C4SLandscape *pLandscape, C4TextureMap *pTexMap, C4MaterialMap *pMatMap, uint32_t iPlayerCount, CSurface8 **pmap_fg_surface, CSurface8** pmap_bg_surface);
bool InitializeMap(C4SLandscape *pLandscape, C4TextureMap *pTexMap, C4MaterialMap *pMatMap, uint32_t iPlayerCount, std::unique_ptr<CSurface8> *pmap_fg_surface, std::unique_ptr<CSurface8>* pmap_bg_surface);
C4PropListStatic *GetLayerPrototype() { return LayerPrototype; }
C4TextureMap* pTexMap;

View File

@ -100,7 +100,7 @@ void C4MassMoverSet::Draw()
bool C4MassMover::Init(int32_t tx, int32_t ty)
{
// Out of bounds check
if (!Inside<int32_t>(tx,0,GBackWdt-1) || !Inside<int32_t>(ty,0,GBackHgt-1))
if (!Inside<int32_t>(tx,0,::Landscape.GetWidth()-1) || !Inside<int32_t>(ty,0,::Landscape.GetHeight()-1))
return false;
// Check mat
Mat=GBackMat(tx,ty);

View File

@ -816,7 +816,7 @@ bool C4MaterialMap::mrfCorrode(C4MaterialReaction *pReaction, int32_t &iX, int32
fDoCorrode = (d100 < ::MaterialMap.Map[iPxsMat].Corrosive) && (d100 < ::MaterialMap.Map[iLsMat].Corrode);
if (fDoCorrode)
{
ClearBackPix(iLSPosX,iLSPosY);
::Landscape.ClearPix(iLSPosX,iLSPosY);
//::Landscape.CheckInstabilityRange(iLSPosX,iLSPosY); - more correct, but makes acid too effective as well
if (!Random(5))
{
@ -843,7 +843,7 @@ bool C4MaterialMap::mrfCorrode(C4MaterialReaction *pReaction, int32_t &iX, int32
fDoCorrode = (d100 < ::MaterialMap.Map[iPxsMat].Corrosive) && (d100 < ::MaterialMap.Map[iLsMat].Corrode);
if (fDoCorrode)
{
ClearBackPix(iLSPosX,iLSPosY);
::Landscape.ClearPix(iLSPosX,iLSPosY);
::Landscape.CheckInstabilityRange(iLSPosX,iLSPosY);
if (!Random(5))
{

View File

@ -48,7 +48,7 @@ void C4PXS::Execute()
{ Deactivate(); return; }
// Out of bounds
if ((x<0) || (x>=GBackWdt) || (y<-10) || (y>=GBackHgt))
if ((x<0) || (x>=::Landscape.GetWidth()) || (y<-10) || (y>=::Landscape.GetHeight()))
{ Deactivate(); return; }
// Material conversion
@ -80,7 +80,7 @@ void C4PXS::Execute()
int32_t iToX = fixtoi(ctcox), iToY = fixtoi(ctcoy);
// In bounds?
if (Inside<int32_t>(iToX, 0, GBackWdt-1) && Inside<int32_t>(iToY, 0, GBackHgt-1))
if (Inside<int32_t>(iToX, 0, ::Landscape.GetWidth()-1) && Inside<int32_t>(iToY, 0, ::Landscape.GetHeight()-1))
// Check path
if (::Landscape._PathFree(iX, iY, iToX, iToY))
{

View File

@ -23,6 +23,7 @@
#ifndef USE_CONSOLE
// headers for particle execution
#include "script/C4Aul.h"
#include <C4Application.h>
#include <C4Value.h>
#include <C4ValueArray.h>
@ -534,7 +535,7 @@ float C4ParticleValueProvider::Wind(C4Particle *forParticle)
float C4ParticleValueProvider::Gravity(C4Particle *forParticle)
{
return startValue + (speedFactor * ::Landscape.Gravity);
return startValue + (speedFactor * ::Landscape.GetGravity());
}
void C4ParticleValueProvider::SetType(C4ParticleValueProviderID what)

View File

@ -215,7 +215,7 @@ void C4Sky::Draw(C4TargetFacet &cgo)
DWORD C4Sky::GetSkyFadeClr(int32_t iY)
{
int32_t iPos2=(iY*256)/GBackHgt; int32_t iPos1=256-iPos2;
int32_t iPos2=(iY*256)/::Landscape.GetHeight(); int32_t iPos1=256-iPos2;
return (((((FadeClr1&0xff00ff)*iPos1 + (FadeClr2&0xff00ff)*iPos2) & 0xff00ff00)
| (((FadeClr1&0x00ff00)*iPos1 + (FadeClr2&0x00ff00)*iPos2) & 0x00ff0000))>>8)
| (FadeClr1 & 0xff000000);

View File

@ -19,12 +19,15 @@
#include <C4Include.h>
#include <C4SolidMask.h>
#include "object/C4Def.h"
#include <C4Object.h>
#include <C4Landscape.h>
#include <C4Game.h>
#include <C4GameObjects.h>
#include <C4DrawGL.h>
#include <StdPNG.h>
#include "graphics/CSurface8.h"
#include "landscape/C4Material.h"
void C4SolidMask::Put(bool fCauseInstability, C4TargetRect *pClipRect, bool fRestoreAttachment)
@ -75,8 +78,8 @@ void C4SolidMask::Put(bool fCauseInstability, C4TargetRect *pClipRect, bool fRes
MaskPutRect.y = oy;
if (MaskPutRect.y < 0) { MaskPutRect.ty = -MaskPutRect.y; MaskPutRect.y = 0; }
else MaskPutRect.ty = 0;
MaskPutRect.Wdt = std::min<int32_t>(ox + pForObject->SolidMask.Wdt, GBackWdt) - MaskPutRect.x;
MaskPutRect.Hgt = std::min<int32_t>(oy + pForObject->SolidMask.Hgt, GBackHgt) - MaskPutRect.y;
MaskPutRect.Wdt = std::min<int32_t>(ox + pForObject->SolidMask.Wdt, ::Landscape.GetWidth()) - MaskPutRect.x;
MaskPutRect.Hgt = std::min<int32_t>(oy + pForObject->SolidMask.Hgt, ::Landscape.GetHeight()) - MaskPutRect.y;
}
// fill rect with mask
for (ycnt=0; ycnt<pClipRect->Hgt; ++ycnt)
@ -93,7 +96,7 @@ void C4SolidMask::Put(bool fCauseInstability, C4TargetRect *pClipRect, bool fRes
if (!MaskPut)
{
// get background pixel
byPixel=GBackPix(iTx,iTy);
byPixel=::Landscape.GetPix(iTx,iTy);
// store it. If MCVehic, also store in initial put, but won't be used in restore
// do not overwrite current value in re-put issued by SolidMask-remover
if (!IsSomeVehicle(byPixel) || RegularPut)
@ -128,8 +131,8 @@ void C4SolidMask::Put(bool fCauseInstability, C4TargetRect *pClipRect, bool fRes
MaskPutRect.y = ystart;
if (MaskPutRect.y < 0) { MaskPutRect.ty = -MaskPutRect.y; MaskPutRect.Hgt = MaskPutRect.y; MaskPutRect.y = 0; }
else { MaskPutRect.ty = 0; MaskPutRect.Hgt = 0; }
MaskPutRect.Wdt = std::min<int32_t>(xstart + MatBuffPitch, GBackWdt) - MaskPutRect.x;
MaskPutRect.Hgt = std::min<int32_t>(ystart + MatBuffPitch, GBackHgt) - MaskPutRect.y;
MaskPutRect.Wdt = std::min<int32_t>(xstart + MatBuffPitch, ::Landscape.GetWidth()) - MaskPutRect.x;
MaskPutRect.Hgt = std::min<int32_t>(ystart + MatBuffPitch, ::Landscape.GetHeight()) - MaskPutRect.y;
}
// go through clipping rect
const C4Real y0 = itofix(pClipRect->ty - MatBuffPitch/2);
@ -159,7 +162,7 @@ void C4SolidMask::Put(bool fCauseInstability, C4TargetRect *pClipRect, bool fRes
if (!MaskPut)
{
// get background pixel
byPixel=_GBackPix(iTx,iTy);
byPixel=::Landscape._GetPix(iTx,iTy);
// store it. If MCVehic, also store in initial put, but won't be used in restore
// do not overwrite current value in re-put issued by SolidMask-remover
if (!IsSomeVehicle(byPixel) || RegularPut)
@ -259,7 +262,7 @@ void C4SolidMask::Remove(bool fBackupAttachment)
// The pPix-check ensures that only pixels that hads been overwritten by this SolidMask are restored
// Non-SolidMask-pixels should not happen here, because all relevant landscape change routines should
// temp remove SolidMasks before
assert(IsSomeVehicle(_GBackPix(iTx,iTy)));
assert(IsSomeVehicle(::Landscape._GetPix(iTx,iTy)));
if (IsSomeVehicle(::Landscape._GetPix(iTx, iTy)))
::Landscape._SetPix2(iTx, iTy, *pPix, ::Landscape.Transparent);
// Instability
@ -353,7 +356,7 @@ void C4SolidMask::RemoveTemporary(C4Rect where)
if (*pPix != MCVehic) //
{
// restore
assert(IsSomeVehicle(GBackPix(x,y)));
assert(IsSomeVehicle(::Landscape.GetPix(x,y)));
::Landscape._SetPix2Tmp(x, y, *pPix, ::Landscape.Transparent);
}
}
@ -374,7 +377,7 @@ void C4SolidMask::PutTemporary(C4Rect where)
if (*pPix != MCVehic)
{
// put
assert(GBackPix(x,y)==*pPix);
assert(::Landscape.GetPix(x,y)==*pPix);
::Landscape._SetPix2Tmp(x, y, MaskMaterial, ::Landscape.Transparent);
}
}
@ -395,7 +398,7 @@ void C4SolidMask::Repair(C4Rect where)
if (*pPix != MCVehic)
{
// record changed landscape in MatBuff
*pPix = GBackPix(x,y);
*pPix = ::Landscape.GetPix(x,y);
// put
::Landscape.SetPix2(x, y, MaskMaterial, ::Landscape.Transparent);
}
@ -439,7 +442,7 @@ C4SolidMask::~C4SolidMask()
void C4SolidMask::RemoveSolidMasks()
{
C4Rect SolidMaskRect(0,0,GBackWdt,GBackHgt);
C4Rect SolidMaskRect(0,0,::Landscape.GetWidth(),::Landscape.GetHeight());
C4SolidMask *pSolid;
for (pSolid = C4SolidMask::Last; pSolid; pSolid = pSolid->Prev)
{
@ -449,7 +452,7 @@ void C4SolidMask::RemoveSolidMasks()
void C4SolidMask::PutSolidMasks()
{
C4Rect SolidMaskRect(0,0,GBackWdt,GBackHgt);
C4Rect SolidMaskRect(0,0,::Landscape.GetWidth(),::Landscape.GetHeight());
C4SolidMask *pSolid;
// Restore Solidmasks
for (pSolid = C4SolidMask::First; pSolid; pSolid = pSolid->Next)
@ -467,7 +470,7 @@ C4SolidMask * C4SolidMask::Last = 0;
bool C4SolidMask::CheckConsistency()
{
assert(IsSomeVehicle(MaskMaterial));
C4Rect SolidMaskRect(0,0,GBackWdt,GBackHgt);
C4Rect SolidMaskRect(0,0,::Landscape.GetWidth(),::Landscape.GetHeight());
C4SolidMask *pSolid;
for (pSolid = C4SolidMask::Last; pSolid; pSolid = pSolid->Prev)
{

View File

@ -175,7 +175,7 @@ void C4TextureShapeActivationMap::Add(int32_t block_x, int32_t block_y, int32_t
}
void C4TextureShape::Draw(CSurface8 * sfcMap, CSurface8* sfcMapBkg, int32_t iMapX, int32_t iMapY, int32_t iMapWdt, int32_t iMapHgt, uint8_t iTexture, int32_t iOffX, int32_t iOffY, int32_t MapZoom, int32_t min_overlap_ratio)
void C4TextureShape::Draw(const CSurface8 &sfcMap, const CSurface8 &sfcMapBkg, int32_t iMapX, int32_t iMapY, int32_t iMapWdt, int32_t iMapHgt, uint8_t iTexture, int32_t iOffX, int32_t iOffY, int32_t MapZoom, int32_t min_overlap_ratio)
{
// Safety
if (!num_shapes) return;
@ -183,8 +183,8 @@ void C4TextureShape::Draw(CSurface8 * sfcMap, CSurface8* sfcMapBkg, int32_t iMap
// Add max polygon size because polygons may extent far onto outside pixels
int32_t x0 = std::max<int32_t>(0, iMapX*MapZoom + iOffX - GetMaxPolyWidth()),
y0 = std::max<int32_t>(0, iMapY*MapZoom + iOffY - GetMaxPolyHeight());
int32_t x1 = std::min<int32_t>(::Landscape.Width, x0 + iMapWdt*MapZoom + GetMaxPolyWidth() * 2),
y1 = std::min<int32_t>(::Landscape.Height, y0 + iMapHgt*MapZoom + GetMaxPolyHeight() * 2);
int32_t x1 = std::min<int32_t>(::Landscape.GetWidth(), x0 + iMapWdt*MapZoom + GetMaxPolyWidth() * 2),
y1 = std::min<int32_t>(::Landscape.GetHeight(), y0 + iMapHgt*MapZoom + GetMaxPolyHeight() * 2);
// Range in shape blocks.
// A shape block is the coverage of the size of one loaded shape data surface
int32_t rblock_x0 = x0 / data.Wdt;
@ -202,11 +202,11 @@ void C4TextureShape::Draw(CSurface8 * sfcMap, CSurface8* sfcMapBkg, int32_t iMap
{
for (int32_t map_x = iMapX; map_x < iMapX + iMapWdt; ++map_x)
{
if (sfcMap->GetPix(map_x, map_y) == iTexture)
if (sfcMap.GetPix(map_x, map_y) == iTexture)
{
// Here we have a pixel of the texture drawn in this shape
// Find all shapes covered by this map pixel and remember background pixel for them
const BYTE pixBkg = sfcMapBkg->GetPix(map_x, map_y);
const BYTE pixBkg = sfcMapBkg.GetPix(map_x, map_y);
// Find all shape blocks to be checked
int32_t px_check_rate = 1; // sample rate to check coverage, in pixels. Could also increase this if it turns out to be a bottleneck
for (int32_t pxo_y = 0; pxo_y < MapZoom; pxo_y += px_check_rate)

View File

@ -45,7 +45,7 @@ public:
int32_t GetMaxPolyWidth() const { return GetWidth() / 4; }
int32_t GetMaxPolyHeight() const { return GetHeight() / 4; }
void Draw(CSurface8 * sfcMap, CSurface8* sfcMapBkg, int32_t iMapX, int32_t iMapY, int32_t iMapWdt, int32_t iMapHgt, uint8_t iTexture, int32_t iOffX, int32_t iOffY, int32_t MapZoom, int32_t min_overlap_ratio);
void Draw(const CSurface8 &sfcMap, const CSurface8 &sfcMapBkg, int32_t iMapX, int32_t iMapY, int32_t iMapWdt, int32_t iMapHgt, uint8_t iTexture, int32_t iOffX, int32_t iOffY, int32_t MapZoom, int32_t min_overlap_ratio);
};
#endif

View File

@ -70,8 +70,8 @@ struct LightMapZoom {
bool operator()(int x, int y) const
{
// Landscape coordinates
const int lx = Clamp(static_cast<int>((x + 0.5) * sx), 0, Landscape.Width - 1);
const int ly = Clamp(static_cast<int>((y + 0.5) * sy), 0, Landscape.Height - 1);
const int lx = Clamp(static_cast<int>((x + 0.5) * sx), 0, Landscape.GetWidth() - 1);
const int ly = Clamp(static_cast<int>((y + 0.5) * sy), 0, Landscape.GetHeight() - 1);
// LightMap check
return ::Landscape._GetLight(lx, ly);
}
@ -124,8 +124,8 @@ void C4FoWAmbient::CreateFromLandscape(const C4Landscape& landscape, double reso
FullCoverage = full_coverage;
// Number of zoomed pixels
LandscapeX = landscape.Width;
LandscapeY = landscape.Height;
LandscapeX = Landscape.GetWidth();
LandscapeY = Landscape.GetHeight();
SizeX = std::min<unsigned int>(static_cast<unsigned int>(ceil(LandscapeX / resolution)), pDraw->MaxTexSize);
SizeY = std::min<unsigned int>(static_cast<unsigned int>(ceil(LandscapeY / resolution)), pDraw->MaxTexSize);
@ -139,7 +139,7 @@ void C4FoWAmbient::CreateFromLandscape(const C4Landscape& landscape, double reso
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, SizeX, SizeY, 0, GL_RED, GL_FLOAT, NULL);
const C4TimeMilliseconds begin = C4TimeMilliseconds::Now();
UpdateFromLandscape(landscape, C4Rect(0, 0, landscape.Width, landscape.Height));
UpdateFromLandscape(landscape, C4Rect(0, 0, Landscape.GetWidth(), Landscape.GetHeight()));
uint32_t dt = C4TimeMilliseconds::Now() - begin;
LogF("Created %ux%u ambient map in %g secs", SizeX, SizeY, dt / 1000.);
#endif
@ -154,8 +154,8 @@ void C4FoWAmbient::UpdateFromLandscape(const C4Landscape& landscape, const C4Rec
assert(Tex != 0);
// Factor to go from zoomed to landscape coordinates
const double zoom_x = static_cast<double>(landscape.Width) / SizeX;
const double zoom_y = static_cast<double>(landscape.Height) / SizeY;
const double zoom_x = static_cast<double>(Landscape.GetWidth()) / SizeX;
const double zoom_y = static_cast<double>(Landscape.GetHeight()) / SizeY;
// Update region in zoomed coordinates
const unsigned int left = std::max(static_cast<int>( (update.x - Radius) / zoom_x), 0);
const unsigned int right = std::min(static_cast<unsigned int>( (update.x + update.Wdt + Radius) / zoom_x), SizeX - 1) + 1;

View File

@ -17,6 +17,9 @@
#define C4FOWAMBIENT_H
#include <C4Landscape.h>
#ifndef USE_CONSOLE
#include <GL/glew.h>
#endif
/**
This class manages a texture that holds the ambient light intensity
@ -62,7 +65,7 @@ public:
void UpdateFromLandscape(const C4Landscape& landscape, const C4Rect& update);
// Fills a 2x3 matrix to transform fragment coordinates to ambient map texture coordinates
void GetFragTransform(const FLOAT_RECT& vpRect, const C4Rect& clipRect, const C4Rect& outRect, float ambientTransform[6]) const;
void GetFragTransform(const struct FLOAT_RECT& vpRect, const C4Rect& clipRect, const C4Rect& outRect, float ambientTransform[6]) const;
unsigned int GetLandscapeWidth() const { return LandscapeX; }
unsigned int GetLandscapeHeight() const { return LandscapeY; }

View File

@ -134,7 +134,7 @@ void C4FoWLightSection::Update(C4Rect RectIn)
{
// Transform rectangle into our coordinate system
C4Rect Rect = rtransRect(RectIn);
C4Rect Bounds = rtransRect(C4Rect(0,0,GBackWdt,GBackHgt));
C4Rect Bounds = rtransRect(C4Rect(0,0,::Landscape.GetWidth(),::Landscape.GetHeight()));
#ifdef LIGHT_DEBUG
if (!::Game.iTick255) {

View File

@ -145,6 +145,11 @@ struct StdMeshBox
{
float x1, y1, z1;
float x2, y2, z2;
StdMeshVector GetCenter() const
{
return StdMeshVector{ (x2 + x1) / 2.0f, (y2 + y1) / 2.0f, (z2 + z1) / 2.0f };
}
};
class StdSubMesh

View File

@ -625,7 +625,7 @@ void LoadShader(StdMeshMaterialParserCtx& ctx, StdMeshMaterialShaderType type)
if (token != TOKEN_BRACE_CLOSE)
ctx.Error(StdCopyStrBuf("'") + token_name.getData() + "' unexpected");
ctx.Manager.AddShader(source.getData(), name.getData(), language.getData(), type, code.getData(), false);
ctx.Manager.AddShader(source.getData(), name.getData(), language.getData(), type, code.getData(), StdMeshMatManager::SMM_ForceReload);
}
StdMeshMaterialShaderParameter::StdMeshMaterialShaderParameter():
@ -885,6 +885,7 @@ bool StdMeshMaterialProgram::CompileShader(StdMeshMaterialLoader& loader, C4Shad
uniformNames[C4SSU_MaterialShininess] = "materialShininess";
uniformNames[C4SSU_Bones] = "bones";
uniformNames[C4SSU_CullMode] = "cullMode";
uniformNames[C4SSU_FrameCounter] = "frameCounter";
for (unsigned int i = 0; i < ParameterNames.size(); ++i)
uniformNames[C4SSU_Count + i] = ParameterNames[i].getData();
uniformNames[C4SSU_Count + ParameterNames.size()] = NULL;
@ -1514,12 +1515,15 @@ void StdMeshMatManager::Clear()
GeometryShaders.clear();
}
void StdMeshMatManager::Parse(const char* mat_script, const char* filename, StdMeshMaterialLoader& loader)
std::set<StdCopyStrBuf> StdMeshMatManager::Parse(const char* mat_script, const char* filename, StdMeshMaterialLoader& loader)
{
StdMeshMaterialParserCtx ctx(*this, mat_script, filename, loader);
Token token;
StdCopyStrBuf token_name;
std::set<StdCopyStrBuf> loaded_materials;
while ((token = ctx.Advance(token_name)) == TOKEN_IDTF)
{
if (token_name == "material")
@ -1574,6 +1578,7 @@ void StdMeshMatManager::Parse(const char* mat_script, const char* filename, StdM
ctx.Error(StdCopyStrBuf("No working technique for material '") + material_name + "'");
}
#endif
loaded_materials.insert(material_name);
}
else if (token_name == "vertex_program")
{
@ -1593,6 +1598,8 @@ void StdMeshMatManager::Parse(const char* mat_script, const char* filename, StdM
if (token != TOKEN_EOF)
ctx.Error(StdCopyStrBuf("'") + token_name.getData() + "' unexpected");
return loaded_materials;
}
const StdMeshMaterial* StdMeshMatManager::GetMaterial(const char* material_name) const
@ -1604,11 +1611,20 @@ const StdMeshMaterial* StdMeshMatManager::GetMaterial(const char* material_name)
StdMeshMatManager::Iterator StdMeshMatManager::Remove(const Iterator& iter, StdMeshMaterialUpdate* update)
{
if(update) update->Add(&*iter);
Iterator next_iter = iter;
++next_iter;
Materials.erase(iter.iter_);
return next_iter;
if(update) update->Add(&*iter);
Iterator next_iter = iter;
++next_iter;
Materials.erase(iter.iter_);
return next_iter;
}
void StdMeshMatManager::Remove(const StdStrBuf &name, StdMeshMaterialUpdate *update)
{
auto it = Materials.find(StdCopyStrBuf(name));
if (it == Materials.end())
return;
if (update) update->Add(&it->second);
Materials.erase(it);
}
const StdMeshMaterialShader* StdMeshMatManager::GetFragmentShader(const char* name) const
@ -1632,7 +1648,7 @@ const StdMeshMaterialShader* StdMeshMatManager::GetGeometryShader(const char* na
return iter->second.get();
}
const StdMeshMaterialShader* StdMeshMatManager::AddShader(const char* filename, const char* name, const char* language, StdMeshMaterialShaderType type, const char* text, bool success_if_exists)
const StdMeshMaterialShader* StdMeshMatManager::AddShader(const char* filename, const char* name, const char* language, StdMeshMaterialShaderType type, const char* text, uint32_t load_flags)
{
ShaderMap* map = NULL;
switch(type)
@ -1650,23 +1666,24 @@ const StdMeshMaterialShader* StdMeshMatManager::AddShader(const char* filename,
StdCopyStrBuf name_buf(name);
ShaderMap::iterator iter = map->find(name_buf);
if(iter != map->end())
{
// Shader exists
if(success_if_exists)
if ((load_flags & SMM_ForceReload) == SMM_ForceReload)
map->erase(iter);
else if ((load_flags & SMM_AcceptExisting) == SMM_AcceptExisting)
return iter->second.get();
else
return NULL;
}
else
{
std::unique_ptr<StdMeshMaterialShader> shader(new StdMeshMaterialShader(filename, name, language, type, text));
std::pair<ShaderMap::iterator, bool> inserted = map->insert(std::make_pair(name_buf, std::move(shader)));
assert(inserted.second == true);
iter = inserted.first;
return iter->second.get();
}
std::unique_ptr<StdMeshMaterialShader> shader(new StdMeshMaterialShader(filename, name, language, type, text));
std::pair<ShaderMap::iterator, bool> inserted = map->insert(std::make_pair(name_buf, std::move(shader)));
assert(inserted.second == true);
iter = inserted.first;
return iter->second.get();
}
const StdMeshMaterialProgram* StdMeshMatManager::AddProgram(const char* name, StdMeshMaterialLoader& loader, const StdMeshMaterialPass::ShaderInstance& fragment_shader, const StdMeshMaterialPass::ShaderInstance& vertex_shader, const StdMeshMaterialPass::ShaderInstance& geometry_shader)

View File

@ -524,6 +524,11 @@ private:
typedef std::map<StdCopyStrBuf, StdMeshMaterial> MaterialMap;
public:
enum ShaderLoadFlag {
SMM_AcceptExisting = 1,
SMM_ForceReload = 2
};
class Iterator
{
friend class StdMeshMatManager;
@ -550,16 +555,18 @@ public:
// filename may be NULL if the source is not a file. It will only be used
// for error messages.
// Throws StdMeshMaterialError.
void Parse(const char* mat_script, const char* filename, StdMeshMaterialLoader& loader);
// Returns a set of all loaded materials.
std::set<StdCopyStrBuf> Parse(const char* mat_script, const char* filename, StdMeshMaterialLoader& loader);
// Get material by name. NULL if there is no such material with this name.
const StdMeshMaterial* GetMaterial(const char* material_name) const;
Iterator Begin() { return Iterator(Materials.begin()); }
Iterator End() { return Iterator(Materials.end()); }
void Remove(const StdStrBuf& name, class StdMeshMaterialUpdate* update);
Iterator Remove(const Iterator& iter, class StdMeshMaterialUpdate* update);
const StdMeshMaterialShader* AddShader(const char* filename, const char* name, const char* language, StdMeshMaterialShaderType type, const char* text, bool success_if_exists); // if pass_if_exists is TRUE, the function returns the existing shader, otherwise returns NULL.
const StdMeshMaterialShader* AddShader(const char* filename, const char* name, const char* language, StdMeshMaterialShaderType type, const char* text, uint32_t load_flags); // if load_flags & SMM_AcceptExisting, the function returns the existing shader, otherwise returns NULL.
const StdMeshMaterialProgram* AddProgram(const char* name, StdMeshMaterialLoader& loader, const StdMeshMaterialPass::ShaderInstance& fragment_shader, const StdMeshMaterialPass::ShaderInstance& vertex_shader, const StdMeshMaterialPass::ShaderInstance& geometry_shader); // returns NULL if shader code cannot be compiled
const StdMeshMaterialShader* GetFragmentShader(const char* name) const;

View File

@ -102,7 +102,7 @@ bool C4DefList::Add(C4Def* def, bool fOverload)
return true;
}
bool C4Def::Load(C4Group& hGroup, StdMeshSkeletonLoader& loader, DWORD dwLoadWhat, const char* szLanguage, C4SoundSystem* pSoundSystem)
bool C4Def::Load(C4Group& hGroup, StdMeshSkeletonLoader& loader, DWORD dwLoadWhat, const char* szLanguage, C4SoundSystem* pSoundSystem, C4DefGraphicsPtrBackup *)
{
// Assume ID has been set already!

View File

@ -14,13 +14,48 @@
*/
#include "C4Include.h"
#include <array>
#include "C4Landscape.h"
#include "C4Texture.h"
#include "graphics/CSurface8.h"
#include "landscape/C4Landscape.h"
#include "landscape/C4Texture.h"
/* This is a small part of the implementation of C4Landscape for what is
* required by mape. We cannot link the full implementation since it would
* introduce a dependency on C4Game, and therefore the rest of the engine. */
struct C4Landscape::P
{
int32_t Pix2Mat[C4M_MaxTexIndex], Pix2Dens[C4M_MaxTexIndex], Pix2Place[C4M_MaxTexIndex];
bool Pix2Light[C4M_MaxTexIndex];
mutable std::array<std::unique_ptr<uint8_t[]>, C4M_MaxTexIndex> BridgeMatConversion;
int32_t Width = 0, Height = 0;
std::unique_ptr<CSurface8> Surface8;
};
C4Landscape::C4Landscape() : p(new P) {}
C4Landscape::~C4Landscape() {}
bool C4Landscape::FindMatSlide(int&, int&, int, int, int) const { return false; }
int32_t C4Landscape::ExtractMaterial(int32_t, int32_t, bool) { return 0; }
bool C4Landscape::InsertMaterial(int32_t, int32_t *, int32_t *, int32_t, int32_t, bool) { return false; }
bool C4Landscape::Incinerate(int32_t, int32_t, int32_t) { return false; }
bool C4Landscape::ClearPix(int32_t, int32_t) { return false; }
void C4Landscape::CheckInstabilityRange(int32_t, int32_t) {}
int32_t C4Landscape::GetDensity(int32_t x, int32_t y) const { return p->Pix2Dens[GetPix(x, y)]; }
int32_t C4Landscape::GetPixDensity(BYTE byPix) const { return p->Pix2Dens[byPix]; }
C4Real C4Landscape::GetGravity() const { return C4REAL100(20); }
int32_t C4Landscape::GetMat(int32_t x, int32_t y) const { return p->Pix2Mat[GetPix(x, y)]; }
BYTE C4Landscape::GetPix(int32_t x, int32_t y) const // get landscape pixel (bounds checked)
{
extern BYTE MCVehic;
// Border checks
if (x < 0 || x >= p->Width) return MCVehic;
if (y < 0 || y >= p->Height) return MCVehic;
return p->Surface8->_GetPix(x, y);
}
int32_t PixCol2Mat(BYTE pixc)
{
// Get texture
@ -40,15 +75,11 @@ void C4Landscape::HandleTexMapUpdate()
void C4Landscape::UpdatePixMaps() // Copied from C4Landscape.cpp
{
int32_t i;
for (i = 0; i < C4M_MaxTexIndex; i++) Pix2Mat[i] = PixCol2Mat(i);
for (i = 0; i < C4M_MaxTexIndex; i++) Pix2Dens[i] = MatDensity(Pix2Mat[i]);
for (i = 0; i < C4M_MaxTexIndex; i++) Pix2Place[i] = MatValid(Pix2Mat[i]) ? ::MaterialMap.Map[Pix2Mat[i]].Placement : 0;
for (i = 0; i < C4M_MaxTexIndex; i++) Pix2Light[i] = MatValid(Pix2Mat[i]) && (::MaterialMap.Map[Pix2Mat[i]].Light>0);
Pix2Place[0] = 0;
for (i = 0; i < C4M_MaxTexIndex; i++) p->Pix2Mat[i] = PixCol2Mat(i);
for (i = 0; i < C4M_MaxTexIndex; i++) p->Pix2Dens[i] = MatDensity(p->Pix2Mat[i]);
for (i = 0; i < C4M_MaxTexIndex; i++) p->Pix2Place[i] = MatValid(p->Pix2Mat[i]) ? ::MaterialMap.Map[p->Pix2Mat[i]].Placement : 0;
for (i = 0; i < C4M_MaxTexIndex; i++) p->Pix2Light[i] = MatValid(p->Pix2Mat[i]) && (::MaterialMap.Map[p->Pix2Mat[i]].Light>0);
p->Pix2Place[0] = 0;
// clear bridge mat conversion buffers
for (int32_t i = 0; i < C4M_MaxTexIndex; ++i)
{
delete [] BridgeMatConversion[i];
BridgeMatConversion[i] = NULL;
}
std::fill(p->BridgeMatConversion.begin(), p->BridgeMatConversion.end(), nullptr);
}

View File

@ -29,6 +29,7 @@
#include "C4Record.h"
#include "C4RoundResults.h"
#include "C4TextureShape.h"
#include "landscape/C4Sky.h"
/* This file implements stubs for the parts of the engine that are not used
* by mape. */
@ -76,15 +77,6 @@ void C4DefList::ResetIncludeDependencies() {}
bool C4DefList::DrawFontImage(const char* szImageTag, C4Facet& rTarget, C4DrawTransform* pTransform) { return false; }
float C4DefList::GetFontImageAspect(const char* szImageTag) { return -1.0f; }
C4Landscape::C4Landscape() {}
C4Landscape::~C4Landscape() {}
bool C4Landscape::FindMatSlide(int&, int&, int, int, int) const { return false; }
int32_t C4Landscape::ExtractMaterial(int32_t, int32_t, bool) { return 0; }
bool C4Landscape::InsertMaterial(int32_t, int32_t *, int32_t *, int32_t, int32_t, bool) { return false; }
bool C4Landscape::Incinerate(int32_t, int32_t, int32_t) { return false; }
bool C4Landscape::ClearPix(int32_t, int32_t) { return false; }
void C4Landscape::CheckInstabilityRange(int32_t, int32_t) {}
void C4Sky::Default() {}
C4Sky::~C4Sky() {}

View File

@ -20,6 +20,7 @@
#include <C4Include.h>
#include <C4Command.h>
#include "object/C4Def.h"
#include <C4DefList.h>
#include <C4Object.h>
#include <C4ObjectCom.h>
@ -143,7 +144,7 @@ bool FreeMoveTo(C4Object *cObj)
void AdjustMoveToTarget(int32_t &rX, int32_t &rY, bool fFreeMove, int32_t iShapeHgt)
{
// Above solid (always)
int32_t iY=std::min(rY, GBackHgt);
int32_t iY=std::min(rY, ::Landscape.GetHeight());
while ((iY>=0) && GBackSolid(rX,iY)) iY--;
if (iY>=0) rY=iY;
// No-free-move adjustments (i.e. if walking)
@ -152,8 +153,8 @@ void AdjustMoveToTarget(int32_t &rX, int32_t &rY, bool fFreeMove, int32_t iShape
// Drop down to bottom of free space
if (!GBackSemiSolid(rX,rY))
{
for (iY=rY; (iY<GBackHgt) && !GBackSemiSolid(rX,iY+1); iY++) {}
if (iY<GBackHgt) rY=iY;
for (iY=rY; (iY<::Landscape.GetHeight()) && !GBackSemiSolid(rX,iY+1); iY++) {}
if (iY<::Landscape.GetHeight()) rY=iY;
}
// Vertical shape offset above solid
if (GBackSolid(rX,rY+1) || GBackSolid(rX,rY+5))

View File

@ -332,10 +332,12 @@ void C4Def::Clear()
}
bool C4Def::Load(C4Group &hGroup,
StdMeshSkeletonLoader &loader,
DWORD dwLoadWhat,
const char *szLanguage,
C4SoundSystem *pSoundSystem)
StdMeshSkeletonLoader &loader,
DWORD dwLoadWhat,
const char *szLanguage,
C4SoundSystem *pSoundSystem,
C4DefGraphicsPtrBackup *gfx_backup
)
{
bool AddFileMonitoring = false;
if (Game.pFileMonitor && !SEqual(hGroup.GetFullName().getData(),Filename) && !hGroup.IsPacked())
@ -354,7 +356,7 @@ bool C4Def::Load(C4Group &hGroup,
hGroup.PreCacheEntries(C4CFN_ShaderFiles);
hGroup.PreCacheEntries(C4CFN_ImageFiles);
LoadMeshMaterials(hGroup);
LoadMeshMaterials(hGroup, gfx_backup);
bool fSuccess = LoadParticleDef(hGroup);
// Read DefCore
@ -400,12 +402,18 @@ bool C4Def::Load(C4Group &hGroup,
return true;
}
void C4Def::LoadMeshMaterials(C4Group &hGroup)
void C4Def::LoadMeshMaterials(C4Group &hGroup, C4DefGraphicsPtrBackup *gfx_backup)
{
// Load all mesh materials from this folder
C4DefAdditionalResourcesLoader loader(hGroup);
hGroup.ResetSearch();
char MaterialFilename[_MAX_PATH + 1]; *MaterialFilename = 0;
for (const auto &mat : mesh_materials)
{
::MeshMaterialManager.Remove(mat, &gfx_backup->GetUpdater());
}
mesh_materials.clear();
while (hGroup.FindNextEntry(C4CFN_DefMaterials, MaterialFilename, NULL, !!*MaterialFilename))
{
StdStrBuf material;
@ -416,7 +424,8 @@ void C4Def::LoadMeshMaterials(C4Group &hGroup)
StdStrBuf buf;
buf.Copy(hGroup.GetName());
buf.Append("/"); buf.Append(MaterialFilename);
::MeshMaterialManager.Parse(material.getData(), buf.getData(), loader);
auto new_materials = ::MeshMaterialManager.Parse(material.getData(), buf.getData(), loader);
mesh_materials.insert(new_materials.begin(), new_materials.end());
}
catch (const StdMeshMaterialError& ex)
{

View File

@ -159,7 +159,7 @@ protected:
bool Compile(const char *szSource, const char *szName);
bool Decompile(StdStrBuf *pOut, const char *szName);
private:
void LoadMeshMaterials(C4Group &hGroup);
void LoadMeshMaterials(C4Group &hGroup, C4DefGraphicsPtrBackup *gfx_backup);
bool LoadParticleDef(C4Group &hGroup);
bool LoadSolidMask(C4Group &hGroup);
bool LoadGraphics(C4Group &hGroup, StdMeshSkeletonLoader &loader);
@ -169,6 +169,7 @@ private:
void LoadRankFaces(C4Group &hGroup);
void LoadSounds(C4Group &hGroup, C4SoundSystem* pSoundSystem);
std::set<StdCopyStrBuf> mesh_materials;
// Here begins the C4Def
friend class C4DefList;
@ -203,9 +204,10 @@ public:
void Clear();
void Default();
bool Load(C4Group &hGroup,
StdMeshSkeletonLoader &loader,
DWORD dwLoadWhat, const char *szLanguage,
class C4SoundSystem *pSoundSystem = NULL);
StdMeshSkeletonLoader &loader,
DWORD dwLoadWhat, const char *szLanguage,
class C4SoundSystem *pSoundSystem = nullptr,
C4DefGraphicsPtrBackup *gfx_backup = nullptr);
void Draw(C4Facet &cgo, bool fSelected=false, DWORD iColor=0, C4Object *pObj=NULL, int32_t iPhaseX=0, int32_t iPhaseY=0, C4DrawTransform* trans=NULL, const char * graphicsName=NULL);
inline C4Facet &GetMainFace(C4DefGraphics *pGraphics, DWORD dwClr=0) { MainFace.Surface=pGraphics->GetBitmap(dwClr); return MainFace; }

View File

@ -18,6 +18,7 @@
#include <C4Include.h>
#include <C4DefGraphics.h>
#include "object/C4Def.h"
#include <C4DefList.h>
#include <C4Object.h>
#include <C4ObjectInfo.h>

View File

@ -135,6 +135,8 @@ public:
void AssignUpdate(); // update all game objects with new graphics pointers
void AssignRemoval(); // remove graphics of all defs from all game objects
StdMeshMaterialUpdate &GetUpdater() { return MeshMaterialUpdate; }
private:
void UpdateMesh(StdMeshInstance* instance);

View File

@ -400,7 +400,7 @@ bool C4DefList::Reload(C4Def *pDef, DWORD dwLoadWhat, const char *szLanguage, C4
// clear all skeletons in that group, so that deleted skeletons are also deleted in the engine
SkeletonLoader->RemoveSkeletonsInGroup(hGroup.GetName());
// load the definition
if (!pDef->Load( hGroup, *SkeletonLoader, dwLoadWhat, szLanguage, pSoundSystem)) return false;
if (!pDef->Load(hGroup, *SkeletonLoader, dwLoadWhat, szLanguage, pSoundSystem, &GfxBackup)) return false;
hGroup.Close();
// rebuild quick access table
BuildTable();

View File

@ -16,6 +16,7 @@
#include <C4Include.h>
#include <C4FindObject.h>
#include "object/C4Def.h"
#include <C4DefList.h>
#include <C4Object.h>
#include <C4Game.h>

View File

@ -20,6 +20,7 @@
#include <C4GameObjects.h>
#include <C4Effect.h>
#include "object/C4Def.h"
#include <C4Object.h>
#include <C4ObjectCom.h>
#include <C4Physics.h>

View File

@ -15,6 +15,7 @@
*/
#include "C4Include.h"
#include "script/C4Aul.h"
#include "C4MeshAnimation.h"
#include "C4Object.h"
#include "C4ValueArray.h"

View File

@ -18,6 +18,7 @@
/* Object motion, collision, friction */
#include <C4Include.h>
#include "object/C4Def.h"
#include <C4Object.h>
#include <C4Effect.h>
@ -169,7 +170,7 @@ void C4Object::SideBounds(C4Real &ctcox)
}
// landscape bounds
C4Real lbound = itofix(0 - Shape.GetX()),
rbound = itofix(GBackWdt - (Shape.GetX() + Shape.Wdt));
rbound = itofix(::Landscape.GetWidth() - (Shape.GetX() + Shape.Wdt));
if (ctcox < lbound && GetPropertyInt(P_BorderBound) & C4D_Border_Sides)
StopAndContact(ctcox, lbound, xdir, CNAT_Left);
if (ctcox > rbound && GetPropertyInt(P_BorderBound) & C4D_Border_Sides)
@ -192,7 +193,7 @@ void C4Object::VerticalBounds(C4Real &ctcoy)
}
// landscape bounds
C4Real tbound = itofix(0 - Shape.GetY()),
bbound = itofix(GBackHgt - (Shape.GetY() + Shape.Hgt));
bbound = itofix(::Landscape.GetHeight() - (Shape.GetY() + Shape.Hgt));
if (ctcoy < tbound && GetPropertyInt(P_BorderBound) & C4D_Border_Top)
StopAndContact(ctcoy, tbound, ydir, CNAT_Top);
if (ctcoy > bbound && GetPropertyInt(P_BorderBound) & C4D_Border_Bottom)
@ -578,8 +579,8 @@ bool C4Object::ExecMovement() // Every Tick1 by Execute
if (!Def->Rotateable) fix_r=Fix0;
// Out of bounds check
if ((!Inside<int32_t>(GetX() + Shape.GetX(), -Shape.Wdt, GBackWdt) && !(GetPropertyInt(P_BorderBound) & C4D_Border_Sides))
|| ((GetY() + Shape.GetY() > GBackHgt) && !(GetPropertyInt(P_BorderBound) & C4D_Border_Bottom)))
if ((!Inside<int32_t>(GetX() + Shape.GetX(), -Shape.Wdt, ::Landscape.GetWidth()) && !(GetPropertyInt(P_BorderBound) & C4D_Border_Sides))
|| ((GetY() + Shape.GetY() > ::Landscape.GetHeight()) && !(GetPropertyInt(P_BorderBound) & C4D_Border_Bottom)))
{
C4PropList* pActionDef = GetAction();
// Never remove attached objects: If they are truly outside landscape, their target will be removed,
@ -593,9 +594,9 @@ bool C4Object::ExecMovement() // Every Tick1 by Execute
int parX, parY;
GetParallaxity(&parX, &parY);
fRemove = false;
if (GetX()>GBackWdt || GetY()>GBackHgt) fRemove = true; // except if they are really out of the viewport to the right...
if (GetX()>::Landscape.GetWidth() || GetY()>::Landscape.GetHeight()) fRemove = true; // except if they are really out of the viewport to the right...
else if (GetX()<0 && !!parX) fRemove = true; // ...or it's not HUD horizontally and it's out to the left
else if (!parX && GetX()<-GBackWdt) fRemove = true; // ...or it's HUD horizontally and it's out to the left
else if (!parX && GetX()<-::Landscape.GetWidth()) fRemove = true; // ...or it's HUD horizontally and it's out to the left
}
if (fRemove)
{
@ -628,7 +629,7 @@ bool SimFlight(C4Real &x, C4Real &y, C4Real &xdir, C4Real &ydir, int32_t iDensit
// Movement to target
ctcox=fixtoi(x); ctcoy=fixtoi(y);
// Bounds
if (!Inside<int32_t>(ctcox,0,GBackWdt) || (ctcoy>=GBackHgt))
if (!Inside<int32_t>(ctcox,0,::Landscape.GetWidth()) || (ctcoy>=::Landscape.GetHeight()))
return false;
// Move to target
do

View File

@ -21,6 +21,7 @@
#include <C4Object.h>
#include <C4AulExec.h>
#include "object/C4Def.h"
#include <C4DefList.h>
#include <C4Effect.h>
#include <C4ObjectInfo.h>
@ -581,6 +582,14 @@ void C4Object::DrawFaceImpl(C4TargetFacet &cgo, bool action, float fx, float fy,
if (!C4ValueToMatrix(value, &matrix))
matrix = StdMeshMatrix::Identity();
if (fix_r != Fix0)
{
const auto mesh_center = pMeshInstance->GetMesh().GetBoundingBox().GetCenter();
matrix = StdMeshMatrix::Translate(-mesh_center.x, -mesh_center.y, -mesh_center.z) * matrix;
matrix = StdMeshMatrix::Rotate(fixtof(fix_r) * (M_PI / 180.0f), 0.0f, 0.0f, 1.0f) * matrix;
matrix = StdMeshMatrix::Translate(mesh_center.x, mesh_center.y, mesh_center.z) * matrix;
}
if(twdt != fwdt || thgt != fhgt)
{
// Also scale Z so that the mesh is not totally distorted and
@ -623,8 +632,8 @@ void C4Object::DrawFace(C4TargetFacet &cgo, float offX, float offY, int32_t iPha
fhgt = thgt;
}
// Straight
if ((!Def->Rotateable || (fix_r == Fix0)) && !pDrawTransform)
// Straight or a mesh; meshes are rotated before the draw transform is applied to ensure correct lighting
if (GetGraphics()->Type == C4DefGraphics::TYPE_Mesh || ((!Def->Rotateable || (fix_r == Fix0)) && !pDrawTransform))
{
DrawFaceImpl(cgo, false, fx, fy, fwdt, fhgt, tx, ty, twdt, thgt, NULL);
/* pDraw->Blit(GetGraphics()->GetBitmap(Color),
@ -696,8 +705,8 @@ void C4Object::DrawActionFace(C4TargetFacet &cgo, float offX, float offY) const
fhgt -= offset_from_top;
}
// Straight
if ((!Def->Rotateable || (fix_r == Fix0)) && !pDrawTransform)
// Straight or a mesh; meshes are rotated before the draw transform is applied to ensure correct lighting
if (GetGraphics()->Type == C4DefGraphics::TYPE_Mesh || ((!Def->Rotateable || (fix_r == Fix0)) && !pDrawTransform))
{
DrawFaceImpl(cgo, true, fx, fy, fwdt, fhgt, tx, ty, twdt, thgt, NULL);
}
@ -4185,7 +4194,7 @@ bool C4Object::SetLightColor(uint32_t iValue)
void C4Object::UpdateLight()
{
if (Landscape.pFoW) Landscape.pFoW->Add(this);
if (Landscape.HasFoW()) Landscape.GetFoW()->Add(this);
}
void C4Object::SetAudibilityAt(C4TargetFacet &cgo, int32_t iX, int32_t iY, int32_t player)
@ -4464,6 +4473,11 @@ void C4Object::UnSelect()
Call(PSF_CrewSelection, &C4AulParSet(true));
}
void C4Object::GetViewPos(float & riX, float & riY, float tx, float ty, const C4Facet & fctViewport) const // get position this object is seen at (for given scroll)
{
if (Category & C4D_Parallax) GetViewPosPar(riX, riY, tx, ty, fctViewport); else { riX = float(GetX()); riY = float(GetY()); }
}
bool C4Object::GetDrawPosition(const C4TargetFacet & cgo,
float & resultx, float & resulty, float & resultzoom) const
{
@ -4691,7 +4705,7 @@ bool C4Object::StatusDeactivate(bool fClearPointers)
// put into inactive list
::Objects.Remove(this);
Status = C4OS_INACTIVE;
if (Landscape.pFoW) Landscape.pFoW->Remove(this);
if (Landscape.HasFoW()) Landscape.GetFoW()->Remove(this);
::Objects.InactiveObjects.Add(this, C4ObjectList::stMain);
// if desired, clear game pointers
if (fClearPointers)
@ -4928,6 +4942,15 @@ bool C4Object::CanConcatPictureWith(C4Object *pOtherObject) const
return true;
}
bool C4Object::IsMoveableBySolidMask(int ComparisonPlane) const
{
return (Status == C4OS_NORMAL)
&& !(Category & C4D_StaticBack)
&& (ComparisonPlane < GetPlane())
&& !Contained
;
}
void C4Object::UpdateScriptPointers()
{
if (pEffects)

View File

@ -20,16 +20,16 @@
#ifndef INC_C4Object
#define INC_C4Object
#include "C4Facet.h"
#include "C4Id.h"
#include "C4Def.h"
#include "C4Sector.h"
#include "C4Value.h"
#include "C4Particles.h"
#include "C4PropList.h"
#include "C4ObjectPtr.h"
#include "StdMesh.h"
#include <C4GameScript.h>
#include "game/C4GameScript.h"
#include "graphics/C4Facet.h"
#include "landscape/C4Particles.h"
#include "lib/StdMesh.h"
#include "object/C4Id.h"
#include "object/C4ObjectPtr.h"
#include "object/C4Sector.h"
#include "object/C4Shape.h"
#include "script/C4PropList.h"
#include "script/C4Value.h"
/* Object status */
@ -199,7 +199,6 @@ public:
void SetPlane(int32_t z) { if (z) Plane = z; Resort(); }
int32_t GetPlane() const { return Plane; }
int32_t GetSolidMaskPlane() const;
int32_t GetAudible() const;
void SetCommand(int32_t iCommand, C4Object *pTarget, C4Value iTx, int32_t iTy=0, C4Object *pTarget2=NULL, bool fControl=false, C4Value iData=C4VNull, int32_t iRetries=0, C4String *szText=NULL);
void SetCommand(int32_t iCommand, C4Object *pTarget=NULL, int32_t iTx=0, int32_t iTy=0, C4Object *pTarget2=NULL, bool fControl=false, C4Value iData=C4VNull, int32_t iRetries=0, C4String *szText=NULL)
{ SetCommand(iCommand, pTarget, C4VInt(iTx), iTy, pTarget2, fControl, iData, iRetries, szText); }
@ -218,8 +217,6 @@ public:
C4Object *ComposeContents(C4ID id);
bool MenuCommand(const char *szCommand);
bool ContainedControl(BYTE byCom);
void Clear();
void ClearInfo(C4ObjectInfo *pInfo);
bool AssignInfo();
@ -290,7 +287,6 @@ public:
void MovePosition(C4Real dx, C4Real dy);
void DoMotion(int32_t mx, int32_t my);
bool ActivateEntrance(int32_t by_plr, C4Object *by_obj);
bool Incinerate(int32_t iCausedBy, bool fBlasted=false, C4Object *pIncineratingObject=NULL);
void DoDamage(int32_t iLevel, int32_t iCausedByPlr, int32_t iCause);
void DoEnergy(int32_t iChange, bool fExact, int32_t iCause, int32_t iCausedByPlr);
void UpdatLastEnergyLossCause(int32_t iNewCausePlr);
@ -359,8 +355,7 @@ public:
bool DoSelect(); // cursor callback if not disabled
void UnSelect(); // unselect callback
void GetViewPos(float &riX, float &riY, float tx, float ty, const C4Facet &fctViewport) const // get position this object is seen at (for given scroll)
{ if (Category & C4D_Parallax) GetViewPosPar(riX, riY, tx, ty, fctViewport); else { riX=float(GetX()); riY=float(GetY()); } }
void GetViewPos(float &riX, float &riY, float tx, float ty, const C4Facet &fctViewport) const;
void GetViewPosPar(float &riX, float &riY, float tx, float ty, const C4Facet &fctViewport) const; // get position this object is seen at, calculating parallaxity
bool PutAwayUnusedObject(C4Object *pToMakeRoomForObject); // either directly put the least-needed object away, or add a command to do it - return whether successful
@ -385,14 +380,7 @@ public:
bool CanConcatPictureWith(C4Object *pOtherObject) const; // return whether this object should be grouped with the other in activation lists, contents list, etc.
bool IsMoveableBySolidMask(int ComparisonPlane) const
{
return (Status == C4OS_NORMAL)
&& !(Category & C4D_StaticBack)
&& (ComparisonPlane < GetPlane())
&& !Contained
;
}
bool IsMoveableBySolidMask(int ComparisonPlane) const;
StdStrBuf GetNeededMatStr() const;

View File

@ -21,6 +21,7 @@
#include <C4ObjectCom.h>
#include <C4Effect.h>
#include "object/C4Def.h"
#include <C4Object.h>
#include <C4Physics.h>
#include <C4Command.h>

View File

@ -20,6 +20,7 @@
#include <C4Include.h>
#include <C4ObjectInfo.h>
#include "object/C4Def.h"
#include <C4DefList.h>
#include <C4Random.h>
#include <C4Components.h>

View File

@ -20,6 +20,7 @@
#include <C4Include.h>
#include <C4ObjectInfoList.h>
#include "object/C4Def.h"
#include <C4DefList.h>
#include <C4ObjectInfo.h>
#include <C4Components.h>

View File

@ -20,6 +20,7 @@
#include <C4Include.h>
#include <C4ObjectList.h>
#include "object/C4Def.h"
#include <C4DefList.h>
#include <C4Object.h>
#include <C4Application.h>

View File

@ -20,6 +20,7 @@
#include "C4ObjectMenu.h"
#include "C4Control.h"
#include "object/C4Def.h"
#include "C4Object.h"
#include "C4ObjectCom.h"
#include "C4Player.h"

View File

@ -177,7 +177,7 @@ void C4Shape::GetVertexOutline(C4Rect &rRect)
inline bool C4Shape::CheckTouchableMaterial(int32_t x, int32_t y, int32_t vtx_i, int32_t ydir, const C4DensityProvider &rDensityProvider) {
return rDensityProvider.GetDensity(x,y) >= ContactDensity &&
((ydir > 0 && !(CNAT_PhaseHalfVehicle & VtxCNAT[vtx_i])) || !IsMCHalfVehicle(GBackPix(x,y)));
((ydir > 0 && !(CNAT_PhaseHalfVehicle & VtxCNAT[vtx_i])) || !IsMCHalfVehicle(::Landscape.GetPix(x,y)));
}
// Adjust given position to one pixel before contact
@ -389,7 +389,7 @@ bool C4Shape::ContactCheck(int32_t cx, int32_t cy, uint32_t *border_hack_contact
if (border_hack_contacts)
{
if (x == 0 && CheckTouchableMaterial(x-1, y, cvtx)) *border_hack_contacts |= CNAT_Left;
else if (x == ::Landscape.Width && CheckTouchableMaterial(x+1, y, cvtx)) *border_hack_contacts |= CNAT_Right;
else if (x == ::Landscape.GetWidth() && CheckTouchableMaterial(x+1, y, cvtx)) *border_hack_contacts |= CNAT_Right;
}
}

View File

@ -245,16 +245,16 @@ bool C4Viewport::ScrollBarsByViewPosition()
{
if (PlayerLock) return false;
NSScrollView* scrollView = pWindow->objectiveCObject<C4WindowController>().scrollView;
[scrollView.horizontalScroller setToLandscapeCoordinate:GetViewX() size:GBackWdt viewportSize:ViewWdt zoom:GetZoom()];
[scrollView.verticalScroller setToLandscapeCoordinate:GetViewY() size:GBackHgt viewportSize:ViewHgt zoom:GetZoom()];
[scrollView.horizontalScroller setToLandscapeCoordinate:GetViewX() size:Landscape.GetWidth() viewportSize:ViewWdt zoom:GetZoom()];
[scrollView.verticalScroller setToLandscapeCoordinate:GetViewY() size:Landscape.GetHeight() viewportSize:ViewHgt zoom:GetZoom()];
return true;
}
bool C4Viewport::ViewPositionByScrollBars()
{
NSScrollView* scrollView = pWindow->objectiveCObject<C4WindowController>().scrollView;
SetViewX([scrollView.horizontalScroller landscapeCoordinateForSize:GBackWdt viewportSize:ViewWdt zoom:GetZoom()]);
SetViewY([scrollView.verticalScroller landscapeCoordinateForSize:GBackHgt viewportSize:ViewHgt zoom:GetZoom()]);
SetViewX([scrollView.horizontalScroller landscapeCoordinateForSize:Landscape.GetWidth() viewportSize:ViewWdt zoom:GetZoom()]);
SetViewY([scrollView.verticalScroller landscapeCoordinateForSize:Landscape.GetHeight() viewportSize:ViewHgt zoom:GetZoom()]);
return true;
}

View File

@ -21,6 +21,7 @@
#include <C4Player.h>
#include <C4Application.h>
#include "object/C4Def.h"
#include <C4DefList.h>
#include <C4Object.h>
#include <C4ObjectInfo.h>
@ -196,8 +197,8 @@ void C4Player::Execute()
{
// player has selected a team that has a valid start position assigned
// set view to this position!
ViewX = Game.C4S.PlrStart[iPlrStartIndex-1].Position[0] * ::Landscape.MapZoom;
ViewY = Game.C4S.PlrStart[iPlrStartIndex-1].Position[1] * ::Landscape.MapZoom;
ViewX = Game.C4S.PlrStart[iPlrStartIndex-1].Position[0] * ::Landscape.GetMapZoom();
ViewY = Game.C4S.PlrStart[iPlrStartIndex-1].Position[1] * ::Landscape.GetMapZoom();
}
}
}
@ -289,7 +290,7 @@ bool C4Player::Init(int32_t iNumber, int32_t iAtClient, const char *szAtClientNa
Name.Copy(pInfo->GetName());
// view pos init: Start at center pos
ViewX = GBackWdt/2; ViewY = GBackHgt/2;
ViewX = ::Landscape.GetWidth()/2; ViewY = ::Landscape.GetHeight()/2;
// Scenario init
if (fScenarioInit)
@ -632,8 +633,8 @@ bool C4Player::ScenarioInit()
pty = Game.C4S.PlrStart[PlrStartIndex].Position[1];
// Zoomed position
if (ptx>-1) ptx = Clamp<int32_t>( ptx * Game.C4S.Landscape.MapZoom.Evaluate(), 0, GBackWdt-1 );
if (pty>-1) pty = Clamp<int32_t>( pty * Game.C4S.Landscape.MapZoom.Evaluate(), 0, GBackHgt-1 );
if (ptx>-1) ptx = Clamp<int32_t>( ptx * Game.C4S.Landscape.MapZoom.Evaluate(), 0, ::Landscape.GetWidth()-1 );
if (pty>-1) pty = Clamp<int32_t>( pty * Game.C4S.Landscape.MapZoom.Evaluate(), 0, ::Landscape.GetHeight()-1 );
// Standard position (PrefPosition)
if (ptx<0)
@ -653,12 +654,12 @@ bool C4Player::ScenarioInit()
}
Position=iPosition;
// Set x position
ptx=Clamp(16+Position*(GBackWdt-32)/(iMaxPos-1),0,GBackWdt-16);
ptx=Clamp(16+Position*(::Landscape.GetWidth()-32)/(iMaxPos-1),0,::Landscape.GetWidth()-16);
}
// All-random position
if (ptx<0) ptx=16+Random(GBackWdt-32);
if (pty<0) pty=16+Random(GBackHgt-32);
if (ptx<0) ptx=16+Random(::Landscape.GetWidth()-32);
if (pty<0) pty=16+Random(::Landscape.GetHeight()-32);
// Place to solid ground
if (!Game.C4S.PlrStart[PlrStartIndex].EnforcePosition)
@ -1359,8 +1360,8 @@ void C4Player::ScrollView(float iX, float iY, float ViewWdt, float ViewHgt)
if (ViewLock) return;
SetViewMode(C4PVM_Scrolling);
float ViewportScrollBorder = Application.isEditor ? 0 : C4ViewportScrollBorder;
ViewX = Clamp<C4Real>( ViewX+ftofix(iX), ftofix(ViewWdt/2.0f-ViewportScrollBorder), ftofix(GBackWdt+ViewportScrollBorder-ViewWdt/2.0f) );
ViewY = Clamp<C4Real>( ViewY+ftofix(iY), ftofix(ViewHgt/2.0f-ViewportScrollBorder), ftofix(GBackHgt+ViewportScrollBorder-ViewHgt/2.0f) );
ViewX = Clamp<C4Real>( ViewX+ftofix(iX), ftofix(ViewWdt/2.0f-ViewportScrollBorder), ftofix(::Landscape.GetWidth()+ViewportScrollBorder-ViewWdt/2.0f) );
ViewY = Clamp<C4Real>( ViewY+ftofix(iY), ftofix(ViewHgt/2.0f-ViewportScrollBorder), ftofix(::Landscape.GetHeight()+ViewportScrollBorder-ViewHgt/2.0f) );
}
void C4Player::ClearControl()

View File

@ -22,6 +22,7 @@
#include <C4Game.h>
#include <C4MessageInput.h>
#include <C4Log.h>
#include "object/C4Def.h"
#include <C4Object.h>
#include "C4AulExec.h"

View File

@ -26,6 +26,8 @@
#include <C4Game.h>
#include <C4Log.h>
#include <C4Record.h>
#include "object/C4Def.h"
#include "script/C4ScriptHost.h"
#include <algorithm>
C4AulExec AulExec;

View File

@ -21,9 +21,11 @@
#include <C4Include.h>
#include <C4Effect.h>
#include "object/C4Def.h"
#include <C4DefList.h>
#include <C4Object.h>
#include <C4Game.h>
#include "script/C4Aul.h"
void C4Effect::AssignCallbackFunctions()
{

View File

@ -17,6 +17,8 @@
#include <C4Include.h>
#include <C4PropList.h>
#include "script/C4Aul.h"
#include <C4GameObjects.h>
#include <C4Game.h>
#include <C4Object.h>

View File

@ -18,10 +18,12 @@
#include <C4Value.h>
#include <C4AulExec.h>
#include "object/C4Def.h"
#include <C4DefList.h>
#include <C4StringTable.h>
#include <C4ValueArray.h>
#include <C4Game.h>
#include "game/C4GameScript.h"
#include <C4GameObjects.h>
#include <C4Object.h>
#include <C4Log.h>