From 50b5fdf80c50ba861398b756f9543e4eb5410039 Mon Sep 17 00:00:00 2001 From: 0TheSpy Date: Wed, 16 Jun 2021 18:48:15 +0300 Subject: [PATCH] Add files via upload --- SpyCustom/sdk/ListPanel.h | 304 ++ SpyCustom/sdk/MaterialSystemUtil.h | 72 + SpyCustom/sdk/Menu.h | 262 ++ SpyCustom/sdk/MenuItem.h | 107 + SpyCustom/sdk/MessageMap.h | 327 ++ SpyCustom/sdk/MouseCode.h | 15 + SpyCustom/sdk/PHandle.h | 70 + SpyCustom/sdk/Panel.h | 962 ++++ SpyCustom/sdk/PanelAnimationVar.h | 153 + SpyCustom/sdk/ParticleSphereRenderer.h | 210 + SpyCustom/sdk/RichText.h | 234 + SpyCustom/sdk/SndInfo.h | 51 + SpyCustom/sdk/SteamCommon.h | 623 +++ SpyCustom/sdk/TextEntry.h | 280 ++ SpyCustom/sdk/TextImage.h | 118 + SpyCustom/sdk/ToggleButton.h | 38 + SpyCustom/sdk/Tooltip.h | 66 + SpyCustom/sdk/lightdesc.h | 139 + SpyCustom/sdk/localflexcontroller.h | 21 + SpyCustom/sdk/logging.h | 421 ++ SpyCustom/sdk/math_pfns.h | 66 + SpyCustom/sdk/mathlib.h | 1785 ++++++++ SpyCustom/sdk/mem.h | 40 + SpyCustom/sdk/memalloc.h | 567 +++ SpyCustom/sdk/memdbgoff.h | 16 + SpyCustom/sdk/memdbgon.h | 219 + SpyCustom/sdk/mempool.h | 590 +++ SpyCustom/sdk/meshreader.h | 231 + SpyCustom/sdk/meshutils.h | 16 + SpyCustom/sdk/messagebox.h | 74 + SpyCustom/sdk/minidump.h | 57 + SpyCustom/sdk/modelloader.h | 148 + SpyCustom/sdk/modes.h | 15 + SpyCustom/sdk/mouthinfo.h | 178 + SpyCustom/sdk/networkstringtabledefs.h | 63 + SpyCustom/sdk/networkvar.h | 737 +++ SpyCustom/sdk/particle_iterators.h | 222 + SpyCustom/sdk/particle_parse.h | 66 + SpyCustom/sdk/particle_property.h | 110 + SpyCustom/sdk/particle_property_inlines.h | 25 + SpyCustom/sdk/particle_util.h | 289 ++ SpyCustom/sdk/particledraw.h | 56 + SpyCustom/sdk/particlemgr.h | 617 +++ SpyCustom/sdk/particles.h | 1954 ++++++++ SpyCustom/sdk/particles_new.h | 295 ++ SpyCustom/sdk/particles_simple.h | 206 + SpyCustom/sdk/platform.h | 1280 ++++++ SpyCustom/sdk/playernet_vars.h | 113 + SpyCustom/sdk/precipitation_shared.h | 22 + SpyCustom/sdk/predictable_entity.h | 185 + SpyCustom/sdk/predictableid.h | 53 + SpyCustom/sdk/predictioncopy.h | 278 ++ SpyCustom/sdk/ragdoll.h | 111 + SpyCustom/sdk/ragdoll_shared.h | 135 + SpyCustom/sdk/random.h | 77 + SpyCustom/sdk/rangecheckedvar.h | 109 + SpyCustom/sdk/recvproxy.h | 45 + SpyCustom/sdk/refcount.h | 320 ++ SpyCustom/sdk/sceneentity_shared.h | 96 + SpyCustom/sdk/sdk_hud_chat.h | 79 + SpyCustom/sdk/seemath.h | 5073 +++++++++++++++++++++ SpyCustom/sdk/sendproxy.h | 52 + SpyCustom/sdk/sequence_Transitioner.h | 34 + SpyCustom/sdk/shake.h | 47 + SpyCustom/sdk/shared_classnames.h | 17 + SpyCustom/sdk/shareddefs.h | 838 ++++ SpyCustom/sdk/shattersurfacetypes.h | 13 + SpyCustom/sdk/smartptr.h | 227 + SpyCustom/sdk/soundflags.h | 161 + SpyCustom/sdk/ssemath.h | 5027 ++++++++++++++++++++ SpyCustom/sdk/steam.h | 79 + SpyCustom/sdk/steamtypes.h | 145 + SpyCustom/sdk/string_t.h | 66 + SpyCustom/sdk/stringpool.h | 465 ++ SpyCustom/sdk/strtools.h | 660 +++ SpyCustom/sdk/studio.h | 2781 +++++++++++ SpyCustom/sdk/tempentity.h | 31 + SpyCustom/sdk/texture_group_names.h | 36 + SpyCustom/sdk/threadtools.h | 1402 ++++++ SpyCustom/sdk/tier1.h | 68 + SpyCustom/sdk/tier2.h | 92 + SpyCustom/sdk/tier2_logging.h | 65 + SpyCustom/sdk/tier3.h | 45 + SpyCustom/sdk/timedevent.h | 50 + SpyCustom/sdk/timeutils.h | 149 + SpyCustom/sdk/touchlink.h | 29 + SpyCustom/sdk/trace.h | 48 + SpyCustom/sdk/tslist.h | 948 ++++ SpyCustom/sdk/uniqueid.h | 37 + SpyCustom/sdk/usercmd.h | 295 ++ SpyCustom/sdk/userid.h | 27 + SpyCustom/sdk/utlblockmemory.h | 294 ++ SpyCustom/sdk/utlbuffer.h | 1157 +++++ SpyCustom/sdk/utldict.h | 278 ++ SpyCustom/sdk/utlenvelope.h | 221 + SpyCustom/sdk/utlfixedmemory.h | 302 ++ SpyCustom/sdk/utlflags.h | 92 + SpyCustom/sdk/utlhandletable.h | 499 ++ SpyCustom/sdk/utlhash.h | 732 +++ 99 files changed, 38600 insertions(+) create mode 100644 SpyCustom/sdk/ListPanel.h create mode 100644 SpyCustom/sdk/MaterialSystemUtil.h create mode 100644 SpyCustom/sdk/Menu.h create mode 100644 SpyCustom/sdk/MenuItem.h create mode 100644 SpyCustom/sdk/MessageMap.h create mode 100644 SpyCustom/sdk/MouseCode.h create mode 100644 SpyCustom/sdk/PHandle.h create mode 100644 SpyCustom/sdk/Panel.h create mode 100644 SpyCustom/sdk/PanelAnimationVar.h create mode 100644 SpyCustom/sdk/ParticleSphereRenderer.h create mode 100644 SpyCustom/sdk/RichText.h create mode 100644 SpyCustom/sdk/SndInfo.h create mode 100644 SpyCustom/sdk/SteamCommon.h create mode 100644 SpyCustom/sdk/TextEntry.h create mode 100644 SpyCustom/sdk/TextImage.h create mode 100644 SpyCustom/sdk/ToggleButton.h create mode 100644 SpyCustom/sdk/Tooltip.h create mode 100644 SpyCustom/sdk/lightdesc.h create mode 100644 SpyCustom/sdk/localflexcontroller.h create mode 100644 SpyCustom/sdk/logging.h create mode 100644 SpyCustom/sdk/math_pfns.h create mode 100644 SpyCustom/sdk/mathlib.h create mode 100644 SpyCustom/sdk/mem.h create mode 100644 SpyCustom/sdk/memalloc.h create mode 100644 SpyCustom/sdk/memdbgoff.h create mode 100644 SpyCustom/sdk/memdbgon.h create mode 100644 SpyCustom/sdk/mempool.h create mode 100644 SpyCustom/sdk/meshreader.h create mode 100644 SpyCustom/sdk/meshutils.h create mode 100644 SpyCustom/sdk/messagebox.h create mode 100644 SpyCustom/sdk/minidump.h create mode 100644 SpyCustom/sdk/modelloader.h create mode 100644 SpyCustom/sdk/modes.h create mode 100644 SpyCustom/sdk/mouthinfo.h create mode 100644 SpyCustom/sdk/networkstringtabledefs.h create mode 100644 SpyCustom/sdk/networkvar.h create mode 100644 SpyCustom/sdk/particle_iterators.h create mode 100644 SpyCustom/sdk/particle_parse.h create mode 100644 SpyCustom/sdk/particle_property.h create mode 100644 SpyCustom/sdk/particle_property_inlines.h create mode 100644 SpyCustom/sdk/particle_util.h create mode 100644 SpyCustom/sdk/particledraw.h create mode 100644 SpyCustom/sdk/particlemgr.h create mode 100644 SpyCustom/sdk/particles.h create mode 100644 SpyCustom/sdk/particles_new.h create mode 100644 SpyCustom/sdk/particles_simple.h create mode 100644 SpyCustom/sdk/platform.h create mode 100644 SpyCustom/sdk/playernet_vars.h create mode 100644 SpyCustom/sdk/precipitation_shared.h create mode 100644 SpyCustom/sdk/predictable_entity.h create mode 100644 SpyCustom/sdk/predictableid.h create mode 100644 SpyCustom/sdk/predictioncopy.h create mode 100644 SpyCustom/sdk/ragdoll.h create mode 100644 SpyCustom/sdk/ragdoll_shared.h create mode 100644 SpyCustom/sdk/random.h create mode 100644 SpyCustom/sdk/rangecheckedvar.h create mode 100644 SpyCustom/sdk/recvproxy.h create mode 100644 SpyCustom/sdk/refcount.h create mode 100644 SpyCustom/sdk/sceneentity_shared.h create mode 100644 SpyCustom/sdk/sdk_hud_chat.h create mode 100644 SpyCustom/sdk/seemath.h create mode 100644 SpyCustom/sdk/sendproxy.h create mode 100644 SpyCustom/sdk/sequence_Transitioner.h create mode 100644 SpyCustom/sdk/shake.h create mode 100644 SpyCustom/sdk/shared_classnames.h create mode 100644 SpyCustom/sdk/shareddefs.h create mode 100644 SpyCustom/sdk/shattersurfacetypes.h create mode 100644 SpyCustom/sdk/smartptr.h create mode 100644 SpyCustom/sdk/soundflags.h create mode 100644 SpyCustom/sdk/ssemath.h create mode 100644 SpyCustom/sdk/steam.h create mode 100644 SpyCustom/sdk/steamtypes.h create mode 100644 SpyCustom/sdk/string_t.h create mode 100644 SpyCustom/sdk/stringpool.h create mode 100644 SpyCustom/sdk/strtools.h create mode 100644 SpyCustom/sdk/studio.h create mode 100644 SpyCustom/sdk/tempentity.h create mode 100644 SpyCustom/sdk/texture_group_names.h create mode 100644 SpyCustom/sdk/threadtools.h create mode 100644 SpyCustom/sdk/tier1.h create mode 100644 SpyCustom/sdk/tier2.h create mode 100644 SpyCustom/sdk/tier2_logging.h create mode 100644 SpyCustom/sdk/tier3.h create mode 100644 SpyCustom/sdk/timedevent.h create mode 100644 SpyCustom/sdk/timeutils.h create mode 100644 SpyCustom/sdk/touchlink.h create mode 100644 SpyCustom/sdk/trace.h create mode 100644 SpyCustom/sdk/tslist.h create mode 100644 SpyCustom/sdk/uniqueid.h create mode 100644 SpyCustom/sdk/usercmd.h create mode 100644 SpyCustom/sdk/userid.h create mode 100644 SpyCustom/sdk/utlblockmemory.h create mode 100644 SpyCustom/sdk/utlbuffer.h create mode 100644 SpyCustom/sdk/utldict.h create mode 100644 SpyCustom/sdk/utlenvelope.h create mode 100644 SpyCustom/sdk/utlfixedmemory.h create mode 100644 SpyCustom/sdk/utlflags.h create mode 100644 SpyCustom/sdk/utlhandletable.h create mode 100644 SpyCustom/sdk/utlhash.h diff --git a/SpyCustom/sdk/ListPanel.h b/SpyCustom/sdk/ListPanel.h new file mode 100644 index 0000000..f4b7ca8 --- /dev/null +++ b/SpyCustom/sdk/ListPanel.h @@ -0,0 +1,304 @@ +#ifndef LISTPANEL_H +#define LISTPANEL_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "utllinkedlist.h" +#include "utlvector.h" +#include "utlrbtree.h" +#include "VGUI.h" +#include "Panel.h" + +class KeyValues; + +namespace vgui +{ + + class ScrollBar; + class TextImage; + class ImagePanel; + class Label; + class Button; + class IDraggerEvent; + class FastSortListPanelItem; + + class ListPanelItem + { + public: + ListPanelItem() : + kv(0), + userData(0), + m_pDragData(0), + m_bImage(false), + m_nImageIndex(-1), + m_nImageIndexSelected(-1), + m_pIcon(0) + { + } + + KeyValues* kv; + unsigned int userData; + KeyValues* m_pDragData; + bool m_bImage; + int m_nImageIndex; + int m_nImageIndexSelected; + IImage* m_pIcon; + }; + + typedef int __cdecl SortFunc( + ListPanel* pPanel, + const ListPanelItem& item1, + const ListPanelItem& item2); + + class ListPanel : public Panel + { + DECLARE_CLASS_SIMPLE(ListPanel, Panel); + + public: + ListPanel(Panel* parent, const char* panelName); + ~ListPanel(); + + enum ColumnFlags_e + { + COLUMN_FIXEDSIZE = 0x01, + COLUMN_RESIZEWITHWINDOW = 0x02, + COLUMN_IMAGE = 0x04, + COLUMN_HIDDEN = 0x08, + COLUMN_UNHIDABLE = 0x10, + }; + + virtual void AddColumnHeader(int index, const char* columnName, const char* columnText, int startingWidth, int minWidth, int maxWidth, int columnFlags = 0); + virtual void AddColumnHeader(int index, const char* columnName, const char* columnText, int width, int columnFlags = 0); + + virtual void RemoveColumn(int column); + virtual int FindColumn(const char* columnName); + virtual void SetColumnHeaderHeight(int height); + virtual void SetColumnHeaderText(int column, const char* text); + virtual void SetColumnHeaderText(int column, wchar_t* text); + virtual void SetColumnHeaderImage(int column, int imageListIndex); + virtual void SetColumnHeaderTooltip(int column, const char* tooltipText); + virtual void SetColumnTextAlignment(int column, int align); + + virtual int GetNumColumnHeaders() const; + virtual bool GetColumnHeaderText(int index, char* pOut, int maxLen); + + virtual void SetSortFunc(int column, SortFunc* func); + virtual void SetSortColumn(int column); + virtual void SortList(void); + virtual void SetColumnSortable(int column, bool sortable); + virtual void SetColumnVisible(int column, bool visible); + int GetSortColumn() const; + + virtual void SetAllowUserModificationOfColumns(bool allowed); + + virtual int AddItem(const KeyValues* data, unsigned int userData, bool bScrollToItem, bool bSortOnAdd); + void SetItemDragData(int itemID, const KeyValues* data); + virtual int GetItemCount(void); + virtual int GetItem(const char* itemName); + virtual KeyValues* GetItem(int itemID); + virtual int GetItemCurrentRow(int itemID); + virtual int GetItemIDFromRow(int currentRow); + virtual unsigned int GetItemUserData(int itemID); + virtual ListPanelItem* GetItemData(int itemID); + virtual void SetUserData(int itemID, unsigned int userData); + virtual int GetItemIDFromUserData(unsigned int userData); + virtual void ApplyItemChanges(int itemID); + virtual void RemoveItem(int itemID); + virtual void RereadAllItems(); + + virtual void RemoveAll(); + virtual void DeleteAllItems(); + + virtual void GetCellText(int itemID, int column, OUT_Z_BYTECAP(bufferSizeInBytes) wchar_t* buffer, int bufferSizeInBytes); + virtual IImage* GetCellImage(int itemID, int column); + + virtual int FirstItem() const; + virtual int NextItem(int iItem) const; + + virtual int InvalidItemID() const; + virtual bool IsValidItemID(int itemID); + + virtual void SetItemVisible(int itemID, bool state); + virtual void SetItemDisabled(int itemID, bool state); + bool IsItemVisible(int itemID); + + virtual void SetFont(HFont font); + + virtual void SetImageList(ImageList* imageList, bool deleteImageListWhenDone); + + virtual int GetSelectedItemsCount(); + + virtual int GetSelectedItem(int selectionIndex); + + virtual void ClearSelectedItems(); + + virtual bool IsItemSelected(int itemID); + + virtual void AddSelectedItem(int itemID); + + virtual void SetSingleSelectedItem(int itemID); + + virtual int GetSelectedColumn(); + + virtual void SetSelectIndividualCells(bool state); + + void SetMultiselectEnabled(bool bState); + bool IsMultiselectEnabled() const; + + virtual void SetSelectedCell(int row, int column); + + virtual bool GetCellAtPos(int x, int y, int& row, int& column); + virtual bool GetCellBounds(int row, int column, int& x, int& y, int& wide, int& tall); + + virtual void SetEmptyListText(const char* text); + virtual void SetEmptyListText(const wchar_t* text); + + void ResetScrollBar(); + + virtual void OnCreateDragData(KeyValues* msg); + + void SetIgnoreDoubleClick(bool state); + + virtual void EnterEditMode(int itemID, int column, vgui::Panel* editPanel); + + virtual void LeaveEditMode(); + + virtual bool IsInEditMode(); + + MESSAGE_FUNC_INT(ResizeColumnToContents, "ResizeColumnToContents", column); + +#ifdef _X360 + virtual void NavigateTo(); +#endif + int m_nUserConfigFileVersion; + + protected: + virtual Panel* GetCellRenderer(int row, int column); + + virtual void OnMouseWheeled(int delta); + virtual void OnSizeChanged(int wide, int tall); + virtual void PerformLayout(); + virtual void Paint(); + virtual void PaintBackground(); + virtual void ApplySchemeSettings(IScheme* pScheme); + virtual void OnMousePressed(MouseCode code); + virtual void OnMouseDoublePressed(MouseCode code); +#ifdef _X360 + virtual void OnKeyCodePressed(KeyCode code); +#else + virtual void OnKeyCodePressed(KeyCode code); +#endif + MESSAGE_FUNC(OnSliderMoved, "ScrollBarSliderMoved"); + MESSAGE_FUNC_INT_INT(OnColumnResized, "ColumnResized", column, delta); + MESSAGE_FUNC_INT(OnSetSortColumn, "SetSortColumn", column); + MESSAGE_FUNC(OpenColumnChoiceMenu, "OpenColumnChoiceMenu"); + MESSAGE_FUNC_INT(OnToggleColumnVisible, "ToggleColumnVisible", col); + virtual float GetRowsPerPage(); + virtual int GetStartItem(); + + virtual void ApplyUserConfigSettings(KeyValues* userConfig); + virtual void GetUserConfigSettings(KeyValues* userConfig); + virtual bool HasUserConfigSettings(); + + public: + virtual void SetSortColumnEx(int iPrimarySortColumn, int iSecondarySortColumn, bool bSortAscending); + void GetSortColumnEx(int& iPrimarySortColumn, int& iSecondarySortColumn, bool& bSortAscending) const; + + private: + void CleanupItem(FastSortListPanelItem* data); + + void IndexItem(int itemID); + + void UpdateSelection(vgui::MouseCode code, int x, int y, int row, int column); + + void HandleMultiSelection(int itemID, int row, int column); + + void HandleAddSelection(int itemID, int row, int column); + + struct IndexItem_t + { + ListPanelItem* dataItem; + int duplicateIndex; + }; + typedef CUtlRBTree IndexRBTree_t; + + struct column_t + { + Button* m_pHeader; + int m_iMinWidth; + int m_iMaxWidth; + bool m_bResizesWithWindow; + Panel* m_pResizer; + SortFunc* m_pSortFunc; + bool m_bTypeIsText; + bool m_bHidden; + bool m_bUnhidable; + IndexRBTree_t m_SortedTree; + int m_nContentAlignment; + }; + + CUtlLinkedList m_ColumnsData; + + CUtlVector m_ColumnsHistory; + + CUtlVector m_CurrentColumns; + + int m_iColumnDraggerMoved; + int m_lastBarWidth; + + CUtlLinkedList m_DataItems; + CUtlVector m_VisibleItems; + + int m_iSortColumn; + int m_iSortColumnSecondary; + + void ResortColumnRBTree(int col); + static bool RBTreeLessFunc(vgui::ListPanel::IndexItem_t& item1, vgui::ListPanel::IndexItem_t& item2); + + TextImage* m_pTextImage; + ImagePanel* m_pImagePanel; + Label* m_pLabel; + ScrollBar* m_hbar; + ScrollBar* m_vbar; + + int m_iSelectedColumn; + + bool m_bNeedsSort : 1; + bool m_bSortAscending : 1; + bool m_bSortAscendingSecondary : 1; + bool m_bCanSelectIndividualCells : 1; + bool m_bShiftHeldDown : 1; + bool m_bMultiselectEnabled : 1; + bool m_bAllowUserAddDeleteColumns : 1; + bool m_bDeleteImageListWhenDone : 1; + bool m_bIgnoreDoubleClick : 1; + + int m_iHeaderHeight; + int m_iRowHeight; + + CUtlVector m_SelectedItems; + int m_LastItemSelected; + + int m_iTableStartX; + int m_iTableStartY; + + Color m_LabelFgColor; + Color m_DisabledColor; + Color m_SelectionFgColor; + Color m_DisabledSelectionFgColor; + + ImageList* m_pImageList; + TextImage* m_pEmptyListText; + + PHandle m_hEditModePanel; + int m_iEditModeItemID; + int m_iEditModeColumn; + + void ResetColumnHeaderCommands(); + }; + +} + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/MaterialSystemUtil.h b/SpyCustom/sdk/MaterialSystemUtil.h new file mode 100644 index 0000000..bb2e8ca --- /dev/null +++ b/SpyCustom/sdk/MaterialSystemUtil.h @@ -0,0 +1,72 @@ +#ifndef MATERIALSYSTEMUTIL_H +#define MATERIALSYSTEMUTIL_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "imageformat.h" +#include "imaterialsystem.h" + +class IMaterial; +class ITexture; +class KeyValues; + +class KeyValues; + + +class CMaterialReference +{ +public: + CMaterialReference(char const* pMaterialName = 0, const char* pTextureGroupName = 0, bool bComplain = true); + ~CMaterialReference(); + + void Init(const char* pMaterialName, const char* pTextureGroupName, bool bComplain = true); + void Init(const char* pMaterialName, KeyValues* pVMTKeyValues); + void Init(IMaterial* pMaterial); + void Init(CMaterialReference& ref); + void Init(const char* pMaterialName, const char* pTextureGroupName, KeyValues* pVMTKeyValues); + + void Shutdown(); + bool IsValid() { return m_pMaterial != 0; } + + operator IMaterial* () { return m_pMaterial; } + operator IMaterial* () const { return m_pMaterial; } + operator IMaterial const* () const { return m_pMaterial; } + IMaterial* operator->() { return m_pMaterial; } + +private: + IMaterial* m_pMaterial; +}; + +class CTextureReference +{ +public: + CTextureReference(); + CTextureReference(const CTextureReference& ref); + ~CTextureReference(); + + void Init(char const* pTexture, const char* pTextureGroupName, bool bComplain = true); + void InitProceduralTexture(const char* pTextureName, const char* pTextureGroupName, int w, int h, ImageFormat fmt, int nFlags); + void InitRenderTarget(int w, int h, RenderTargetSizeMode_t sizeMode, ImageFormat fmt, MaterialRenderTargetDepth_t depth, bool bHDR, char* pStrOptionalName = NULL); +#if defined( _X360 ) + void InitRenderTargetTexture(int width, int height, RenderTargetSizeMode_t sizeMode, ImageFormat fmt, MaterialRenderTargetDepth_t depth, bool bHDR, char* pStrOptionalName = NULL); + void InitRenderTargetSurface(int width, int height, ImageFormat fmt, bool bSameAsTexture); +#endif + void Init(ITexture* pTexture); + + void Shutdown(bool bDeleteIfUnReferenced = false); + bool IsValid() { return m_pTexture != 0; } + + operator ITexture* () { return m_pTexture; } + operator ITexture const* () const { return m_pTexture; } + ITexture* operator->() { return m_pTexture; } + + void operator=(CTextureReference& ref); + +private: + ITexture* m_pTexture; +}; + + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/Menu.h b/SpyCustom/sdk/Menu.h new file mode 100644 index 0000000..6f51fa4 --- /dev/null +++ b/SpyCustom/sdk/Menu.h @@ -0,0 +1,262 @@ +#ifndef MENU_H +#define MENU_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "Panel.h" +#include "Label.h" +#include "utllinkedlist.h" +#include "utlvector.h" + +namespace vgui +{ + + class MenuItem; + class ScrollBar; + class MenuSeparator; + + class Menu : public Panel + { + DECLARE_CLASS_SIMPLE(Menu, Panel); + friend class MenuItem; + public: + enum MenuDirection_e + { + LEFT, + RIGHT, + UP, + DOWN, + CURSOR, + ALIGN_WITH_PARENT, + }; + + Menu(Panel* parent, const char* panelName); + ~Menu(); + + static void PlaceContextMenu(Panel* parent, Menu* menu); + static void OnInternalMousePressed(Panel* other, MouseCode code); + + virtual void PositionRelativeToPanel(Panel* reference, MenuDirection_e direction, int nAdditionalYOffset = 0, bool showMenu = false); + + virtual int AddMenuItem(const char* itemName, const char* itemText, const char* command, Panel* target, const KeyValues* userData = NULL); + virtual int AddMenuItem(const char* itemName, const wchar_t* wszItemText, const char* command, Panel* target, const KeyValues* userData = NULL); + + virtual int AddMenuItem(const char* itemName, const char* itemText, KeyValues* message, Panel* target, const KeyValues* userData = NULL); + virtual int AddMenuItem(const char* itemName, const wchar_t* wszItemText, KeyValues* message, Panel* target, const KeyValues* userData = NULL); + + virtual int AddMenuItem(const char* itemText, const char* command, Panel* target, const KeyValues* userData = NULL); + virtual int AddMenuItem(const char* itemText, KeyValues* message, Panel* target, const KeyValues* userData = NULL); + virtual int AddMenuItem(const char* itemText, Panel* target, const KeyValues* userData = NULL); + + virtual int AddCheckableMenuItem(const char* itemName, const char* itemText, const char* command, Panel* target, const KeyValues* userData = NULL); + virtual int AddCheckableMenuItem(const char* itemName, const wchar_t* wszItemText, const char* command, Panel* target, const KeyValues* userData = NULL); + + virtual int AddCheckableMenuItem(const char* itemName, const char* itemText, KeyValues* message, Panel* target, const KeyValues* userData = NULL); + virtual int AddCheckableMenuItem(const char* itemName, const wchar_t* wszItemText, KeyValues* message, Panel* target, const KeyValues* userData = NULL); + + virtual int AddCheckableMenuItem(const char* itemText, const char* command, Panel* target, const KeyValues* userData = NULL); + virtual int AddCheckableMenuItem(const char* itemText, KeyValues* message, Panel* target, const KeyValues* userData = NULL); + virtual int AddCheckableMenuItem(const char* itemText, Panel* target, const KeyValues* userData = NULL); + + virtual int AddCascadingMenuItem(const char* itemName, const char* itemText, const char* command, Panel* target, Menu* cascadeMenu, const KeyValues* userData = NULL); + virtual int AddCascadingMenuItem(const char* itemName, const wchar_t* wszItemText, const char* command, Panel* target, Menu* cascadeMenu, const KeyValues* userData = NULL); + + virtual int AddCascadingMenuItem(const char* itemName, const char* itemText, KeyValues* message, Panel* target, Menu* cascadeMenu, const KeyValues* userData = NULL); + virtual int AddCascadingMenuItem(const char* itemName, const wchar_t* wszItemText, KeyValues* message, Panel* target, Menu* cascadeMenu, const KeyValues* userData = NULL); + + virtual int AddCascadingMenuItem(const char* itemText, const char* command, Panel* target, Menu* cascadeMenu, const KeyValues* userData = NULL); + virtual int AddCascadingMenuItem(const char* itemText, KeyValues* message, Panel* target, Menu* cascadeMenu, const KeyValues* userData = NULL); + virtual int AddCascadingMenuItem(const char* itemText, Panel* target, Menu* cascadeMenu, const KeyValues* userData = NULL); + + virtual int AddMenuItem(MenuItem* panel); + + virtual void AddSeparator(); + virtual void AddSeparatorAfterItem(int itemID); + + virtual void UpdateMenuItem(int itemID, const char* itemText, KeyValues* message, const KeyValues* userData = NULL); + virtual void UpdateMenuItem(int itemID, const wchar_t* wszItemText, KeyValues* message, const KeyValues* userData = NULL); + + virtual void MoveMenuItem(int itemID, int moveBeforeThisItemID); + + virtual bool IsValidMenuID(int itemID); + virtual int GetInvalidMenuID(); + + KeyValues* GetItemUserData(int itemID); + void GetItemText(int itemID, wchar_t* text, int bufLenInBytes); + void GetItemText(int itemID, char* text, int bufLenInBytes); + + virtual void SetItemEnabled(const char* itemName, bool state); + virtual void SetItemEnabled(int itemID, bool state); + virtual void SetItemVisible(const char* itemName, bool visible); + virtual void SetItemVisible(int itemID, bool visible); + + void DeleteItem(int itemID); + + void DeleteAllItems(); + + virtual void SetFixedWidth(int width); + + void SetContentAlignment(Label::Alignment alignment); + + virtual void SetMenuItemHeight(int itemHeight); + virtual int GetMenuItemHeight() const; + + virtual void SetNumberOfVisibleItems(int numItems); + + void EnableUseMenuManager(bool bUseMenuManager); + + virtual void PerformLayout(void); + + virtual void SetBorder(class IBorder* border); + virtual void ApplySchemeSettings(IScheme* pScheme); + + enum MenuTypeAheadMode + { + COMPAT_MODE = 0, + HOT_KEY_MODE, + TYPE_AHEAD_MODE, + }; + virtual void SetTypeAheadMode(MenuTypeAheadMode mode); + virtual int GetTypeAheadMode(); + + virtual void OnKeyTyped(wchar_t unichar); + virtual void OnKeyCodeTyped(KeyCode code); + + virtual void SetVisible(bool state); + + virtual void ActivateItem(int itemID); + virtual void SilentActivateItem(int itemID); + virtual void ActivateItemByRow(int row); + virtual int GetActiveItem(); + + virtual int GetItemCount(); + + virtual int GetMenuID(int index); + + int GetCurrentlyVisibleItemsCount(); + + MenuItem* GetMenuItem(int itemID); + void CloseOtherMenus(MenuItem* item); + virtual void OnKillFocus(); + + int GetMenuMode(); + enum MenuMode + { + MOUSE = 0, + KEYBOARD, + }; + + void SetCurrentlyHighlightedItem(int itemID); + int GetCurrentlyHighlightedItem(); + void ClearCurrentlyHighlightedItem(); + + void SetMenuItemChecked(int itemID, bool state); + bool IsChecked(int index); + + + void SetMinimumWidth(int width); + int GetMinimumWidth(); + + virtual void SetFgColor(Color newColor); + virtual void SetBgColor(Color newColor); + + virtual void SetFont(HFont font); + + void SetCurrentKeyBinding(int itemID, char const* hotkey); + + void ForceCalculateWidth(); + + void SetUseFallbackFont(bool bState, HFont hFallback); + + protected: + int AddMenuItemCharCommand(MenuItem* item, const char* command, Panel* target, const KeyValues* userData); + int AddMenuItemKeyValuesCommand(MenuItem* item, KeyValues* message, Panel* target, const KeyValues* userData); + + virtual void OnCommand(const char* command); + MESSAGE_FUNC_PTR(OnMenuItemSelected, "MenuItemSelected", panel); + virtual void AddScrollBar(); + virtual void RemoveScrollBar(); + MESSAGE_FUNC(OnSliderMoved, "ScrollBarSliderMoved"); + virtual void Paint(); + virtual void LayoutMenuBorder(); + virtual void MakeItemsVisibleInScrollRange(int maxVisibleItems, int nNumPixelsAvailable); + virtual void OnMouseWheeled(int delta); + virtual void OnHotKey(wchar_t unichar); + virtual void OnTypeAhead(wchar_t unichar); + + int CountVisibleItems(); + void ComputeWorkspaceSize(int& workWide, int& workTall); + int ComputeFullMenuHeightWithInsets(); + + void CalculateWidth(); + + void LayoutScrollBar(); + void PositionCascadingMenu(); + void SizeMenuItems(); + void OnCursorMoved(int x, int y); + void OnKeyCodePressed(KeyCode code); + void OnMenuClose(); + MESSAGE_FUNC(OnKeyModeSet, "KeyModeSet"); + + void SetCurrentlySelectedItem(MenuItem* item); + void SetCurrentlySelectedItem(int itemID); + MESSAGE_FUNC_INT(OnCursorEnteredMenuItem, "CursorEnteredMenuItem", VPanel); + MESSAGE_FUNC_INT(OnCursorExitedMenuItem, "CursorExitedMenuItem", VPanel); + + void MoveAlongMenuItemList(int direction, int loopCount); + + enum + { + DEFAULT_MENU_ITEM_HEIGHT = 22, + MENU_UP = -1, + MENU_DOWN = 1 + }; + +#ifdef DBGFLAG_VALIDATE + virtual void Validate(CValidator& validator, char* pchName); +#endif + + private: + MenuItem* GetParentMenuItem(); + + int m_iMenuItemHeight; + int m_iFixedWidth; + int m_iMinimumWidth; + int m_iNumVisibleLines; + ScrollBar* m_pScroller; + + CUtlLinkedList m_MenuItems; + + CUtlVector m_VisibleSortedItems; + CUtlVector m_SortedItems; + CUtlVector m_Separators; + CUtlVector m_SeparatorPanels; + + bool _sizedForScrollBar : 1; + bool m_bUseFallbackFont : 1; + bool _recalculateWidth : 1; + bool m_bUseMenuManager : 1; + + int _menuWide; + int m_iCurrentlySelectedItemID; + int m_iInputMode; + int m_iCheckImageWidth; + int m_iProportionalScrollBarSize; + Label::Alignment m_Alignment; + Color _borderDark; + int m_iActivatedItem; + HFont m_hItemFont; + HFont m_hFallbackItemFont; + +#define TYPEAHEAD_BUFSIZE 256 + MenuTypeAheadMode m_eTypeAheadMode; + wchar_t m_szTypeAheadBuf[TYPEAHEAD_BUFSIZE]; + int m_iNumTypeAheadChars; + double m_fLastTypeAheadTime; + }; + +} + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/MenuItem.h b/SpyCustom/sdk/MenuItem.h new file mode 100644 index 0000000..aef2cbb --- /dev/null +++ b/SpyCustom/sdk/MenuItem.h @@ -0,0 +1,107 @@ +#ifndef MENUITEM_H +#define MENUITEM_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "VGUI.h" +#include "Button.h" +#include "Menu.h" + +namespace vgui +{ + + class IBorder; + class TextImage; + class Menu; + class Image; + + class MenuItem : public Button + { + DECLARE_CLASS_SIMPLE(MenuItem, Button); + + public: + MenuItem(Menu* parent, const char* panelName, const char* text, Menu* cascadeMenu = NULL, bool checkable = false); + MenuItem(Menu* parent, const char* panelName, const wchar_t* wszText, Menu* cascadeMenu = NULL, bool checkable = false); + ~MenuItem(); + + virtual void Paint(); + + virtual void FireActionSignal(); + + virtual bool CanBeDefaultButton(void); + + void OnCursorEntered(); + void OnCursorExited(); + + void CloseCascadeMenu(); + + MESSAGE_FUNC(OnKillFocus, "MenuClose"); + + bool HasMenu(); + + void SetTextImageSize(int wide, int tall); + + void GetTextImageSize(int& wide, int& tall); + + void GetArrowImageSize(int& wide, int& tall); + + void GetCheckImageSize(int& wide, int& tall); + + Menu* GetMenu(); + + virtual void PerformLayout(); + + void OnCursorMoved(int x, int y); + + MESSAGE_FUNC(ArmItem, "ArmItem"); + MESSAGE_FUNC(DisarmItem, "DisarmItem"); + + bool IsItemArmed(); + + void OpenCascadeMenu(); + + bool IsCheckable(); + bool IsChecked(); + + void SetChecked(bool state); + + KeyValues* GetUserData(); + void SetUserData(const KeyValues* kv); + + int GetActiveItem() { if (m_pCascadeMenu) { return m_pCascadeMenu->GetActiveItem(); } else { return 0; } } + + Menu* GetParentMenu(); + + void SetCurrentKeyBinding(char const* keyName); + + virtual void GetContentSize(int& cw, int& ch); + + protected: + void OnKeyCodeReleased(KeyCode code); + void OnMenuClose(); + MESSAGE_FUNC(OnKeyModeSet, "KeyModeSet"); + + virtual void Init(void); + virtual void ApplySchemeSettings(IScheme* pScheme); + virtual IBorder* GetBorder(bool depressed, bool armed, bool selected, bool keyfocus); + + private: + enum { CHECK_INSET = 6 }; + Menu* m_pCascadeMenu; + bool m_bCheckable; + bool m_bChecked; + TextImage* m_pCascadeArrow; + Image* m_pCheck; + TextImage* m_pBlankCheck; + + TextImage* m_pCurrentKeyBinding; + + KeyValues* m_pUserData; + + }; + +} + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/MessageMap.h b/SpyCustom/sdk/MessageMap.h new file mode 100644 index 0000000..9555f56 --- /dev/null +++ b/SpyCustom/sdk/MessageMap.h @@ -0,0 +1,327 @@ +#ifndef MESSAGEMAP_H +#define MESSAGEMAP_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "dmxelement.h" + +#pragma pointers_to_members( full_generality, virtual_inheritance ) + +namespace vgui +{ + + +#ifndef ARRAYSIZE +#define ARRAYSIZE(p) (sizeof(p)/sizeof(p[0])) +#endif + + + enum DataType_t + { + DATATYPE_VOID, + DATATYPE_CONSTCHARPTR, + DATATYPE_INT, + DATATYPE_FLOAT, + DATATYPE_PTR, + DATATYPE_BOOL, + DATATYPE_KEYVALUES, + DATATYPE_CONSTWCHARPTR, + DATATYPE_UINT64, + DATATYPE_HANDLE, + }; + + class Panel; + typedef uintp VPANEL; + + typedef void (Panel::* MessageFunc_t)(void); + +#pragma warning(disable:4121) + struct MessageMapItem_t + { + const char* name; + ALIGN16 MessageFunc_t func; + + int numParams; + + DataType_t firstParamType; + const char* firstParamName; + + DataType_t secondParamType; + const char* secondParamName; + + int nameSymbol; + int firstParamSymbol; + int secondParamSymbol; + }; + +#define DECLARE_PANELMESSAGEMAP( className ) \ + static void AddToMap( char const *scriptname, vgui::MessageFunc_t function, int paramCount, int p1type, const char *p1name, int p2type, const char *p2name ) \ + { \ + vgui::PanelMessageMap *map = vgui::FindOrAddPanelMessageMap( GetPanelClassName() ); \ + \ + vgui::MessageMapItem_t entry; \ + entry.name = scriptname; \ + entry.func = function; \ + entry.numParams = paramCount; \ + entry.firstParamType = (vgui::DataType_t)p1type; \ + entry.firstParamName = p1name; \ + entry.secondParamType = (vgui::DataType_t)p2type; \ + entry.secondParamName = p2name; \ + entry.nameSymbol = 0; \ + entry.firstParamSymbol = 0; \ + entry.secondParamSymbol = 0; \ + \ + map->entries.AddToTail( entry ); \ + } \ + \ + static void ChainToMap( void ) \ + { \ + static bool chained = false; \ + if ( chained ) \ + return; \ + chained = true; \ + vgui::PanelMessageMap *map = vgui::FindOrAddPanelMessageMap( GetPanelClassName() ); \ + map->pfnClassName = &GetPanelClassName; \ + if ( map && GetPanelBaseClassName() && GetPanelBaseClassName()[0] ) \ + { \ + map->baseMap = vgui::FindOrAddPanelMessageMap( GetPanelBaseClassName() ); \ + } \ + } \ + \ + class className##_RegisterMap; \ + friend class className##_RegisterMap; \ + class className##_RegisterMap \ + { \ + public: \ + className##_RegisterMap() \ + { \ + className::ChainToMap(); \ + } \ + }; \ + className##_RegisterMap m_RegisterClass; \ + \ + virtual vgui::PanelMessageMap *GetMessageMap() \ + { \ + static vgui::PanelMessageMap *s_pMap = vgui::FindOrAddPanelMessageMap( GetPanelClassName() ); \ + return s_pMap; \ + } + +#define VGUI_USEKEYBINDINGMAPS 1 + +#if defined( VGUI_USEKEYBINDINGMAPS ) + +#define DECLARE_CLASS_SIMPLE( className, baseClassName ) \ + typedef baseClassName BaseClass; \ + typedef className ThisClass; \ +public: \ + DECLARE_PANELMESSAGEMAP( className ); \ + DECLARE_PANELANIMATION( className ); \ + DECLARE_KEYBINDINGMAP( className ); \ + static char const *GetPanelClassName() { return #className; } \ + static char const *GetPanelBaseClassName() { return #baseClassName; } + +#define DECLARE_CLASS_SIMPLE_NOBASE( className ) \ + typedef className ThisClass; \ +public: \ + DECLARE_PANELMESSAGEMAP( className ); \ + DECLARE_PANELANIMATION( className ); \ + DECLARE_KEYBINDINGMAP( className ); \ + static char const *GetPanelClassName() { return #className; } \ + static char const *GetPanelBaseClassName() { return NULL; } + +#else + +#define DECLARE_CLASS_SIMPLE( className, baseClassName ) \ + typedef baseClassName BaseClass; \ + typedef className ThisClass; \ +public: \ + DECLARE_PANELMESSAGEMAP( className ); \ + DECLARE_PANELANIMATION( className ); \ + static char const *GetPanelClassName() { return #className; } \ + static char const *GetPanelBaseClassName() { return #baseClassName; } + +#define DECLARE_CLASS_SIMPLE_NOBASE( className ) \ + typedef className ThisClass; \ +public: \ + DECLARE_PANELMESSAGEMAP( className ); \ + DECLARE_PANELANIMATION( className ); \ + static char const *GetPanelClassName() { return #className; } \ + static char const *GetPanelBaseClassName() { return NULL; } + +#endif + +#define _MessageFuncCommon( name, scriptname, paramCount, p1type, p1name, p2type, p2name ) \ + class PanelMessageFunc_##name; \ + friend class PanelMessageFunc_##name; \ + class PanelMessageFunc_##name \ + { \ + public: \ + static void InitVar() \ + { \ + static bool bAdded = false; \ + if ( !bAdded ) \ + { \ + bAdded = true; \ + AddToMap( scriptname, (vgui::MessageFunc_t)&ThisClass::name, paramCount, p1type, p1name, p2type, p2name ); \ + } \ + } \ + PanelMessageFunc_##name() \ + { \ + PanelMessageFunc_##name::InitVar(); \ + } \ + }; \ + PanelMessageFunc_##name m_##name##_register; \ + +#define MESSAGE_FUNC( name, scriptname ) _MessageFuncCommon( name, scriptname, 0, 0, 0, 0, 0 ); virtual void name( void ) + +#define MESSAGE_FUNC_INT( name, scriptname, p1 ) _MessageFuncCommon( name, scriptname, 1, vgui::DATATYPE_INT, #p1, 0, 0 ); virtual void name( int p1 ) +#define MESSAGE_FUNC_UINT64( name, scriptname, p1 ) _MessageFuncCommon( name, scriptname, 1, vgui::DATATYPE_UINT64, #p1, 0, 0 ); virtual void name( uint64 p1 ) +#define MESSAGE_FUNC_PTR( name, scriptname, p1 ) _MessageFuncCommon( name, scriptname, 1, vgui::DATATYPE_PTR, #p1, 0, 0 ); virtual void name( vgui::Panel *p1 ) +#define MESSAGE_FUNC_HANDLE( name, scriptname, p1 ) _MessageFuncCommon( name, scriptname, 1, vgui::DATATYPE_HANDLE, #p1, 0, 0 ); virtual void name( vgui::VPANEL p1 ) +#define MESSAGE_FUNC_FLOAT( name, scriptname, p1 ) _MessageFuncCommon( name, scriptname, 1, vgui::DATATYPE_FLOAT, #p1, 0, 0 ); virtual void name( float p1 ) +#define MESSAGE_FUNC_CHARPTR( name, scriptname, p1 ) _MessageFuncCommon( name, scriptname, 1, vgui::DATATYPE_CONSTCHARPTR, #p1, 0, 0 ); virtual void name( const char *p1 ) +#define MESSAGE_FUNC_WCHARPTR( name, scriptname, p1 ) _MessageFuncCommon( name, scriptname, 1, vgui::DATATYPE_CONSTWCHARPTR, #p1, 0, 0 ); virtual void name( const wchar_t *p1 ) + +#define MESSAGE_FUNC_INT_INT( name, scriptname, p1, p2 ) _MessageFuncCommon( name, scriptname, 2, vgui::DATATYPE_INT, #p1, vgui::DATATYPE_INT, #p2 ); virtual void name( int p1, int p2 ) +#define MESSAGE_FUNC_PTR_INT( name, scriptname, p1, p2 ) _MessageFuncCommon( name, scriptname, 2, vgui::DATATYPE_PTR, #p1, vgui::DATATYPE_INT, #p2 ); virtual void name( vgui::Panel *p1, int p2 ) +#define MESSAGE_FUNC_HANDLE_INT( name, scriptname, p1, p2 ) _MessageFuncCommon( name, scriptname, 2, vgui::DATATYPE_HANDLE, #p1, vgui::DATATYPE_INT, #p2 ); virtual void name( vgui::VPANEL p1, int p2 ) +#define MESSAGE_FUNC_ENUM_ENUM( name, scriptname, t1, p1, t2, p2 ) _MessageFuncCommon( name, scriptname, 2, vgui::DATATYPE_PTR, #p1, vgui::DATATYPE_PTR, #p2 ); virtual void name( t1 p1, t2 p2 ) +#define MESSAGE_FUNC_INT_CHARPTR( name, scriptname, p1, p2 ) _MessageFuncCommon( name, scriptname, 2, vgui::DATATYPE_INT, #p1, vgui::DATATYPE_CONSTCHARPTR, #p2 ); virtual void name( int p1, const char *p2 ) +#define MESSAGE_FUNC_PTR_CHARPTR( name, scriptname, p1, p2 ) _MessageFuncCommon( name, scriptname, 2, vgui::DATATYPE_PTR, #p1, vgui::DATATYPE_CONSTCHARPTR, #p2 ); virtual void name( vgui::Panel *p1, const char *p2 ) +#define MESSAGE_FUNC_HANDLE_CHARPTR( name, scriptname, p1, p2 ) _MessageFuncCommon( name, scriptname, 2, vgui::DATATYPE_HANDLE, #p1, vgui::DATATYPE_CONSTCHARPTR, #p2 ); virtual void name( vgui::VPANEL p1, const char *p2 ) +#define MESSAGE_FUNC_PTR_WCHARPTR( name, scriptname, p1, p2 ) _MessageFuncCommon( name, scriptname, 2, vgui::DATATYPE_PTR, #p1, vgui::DATATYPE_CONSTWCHARPTR, #p2 ); virtual void name( vgui::Panel *p1, const wchar_t *p2 ) +#define MESSAGE_FUNC_HANDLE_WCHARPTR( name, scriptname, p1, p2 ) _MessageFuncCommon( name, scriptname, 2, vgui::DATATYPE_HANDLE, #p1, vgui::DATATYPE_CONSTWCHARPTR, #p2 ); virtual void name( vgui::VPANEL p1, const wchar_t *p2 ) +#define MESSAGE_FUNC_CHARPTR_CHARPTR( name, scriptname, p1, p2 ) _MessageFuncCommon( name, scriptname, 2, vgui::DATATYPE_CONSTCHARPTR, #p1, vgui::DATATYPE_CONSTCHARPTR, #p2 ); virtual void name( const char *p1, const char *p2 ) + +#define MESSAGE_FUNC_PARAMS( name, scriptname, p1 ) _MessageFuncCommon( name, scriptname, 1, vgui::DATATYPE_KEYVALUES, NULL, 0, 0 ); virtual void name( KeyValues *p1 ) + +#define MESSAGE_FUNC_NV( name, scriptname ) _MessageFuncCommon( name, scriptname, 0, 0, 0, 0, 0 ); void name( void ) +#define MESSAGE_FUNC_NV_INT( name, scriptname, p1 ) _MessageFuncCommon( name, scriptname, 1, vgui::DATATYPE_INT, #p1, 0, 0 ); void name( int p1 ) +#define MESSAGE_FUNC_NV_INT_INT( name, scriptname, p1, p2 ) _MessageFuncCommon( name, scriptname, 2, vgui::DATATYPE_INT, #p1, vgui::DATATYPE_INT, #p2 ); void name( int p1, int p2 ) + + + struct PanelMessageMap + { + PanelMessageMap() + { + baseMap = NULL; + pfnClassName = NULL; + processed = false; + } + + CUtlVector< MessageMapItem_t > entries; + bool processed; + PanelMessageMap* baseMap; + char const* (*pfnClassName)(void); + }; + + PanelMessageMap* FindPanelMessageMap(char const* className); + PanelMessageMap* FindOrAddPanelMessageMap(char const* className); + + + +#define MAP_MESSAGE( type, name, func ) { name, (vgui::MessageFunc_t)(&type::func), 0 } + +#define MAP_MESSAGE_PARAMS( type, name, func ) { name, (vgui::MessageFunc_t)(&type::func), 1, vgui::DATATYPE_KEYVALUES, NULL } + +#define MAP_MESSAGE_PTR( type, name, func, param1 ) { name, (vgui::MessageFunc_t)(&type::func), 1, vgui::DATATYPE_PTR, param1 } +#define MAP_MESSAGE_INT( type, name, func, param1 ) { name, (vgui::MessageFunc_t)(&type::func), 1, vgui::DATATYPE_INT, param1 } +#define MAP_MESSAGE_BOOL( type, name, func, param1 ) { name, (vgui::MessageFunc_t)(&type::func), 1, vgui::DATATYPE_BOOL, param1 } +#define MAP_MESSAGE_FLOAT( type, name, func, param1 ) { name, (vgui::MessageFunc_t)(&type::func), 1, vgui::DATATYPE_FLOAT, param1 } +#define MAP_MESSAGE_PTR( type, name, func, param1 ) { name, (vgui::MessageFunc_t)(&type::func), 1, vgui::DATATYPE_PTR, param1 } +#define MAP_MESSAGE_CONSTCHARPTR( type, name, func, param1) { name, (vgui::MessageFunc_t)(&type::func), 1, vgui::DATATYPE_CONSTCHARPTR, param1 } +#define MAP_MESSAGE_CONSTWCHARPTR( type, name, func, param1) { name, (vgui::MessageFunc_t)(&type::func), 1, vgui::DATATYPE_CONSTWCHARPTR, param1 } + +#define MAP_MESSAGE_INT_INT( type, name, func, param1, param2 ) { name, (vgui::MessageFunc_t)&type::func, 2, vgui::DATATYPE_INT, param1, vgui::DATATYPE_INT, param2 } +#define MAP_MESSAGE_PTR_INT( type, name, func, param1, param2 ) { name, (vgui::MessageFunc_t)&type::func, 2, vgui::DATATYPE_PTR, param1, vgui::DATATYPE_INT, param2 } +#define MAP_MESSAGE_INT_CONSTCHARPTR( type, name, func, param1, param2 ) { name, (vgui::MessageFunc_t)&type::func, 2, vgui::DATATYPE_INT, param1, vgui::DATATYPE_CONSTCHARPTR, param2 } +#define MAP_MESSAGE_PTR_CONSTCHARPTR( type, name, func, param1, param2 ) { name, (vgui::MessageFunc_t)&type::func, 2, vgui::DATATYPE_PTR, param1, vgui::DATATYPE_CONSTCHARPTR, param2 } +#define MAP_MESSAGE_PTR_CONSTWCHARPTR( type, name, func, param1, param2 ) { name, (vgui::MessageFunc_t)&type::func, 2, vgui::DATATYPE_PTR, param1, vgui::DATATYPE_CONSTWCHARPTR, param2 } +#define MAP_MESSAGE_CONSTCHARPTR_CONSTCHARPTR( type, name, func, param1, param2 ) { name, (vgui::MessageFunc_t)&type::func, 2, vgui::DATATYPE_CONSTCHARPTR, param1, vgui::DATATYPE_CONSTCHARPTR, param2 } + + + struct PanelMap_t + { + MessageMapItem_t* dataDesc; + int dataNumFields; + const char* dataClassName; + PanelMap_t* baseMap; + int processed; + }; + +#define DECLARE_PANELMAP() \ + static vgui::PanelMap_t m_PanelMap; \ + static vgui::MessageMapItem_t m_MessageMap[]; \ + virtual vgui::PanelMap_t *GetPanelMap( void ); + +#define IMPLEMENT_PANELMAP( derivedClass, baseClass ) \ + vgui::PanelMap_t derivedClass::m_PanelMap = { derivedClass::m_MessageMap, ARRAYSIZE(derivedClass::m_MessageMap), #derivedClass, &baseClass::m_PanelMap }; \ + vgui::PanelMap_t *derivedClass::GetPanelMap( void ) { return &m_PanelMap; } + + typedef vgui::Panel* (*PANELCREATEFUNC)(void); + + class CBuildFactoryHelper + { + public: + static CBuildFactoryHelper* m_sHelpers; + + public: + CBuildFactoryHelper(char const* className, PANELCREATEFUNC func); + + CBuildFactoryHelper* GetNext(void); + + char const* GetClassName() const; + + vgui::Panel* CreatePanel(); + + static vgui::Panel* InstancePanel(char const* className); + static void GetFactoryNames(CUtlVector< char const* >& list); + + static CDmxElement* CreatePanelDmxElement(vgui::Panel* pPanel); + static Panel* UnserializeDmxElementPanel(CDmxElement* pElement); + + static bool Serialize(CUtlBuffer& buf, vgui::Panel* pPanel); + static bool Unserialize(Panel** ppPanel, CUtlBuffer& buf, const char* pFileName = NULL); + + + private: + + static bool HasFactory(char const* className); + + CBuildFactoryHelper* m_pNext; + + int m_Type; + PANELCREATEFUNC m_CreateFunc; + char const* m_pClassName; + }; + +#define DECLARE_BUILD_FACTORY( className ) \ + static vgui::Panel *Create_##className( void ) \ + { \ + return new className( NULL, NULL ); \ + }; \ + static vgui::CBuildFactoryHelper g_##className##_Helper( #className, Create_##className );\ + className *g_##className##LinkerHack = NULL; + +#define DECLARE_BUILD_FACTORY_DEFAULT_TEXT( className, defaultText ) \ + static vgui::Panel *Create_##className( void ) \ + { \ + return new className( NULL, NULL, #defaultText ); \ + }; \ + static vgui::CBuildFactoryHelper g_##className##_Helper( #className, Create_##className );\ + className *g_##className##LinkerHack = NULL; + +#define DECLARE_BUILD_FACTORY_CUSTOM( className, createFunc ) \ + static vgui::CBuildFactoryHelper g_##className##_Helper( #className, createFunc );\ + className *g_##className##LinkerHack = NULL; + +#define DECLARE_BUILD_FACTORY_CUSTOM_ALIAS( className, factoryName, createFunc ) \ + static vgui::CBuildFactoryHelper g_##factoryName##_Helper( #factoryName, createFunc );\ + className *g_##factoryName##LinkerHack = NULL; + +} + + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/MouseCode.h b/SpyCustom/sdk/MouseCode.h new file mode 100644 index 0000000..feb02ac --- /dev/null +++ b/SpyCustom/sdk/MouseCode.h @@ -0,0 +1,15 @@ +#ifndef MOUSECODE_H +#define MOUSECODE_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "ButtonCode.h" + +namespace vgui +{ + typedef ButtonCode_t MouseCode; +} + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/PHandle.h b/SpyCustom/sdk/PHandle.h new file mode 100644 index 0000000..ff606db --- /dev/null +++ b/SpyCustom/sdk/PHandle.h @@ -0,0 +1,70 @@ +#ifndef PHANDLE_H +#define PHANDLE_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "VGUI.h" + +namespace vgui +{ + + class Panel; + + class PHandle + { + public: + PHandle() : m_iPanelID(INVALID_PANEL) {} + + Panel* Get(); + Panel* Set(Panel* pPanel); + Panel* Set(HPanel hPanel); + + operator Panel* () { return Get(); } + Panel* operator ->() { return Get(); } + Panel* operator = (Panel* pPanel) { return Set(pPanel); } + + bool operator == (Panel* pPanel) { return (Get() == pPanel); } + operator bool() { return Get() != 0; } + + private: + HPanel m_iPanelID; + }; + + class VPanelHandle + { + public: + VPanelHandle() : m_iPanelID(INVALID_PANEL) {} + + VPANEL Get(); + VPANEL Set(VPANEL pPanel); + + operator VPANEL () { return Get(); } + VPANEL operator = (VPANEL pPanel) { return Set(pPanel); } + + bool operator == (VPANEL pPanel) { return (Get() == pPanel); } + operator bool() { return Get() != 0; } + + private: + HPanel m_iPanelID; + }; + + template< class PanelType > + class DHANDLE : public PHandle + { + public: + PanelType* Get() { return (PanelType*)PHandle::Get(); } + PanelType* Set(PanelType* pPanel) { return (PanelType*)PHandle::Set(pPanel); } + PanelType* Set(HPanel hPanel) { return (PanelType*)PHandle::Set(hPanel); } + + operator PanelType* () { return (PanelType*)PHandle::Get(); } + PanelType* operator ->() { return (PanelType*)PHandle::Get(); } + PanelType* operator = (PanelType* pPanel) { return (PanelType*)PHandle::Set(pPanel); } + bool operator == (Panel* pPanel) { return (PHandle::Get() == pPanel); } + operator bool() { return PHandle::Get() != NULL; } + }; + +}; + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/Panel.h b/SpyCustom/sdk/Panel.h new file mode 100644 index 0000000..6d48b3a --- /dev/null +++ b/SpyCustom/sdk/Panel.h @@ -0,0 +1,962 @@ +#ifndef PANEL_H +#define PANEL_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "utlflags.h" +#include "vgui.h" +#include "Dar.h" +#include "MessageMap.h" +#if defined( VGUI_USEKEYBINDINGMAPS ) +#include "KeyBindingMap.h" +#endif +#include "IClientPanel.h" +#include "IScheme.h" +#include "Controls.h" +#include "PHandle.h" +#include "PanelAnimationVar.h" +#include "color.h" +#include "keyvalues.h" +#include "ikeyvaluessystem.h" +#include "utlsymbol.h" +#include "BuildGroup.h" +#include "dmxelement.h" + +#ifdef PostMessage +#undef PostMessage +#endif + +#ifdef SetCursor +#undef SetCursor +#endif + + +class CUtlBuffer; +struct DmxElementUnpackStructure_t; + +namespace vgui +{ + +#if !defined( _GAMECONSOLE ) +#define VGUI_USEDRAGDROP 1 +#endif + +#if defined( VGUI_USEKEYBINDINGMAPS ) + struct PanelKeyBindingMap; +#endif + template< class T > + inline T* SETUP_PANEL(T* panel) + { + panel->MakeReadyForUse(); + return panel; + } + +#define CREATE_PANEL(type, parent, name) (SETUP_PANEL(new type(parent, name))) + +#if defined( VGUI_USEDRAGDROP ) + struct DragDrop_t; + class Menu; +#endif + + + + class Panel; + + struct SizerAddArgs_t + { + SizerAddArgs_t() + { + m_flExpandFactor = 0.0f; + m_nPadding = 5; + m_bMinorExpand = true; + m_nMinX = -1; + m_nMinY = -1; + m_bIgnoreMemberMin = false; + } + + SizerAddArgs_t& Expand(float flExpandFactor) { m_flExpandFactor = flExpandFactor; return *this; } + SizerAddArgs_t& Padding(int nPadding) { m_nPadding = nPadding; return *this; } + SizerAddArgs_t& MinorExpand(bool bMinorExpand) { m_bMinorExpand = bMinorExpand; return *this; } + SizerAddArgs_t& MinSize(int nMinX, int nMinY) { m_nMinX = nMinX; m_nMinY = nMinY; return *this; } + SizerAddArgs_t& MinX(int nMinX) { m_nMinX = nMinX; return *this; } + SizerAddArgs_t& MinY(int nMinY) { m_nMinY = nMinY; return *this; } + + SizerAddArgs_t& IgnoreMemberMin(bool bIgnoreMemberMin = true) { m_bIgnoreMemberMin = bIgnoreMemberMin; return *this; } + + SizerAddArgs_t& FixedSize(int nX, int nY) + { + IgnoreMemberMin(true); + MinSize(nX, nY); + Expand(0.f); + MinorExpand(false); + return *this; + } + + float m_flExpandFactor; + int m_nPadding; + bool m_bMinorExpand; + int m_nMinX; + int m_nMinY; + bool m_bIgnoreMemberMin; + }; + + + enum SizerLayoutDirection_t + { + ESLD_HORIZONTAL, + ESLD_VERTICAL + }; + + enum SizerElementType_t + { + ESET_SIZER, + ESET_PANEL, + ESET_SPACER, + }; + + class CSizerBase + { + public: + CSizerBase(); + virtual ~CSizerBase(); + + int GetElementCount() { return m_Members.Count(); } + SizerElementType_t GetElementType(int i); + Panel* GetPanel(int i); + + void SetElementArgs(int nIndex, const SizerAddArgs_t& args) { m_Members[nIndex].Fill(args); } + + void InsertPanel(int nIndex, Panel* pPanel, const SizerAddArgs_t& args); + void InsertSizer(int nIndex, CSizerBase* pSizer, const SizerAddArgs_t& args); + void InsertSpacer(int nIndex, const SizerAddArgs_t& args); + + void AddPanel(Panel* pPanel, const SizerAddArgs_t& args) { InsertPanel(GetElementCount(), pPanel, args); } + void AddSizer(CSizerBase* pSizer, const SizerAddArgs_t& args) { InsertSizer(GetElementCount(), pSizer, args); } + void AddSpacer(const SizerAddArgs_t& args) { InsertSpacer(GetElementCount(), args); } + + void RemoveElement(int i, bool bDelete); + void RemoveAllMembers(bool bDelete); + + void GetMinSize(int& OutX, int& OutY); + + void RecursiveInvalidateCachedSize(); + + virtual void DoLayout(int BaseX, int BaseY, int SizeX, int SizeY) = 0; + virtual void CalculateSize() = 0; + + protected: + class CSizerMember + { + friend class CSizerBase; + + public: + SizerElementType_t GetElementType() const; + Panel* GetPanel() const; + + void GetMemberMinSize(int& OutX, int& OutY); + void RecursiveInvalidateCachedSize(); + void Place(int BaseX, int BaseY, int SizeX, int SizeY); + + float GetExpandFactor() { return m_flExpandFactor; } + bool GetMinorExpand() { return m_bMinorExpand; } + + void DiscardOwnedSizer(); + + bool IsVisible(); + + void Fill(const SizerAddArgs_t& args); + + private: + void RecursiveRemove(bool bDelete); + + Panel* m_pPanel; + CSizerBase* m_pSizer; + + int m_nPadding; + float m_flExpandFactor; + bool m_bMinorExpand; + bool m_bIgnoreMemberMin; + int m_nMinX; + int m_nMinY; + }; + + CUtlVector m_Members; + int m_nMinXSize; + int m_nMinYSize; + }; + + inline int SizerMajorAxis(SizerLayoutDirection_t Dir, int X, int Y) { return (Dir == ESLD_HORIZONTAL) ? X : Y; } + inline int SizerMinorAxis(SizerLayoutDirection_t Dir, int X, int Y) { return (Dir == ESLD_VERTICAL) ? X : Y; } + inline int SizerXAxis(SizerLayoutDirection_t Dir, int MajorAxis, int MinorAxis) { return (Dir == ESLD_HORIZONTAL) ? MajorAxis : MinorAxis; } + inline int SizerYAxis(SizerLayoutDirection_t Dir, int MajorAxis, int MinorAxis) { return (Dir == ESLD_VERTICAL) ? MajorAxis : MinorAxis; } + + class CBoxSizer : public CSizerBase + { + public: + CBoxSizer(SizerLayoutDirection_t LayoutDirection); + + virtual void CalculateSize(); + virtual void DoLayout(int BaseX, int BaseY, int SizeX, int SizeY); + + protected: + SizerLayoutDirection_t m_LayoutDirection; + }; + + + struct OverridableColorEntry + { + char const* name() { return m_pszScriptName; } + + char const* m_pszScriptName; + Color* m_pColor; + Color m_colFromScript; + UtlSymId_t m_sColorNameFromScript; + bool m_bOverridden; + }; + +#define REGISTER_COLOR_AS_OVERRIDABLE( name, scriptname ) \ + AddToOverridableColors( &name, scriptname ); + + +#define DECLARE_VGUI_UNPACK() \ + DECLARE_DMXELEMENT_UNPACK() \ + private: \ + static DmxElementUnpackStructure_t *s_pUnpackParams; \ + public: \ + virtual const DmxElementUnpackStructure_t* GetUnpackStructure() const { return s_pUnpackParams; } + +#define DECLARE_VGUI_UNPACK_NAMESPACE( _namespace ) \ + template friend DmxElementUnpackStructure_t *DmxElementUnpackInit##_namespace(T *); \ + private: \ + static DmxElementUnpackStructure_t *s_pUnpackParams; \ + public: \ + virtual const DmxElementUnpackStructure_t* GetUnpackStructure() const { return s_pUnpackParams; } + +#define BEGIN_VGUI_UNPACK( _structName ) BEGIN_DMXELEMENT_UNPACK( _structName ) +#define END_VGUI_UNPACK( _structName ) \ + END_DMXELEMENT_UNPACK( _structName, s_pUnpackParams ) \ + DmxElementUnpackStructure_t *_structName::s_pUnpackParams = _structName##_UnpackInit::s_pUnpack; + +#define BEGIN_VGUI_UNPACK_NAMESPACE( _nameSpace, _structName ) BEGIN_DMXELEMENT_UNPACK_NAMESPACE( _nameSpace, _structName ) +#define END_VGUI_UNPACK_NAMESPACE( _nameSpace, _structName ) \ + END_DMXELEMENT_UNPACK_NAMESPACE( _nameSpace, _structName, s_pUnpackParams ) \ + DmxElementUnpackStructure_t *_structName::s_pUnpackParams = _namespace##_structName##_UnpackInit::s_pUnpack; + + + class IPanelAnimationPropertyConverter + { + public: + virtual void GetData(Panel* panel, KeyValues* kv, PanelAnimationMapEntry* entry) = 0; + virtual void SetData(Panel* panel, KeyValues* kv, PanelAnimationMapEntry* entry) = 0; + virtual void InitFromDefault(Panel* panel, PanelAnimationMapEntry* entry) = 0; + }; + +#if defined( VGUI_USEKEYBINDINGMAPS ) + enum KeyBindingContextHandle_t + { + INVALID_KEYBINDINGCONTEXT_HANDLE = 0xffffffff, + }; +#endif + +#define PANEL_ROUND_CORNER_TOP_LEFT (1 << 0) +#define PANEL_ROUND_CORNER_TOP_RIGHT (1 << 1) +#define PANEL_ROUND_CORNER_BOTTOM_LEFT (1 << 2) +#define PANEL_ROUND_CORNER_BOTTOM_RIGHT (1 << 3) +#define PANEL_ROUND_CORNER_ALL PANEL_ROUND_CORNER_TOP_LEFT | PANEL_ROUND_CORNER_TOP_RIGHT | PANEL_ROUND_CORNER_BOTTOM_LEFT | PANEL_ROUND_CORNER_BOTTOM_RIGHT + class Panel : public IClientPanel + { + DECLARE_CLASS_SIMPLE_NOBASE(Panel); + DECLARE_DMXELEMENT_UNPACK_NAMESPACE(vgui); + + public: + static void InitPropertyConverters(void); + static void AddPropertyConverter(char const* typeName, IPanelAnimationPropertyConverter* converter); + + Panel(); + Panel(Panel* parent); + Panel(Panel* parent, const char* panelName); + Panel(Panel* parent, const char* panelName, HScheme scheme); + + virtual ~Panel(); + + virtual VPANEL GetVPanel() { return _vpanel; } + HPanel ToHandle() const; + + + void SetName(const char* panelName); + const char* GetName(); + const char* GetClassName(); + + void MakeReadyForUse(); + + void SetPos(int x, int y); + void GetPos(int& x, int& y); + void SetSize(int wide, int tall); + void GetSize(int& wide, int& tall); + void SetBounds(int x, int y, int wide, int tall); + void GetBounds(int& x, int& y, int& wide, int& tall); + int GetWide(); + void SetWide(int wide); + int GetTall(); + void SetTall(int tall); + void SetMinimumSize(int wide, int tall); + void GetMinimumSize(int& wide, int& tall); + bool IsBuildModeEditable(); + void SetBuildModeEditable(bool state); + bool IsBuildModeDeletable(); + void SetBuildModeDeletable(bool state); + bool IsBuildModeActive(); + void SetZPos(int z); + int GetZPos(void); + void SetAlpha(int alpha); + int GetAlpha(); + + virtual void SetVisible(bool state); + virtual bool IsVisible(); + virtual bool IsFullyVisible(); + + virtual VPANEL IsWithinTraverse(int x, int y, bool traversePopups); + MESSAGE_FUNC(Repaint, "Repaint"); + virtual void PostMessage(VPANEL target, KeyValues* message, float delaySeconds = 0.0f); + + bool IsWithin(int x, int y); + void LocalToScreen(int& x, int& y); + void ScreenToLocal(int& x, int& y); + void ParentLocalToScreen(int& x, int& y); + void MakePopup(bool showTaskbarIcon = true, bool disabled = false); + virtual void OnMove(); + + virtual Panel* GetParent(); + virtual VPANEL GetVParent(); + virtual void SetParent(Panel* newParent); + virtual void SetParent(VPANEL newParent); + virtual bool HasParent(VPANEL potentialParent); + + int GetChildCount(); + Panel* GetChild(int index); + int FindChildIndexByName(const char* childName); + Panel* FindChildByName(const char* childName, bool recurseDown = false); + Panel* FindSiblingByName(const char* siblingName); + void CallParentFunction(KeyValues* message); + + virtual bool LookupElementBounds(const char* elementName, int& x, int& y, int& wide, int& tall) { return false; } + + virtual void SetAutoDelete(bool state); + virtual bool IsAutoDeleteSet(); + virtual void DeletePanel(); + + virtual void AddActionSignalTarget(Panel* messageTarget); + virtual void AddActionSignalTarget(VPANEL messageTarget); + virtual void RemoveActionSignalTarget(Panel* oldTarget); + virtual void PostActionSignal(KeyValues* message); + virtual bool RequestInfoFromChild(const char* childName, KeyValues* outputData); + virtual void PostMessageToChild(const char* childName, KeyValues* messsage); + virtual void PostMessage(Panel* target, KeyValues* message, float delaySeconds = 0.0f); + virtual bool RequestInfo(KeyValues* outputData); + virtual bool SetInfo(KeyValues* inputData); + virtual void SetSilentMode(bool bSilent); + + virtual void InstallMouseHandler(Panel* pHandler); + + virtual void SetEnabled(bool state); + virtual bool IsEnabled(); + virtual bool IsPopup(); + virtual void GetClipRect(int& x0, int& y0, int& x1, int& y1); + virtual void MoveToFront(); + + enum PinCorner_e + { + PIN_TOPLEFT = 0, + PIN_TOPRIGHT, + PIN_BOTTOMLEFT, + PIN_BOTTOMRIGHT, + PIN_NO, + + PIN_CENTER_TOP, + PIN_CENTER_RIGHT, + PIN_CENTER_BOTTOM, + PIN_CENTER_LEFT, + }; + + enum AutoResize_e + { + AUTORESIZE_NO = 0, + AUTORESIZE_RIGHT, + AUTORESIZE_DOWN, + AUTORESIZE_DOWNANDRIGHT, + }; + + void SetPinCorner(PinCorner_e pinCorner, int nOffsetX, int nOffsetY); + + void SetAutoResize(PinCorner_e pinCorner, AutoResize_e resizeDir, int nPinOffsetX, int nPinOffsetY, int nUnpinnedCornerOffsetX, int nUnpinnedCornerOffsetY); + + AutoResize_e GetAutoResize(); + PinCorner_e GetPinCorner(); + + void GetPinOffset(int& dx, int& dy); + void GetResizeOffset(int& dx, int& dy); + + void PinToSibling(const char* pszSibling, PinCorner_e pinOurCorner, PinCorner_e pinSibling); + void UpdateSiblingPin(void); + + virtual void SetBgColor(Color color); + virtual void SetFgColor(Color color); + virtual Color GetBgColor(); + virtual Color GetFgColor(); + + virtual void SetCursor(HCursor cursor); + virtual HCursor GetCursor(); + virtual void RequestFocus(int direction = 0); + virtual bool HasFocus(); + virtual void InvalidateLayout(bool layoutNow = false, bool reloadScheme = false); + virtual bool RequestFocusPrev(VPANEL panel = NULL); + virtual bool RequestFocusNext(VPANEL panel = NULL); + virtual void SetTabPosition(int position); + virtual int GetTabPosition(); + virtual void SetBorder(IBorder* border); + virtual IBorder* GetBorder(); + virtual void SetPaintBorderEnabled(bool state); + virtual void SetPaintBackgroundEnabled(bool state); + virtual void SetPaintEnabled(bool state); + virtual void SetPostChildPaintEnabled(bool state); + virtual void SetPaintBackgroundType(int type); + virtual void GetInset(int& left, int& top, int& right, int& bottom); + virtual void GetPaintSize(int& wide, int& tall); + virtual void SetBuildGroup(BuildGroup* buildGroup); + virtual bool IsBuildGroupEnabled(); + virtual bool IsCursorNone(); + virtual bool IsCursorOver(); + virtual void MarkForDeletion(); + virtual bool IsLayoutInvalid(); + virtual Panel* HasHotkey(wchar_t key); + virtual bool IsOpaque(); + bool IsRightAligned(); + bool IsBottomAligned(); + bool IsPercentage(); + + virtual HScheme GetScheme(); + virtual void SetScheme(const char* tag); + virtual void SetScheme(HScheme scheme); + virtual Color GetSchemeColor(const char* keyName, IScheme* pScheme); + virtual Color GetSchemeColor(const char* keyName, Color defaultColor, IScheme* pScheme); + + virtual void ApplySchemeSettings(IScheme* pScheme); + + virtual void ApplySettings(KeyValues* inResourceData); + virtual void OnUnserialized(CDmxElement* pElement); + + virtual void GetSettings(KeyValues* outResourceData); + + virtual const char* GetDescription(); + + virtual const char* GetModuleName(); + + virtual void ApplyUserConfigSettings(KeyValues* userConfig); + + virtual void GetUserConfigSettings(KeyValues* userConfig); + + virtual bool HasUserConfigSettings(); + + virtual void OnMessage(const KeyValues* params, VPANEL fromPanel); + MESSAGE_FUNC_CHARPTR(OnCommand, "Command", command); + MESSAGE_FUNC(OnMouseCaptureLost, "MouseCaptureLost"); + MESSAGE_FUNC(OnSetFocus, "SetFocus"); + MESSAGE_FUNC(OnKillFocus, "KillFocus"); + MESSAGE_FUNC(OnDelete, "Delete"); + virtual void OnThink(); + virtual void OnChildAdded(VPANEL child); + virtual void OnSizeChanged(int newWide, int newTall); + + virtual void OnTick(); + + MESSAGE_FUNC_INT_INT(OnCursorMoved, "OnCursorMoved", x, y); + virtual void OnCursorEntered(); + virtual void OnCursorExited(); + virtual void OnMousePressed(MouseCode code); + virtual void OnMouseDoublePressed(MouseCode code); + virtual void OnMouseReleased(MouseCode code); + virtual void OnMouseWheeled(int delta); + + virtual void SetTriplePressAllowed(bool state); + virtual bool IsTriplePressAllowed() const; + virtual void OnMouseTriplePressed(MouseCode code); + + static char const* KeyCodeToString(KeyCode code); + static wchar_t const* KeyCodeToDisplayString(KeyCode code); + static wchar_t const* KeyCodeModifiersToDisplayString(KeyCode code, int modifiers); + + static KeyCode StringToKeyCode(char const* str); +#if defined( VGUI_USEKEYBINDINGMAPS ) + static KeyBindingContextHandle_t CreateKeyBindingsContext(char const* filename, char const* pathID = 0); + virtual void SetKeyBindingsContext(KeyBindingContextHandle_t handle); + virtual KeyBindingContextHandle_t GetKeyBindingsContext() const; + virtual bool IsValidKeyBindingsContext() const; + + static int GetPanelsWithKeyBindingsCount(KeyBindingContextHandle_t handle); + static Panel* GetPanelWithKeyBindings(KeyBindingContextHandle_t handle, int index); + + static void RevertKeyBindings(KeyBindingContextHandle_t handle); + + static void ReloadKeyBindings(KeyBindingContextHandle_t handle); + static void SaveKeyBindings(KeyBindingContextHandle_t handle); + static void SaveKeyBindingsToFile(KeyBindingContextHandle_t handle, char const* filename, char const* pathID = 0); + static void LoadKeyBindings(KeyBindingContextHandle_t handle); + static void LoadKeyBindingsForOnePanel(KeyBindingContextHandle_t handle, Panel* panelOfInterest); + + virtual bool IsKeyRebound(KeyCode code, int modifiers); + virtual bool IsKeyOverridden(KeyCode code, int modifiers); + + virtual void AddKeyBinding(char const* bindingName, int keycode, int modifiers); + + KeyBindingMap_t* LookupBinding(char const* bindingName); + KeyBindingMap_t* LookupBindingByKeyCode(KeyCode code, int modifiers); + void LookupBoundKeys(char const* bindingName, CUtlVector< BoundKey_t* >& list); + BoundKey_t* LookupDefaultKey(char const* bindingName); + PanelKeyBindingMap* LookupMapForBinding(char const* bindingName); + + int GetKeyMappingCount(); + + void RevertKeyBindingsToDefault(); + void RemoveAllKeyBindings(); + void ReloadKeyBindings(); + virtual void EditKeyBindings(); + + void SaveKeyBindingsToBuffer(int level, CUtlBuffer& buf); + bool ParseKeyBindings(KeyValues* kv); + + virtual char const* GetKeyBindingsFile() const; + virtual char const* GetKeyBindingsFilePathID() const; + + void SetAllowKeyBindingChainToParent(bool state); + bool IsKeyBindingChainToParentAllowed() const; +#endif + + virtual void OnKeyCodePressed(KeyCode code); + virtual void OnKeyCodeTyped(KeyCode code); + virtual void OnKeyTyped(wchar_t unichar); + virtual void OnKeyCodeReleased(KeyCode code); + virtual void OnKeyFocusTicked(); + + MESSAGE_FUNC(OnMouseFocusTicked, "OnMouseFocusTicked"); + + virtual void PaintBackground(); + virtual void Paint(); + virtual void PaintBorder(); + virtual void PaintBuildOverlay(); + virtual void PostChildPaint(); + virtual void PerformLayout(); + + DECLARE_PANELMAP(); + + virtual VPANEL GetCurrentKeyFocus(); + + BaseTooltip* GetTooltip(); + void SetTooltip(BaseTooltip* pToolTip, const char* pszText); + + virtual bool IsProportional() { return _flags.IsFlagSet(IS_PROPORTIONAL); } + virtual void SetProportional(bool state); + + virtual void SetMouseInputEnabled(bool state); + virtual void SetKeyBoardInputEnabled(bool state); + virtual bool IsMouseInputEnabled(); + virtual bool IsKeyBoardInputEnabled(); + + void DisableMouseInputForThisPanel(bool bDisable); + bool IsMouseInputDisabledForThisPanel() const; + + virtual void DrawTexturedBox(int x, int y, int wide, int tall, Color color, float normalizedAlpha); + virtual void DrawBox(int x, int y, int wide, int tall, Color color, float normalizedAlpha, bool hollow = false); + virtual void DrawBoxFade(int x, int y, int wide, int tall, Color color, float normalizedAlpha, unsigned int alpha0, unsigned int alpha1, bool bHorizontal, bool hollow = false); + virtual void DrawHollowBox(int x, int y, int wide, int tall, Color color, float normalizedAlpha); + virtual void DrawHollowBox(int x, int y, int wide, int tall, Color color, float normalizedAlpha, int cornerWide, int cornerTall); + + unsigned char GetRoundedCorners() { return m_roundedCorners; } + void SetRoundedCorners(unsigned char cornerFlags) { m_roundedCorners = cornerFlags; } + bool ShouldDrawTopLeftCornerRounded() { return 0 != (m_roundedCorners & PANEL_ROUND_CORNER_TOP_LEFT); } + bool ShouldDrawTopRightCornerRounded() { return 0 != (m_roundedCorners & PANEL_ROUND_CORNER_TOP_RIGHT); } + bool ShouldDrawBottomLeftCornerRounded() { return 0 != (m_roundedCorners & PANEL_ROUND_CORNER_BOTTOM_LEFT); } + bool ShouldDrawBottomRightCornerRounded() { return 0 != (m_roundedCorners & PANEL_ROUND_CORNER_BOTTOM_RIGHT); } + + virtual void SetDragEnabled(bool enabled); + virtual bool IsDragEnabled() const; + + virtual void SetShowDragHelper(bool enabled); + + virtual void OnDragFailed(CUtlVector< KeyValues* >& msglist); + + virtual void SetBlockDragChaining(bool block); + virtual bool IsBlockingDragChaining() const; + + virtual int GetDragStartTolerance() const; + virtual void SetDragSTartTolerance(int nTolerance); + + virtual void SetDropEnabled(bool enabled, float m_flHoverContextTime = 0.0f); + virtual bool IsDropEnabled() const; + + virtual bool GetDropContextMenu(Menu* menu, CUtlVector< KeyValues* >& msglist); + virtual void OnDropContextHoverShow(CUtlVector< KeyValues* >& msglist); + virtual void OnDropContextHoverHide(CUtlVector< KeyValues* >& msglist); + +#if defined( VGUI_USEDRAGDROP ) + virtual DragDrop_t* GetDragDropInfo(); +#endif + virtual void OnGetAdditionalDragPanels(CUtlVector< Panel* >& dragabbles); + + virtual void OnCreateDragData(KeyValues* msg); + virtual bool IsDroppable(CUtlVector< KeyValues* >& msglist); + + virtual void OnDraggablePanelPaint(); + virtual void OnDroppablePanelPaint(CUtlVector< KeyValues* >& msglist, CUtlVector< Panel* >& dragPanels); + + virtual void OnPanelDropped(CUtlVector< KeyValues* >& msglist); + + virtual void OnPanelEnteredDroppablePanel(CUtlVector< KeyValues* >& msglist); + virtual void OnPanelExitedDroppablePanel(CUtlVector< KeyValues* >& msglist); + + virtual Panel* GetDropTarget(CUtlVector< KeyValues* >& msglist); + virtual Panel* GetDragPanel(); + virtual bool IsBeingDragged(); + virtual HCursor GetDropCursor(CUtlVector< KeyValues* >& msglist); + virtual HCursor GetDragFailCursor(CUtlVector< KeyValues* >& msglist) { return dc_no; } + + Color GetDropFrameColor(); + Color GetDragFrameColor(); + + virtual bool CanStartDragging(int startx, int starty, int mx, int my); + + virtual void FillRectSkippingPanel(const Color clr, int x, int y, int w, int h, Panel* skipPanel); + + virtual int GetPaintBackgroundType(); + virtual void GetCornerTextureSize(int& w, int& h); + + bool IsChildOfModalSubTree(); + bool IsChildOfSurfaceModalPanel(); + + bool ShouldHandleInputMessage(); + + virtual void SetSkipChildDuringPainting(Panel* child); + + void SetStartDragWhenMouseExitsPanel(bool state); + bool IsStartDragWhenMouseExitsPanel() const; + + void SetMessageContextId_R(int nContextID); + + void PostMessageToAllSiblings(KeyValues* msg, float delaySeconds = 0.0f); + template< class S > + void PostMessageToAllSiblingsOfType(KeyValues* msg, float delaySeconds = 0.0f); + + void SetConsoleStylePanel(bool bConsoleStyle); + bool IsConsoleStylePanel() const; + + enum NAV_DIRECTION { ND_UP, ND_DOWN, ND_LEFT, ND_RIGHT, ND_BACK, ND_NONE }; + virtual Panel* NavigateUp(); + virtual Panel* NavigateDown(); + virtual Panel* NavigateLeft(); + virtual Panel* NavigateRight(); + virtual void NavigateTo(); + virtual void NavigateFrom(); + virtual void NavigateToChild(Panel* pNavigateTo); + + Panel* SetNavUp(Panel* navUp); + Panel* SetNavDown(Panel* navDown); + Panel* SetNavLeft(Panel* navLeft); + Panel* SetNavRight(Panel* navRight); + NAV_DIRECTION GetLastNavDirection(); + MESSAGE_FUNC_CHARPTR(OnNavigateTo, "OnNavigateTo", panelName); + MESSAGE_FUNC_CHARPTR(OnNavigateFrom, "OnNavigateFrom", panelName); + + protected: + + virtual void OnStartDragging(); + virtual void OnContinueDragging(); + virtual void OnFinishDragging(bool mousereleased, MouseCode code, bool aborted = false); + + virtual void DragDropStartDragging(); + + virtual void GetDragData(CUtlVector< KeyValues* >& list); + virtual void CreateDragData(); + + virtual void PaintTraverse(bool Repaint, bool allowForce = true); + + protected: + MESSAGE_FUNC_ENUM_ENUM(OnRequestFocus, "OnRequestFocus", VPANEL, subFocus, VPANEL, defaultPanel); + MESSAGE_FUNC_INT_INT(OnScreenSizeChanged, "OnScreenSizeChanged", oldwide, oldtall); + virtual void* QueryInterface(EInterfaceID id); + + void AddToOverridableColors(Color* pColor, char const* scriptname) + { + int iIdx = m_OverridableColorEntries.AddToTail(); + m_OverridableColorEntries[iIdx].m_pszScriptName = scriptname; + m_OverridableColorEntries[iIdx].m_pColor = pColor; + m_OverridableColorEntries[iIdx].m_bOverridden = false; + } + + void ApplyOverridableColors(IScheme* pScheme); + void SetOverridableColor(Color* pColor, const Color& newColor); + + protected: + void SetNavUp(const char* controlName); + void SetNavDown(const char* controlName); + void SetNavLeft(const char* controlName); + void SetNavRight(const char* controlName); + + public: + Panel* GetNavUp(Panel* first = NULL); + Panel* GetNavDown(Panel* first = NULL); + Panel* GetNavLeft(Panel* first = NULL); + Panel* GetNavRight(Panel* first = NULL); + + inline void SetWorldPositionCurrentFrame(bool bWorldPositionCurrentFrame) { m_bWorldPositionCurrentFrame = bWorldPositionCurrentFrame; } + inline bool GetWorldPositionCurrentFrame() { return m_bWorldPositionCurrentFrame; } + + protected: + Panel* GetNavUpPanel(); + Panel* GetNavDownPanel(); + Panel* GetNavLeftPanel(); + Panel* GetNavRightPanel(); + + bool m_PassUnhandledInput; + NAV_DIRECTION m_LastNavDirection; + + void InternalInitDefaultValues(PanelAnimationMap* map); + + + private: + enum BuildModeFlags_t + { + BUILDMODE_EDITABLE = 0x01, + BUILDMODE_DELETABLE = 0x02, + BUILDMODE_SAVE_XPOS_RIGHTALIGNED = 0x04, + BUILDMODE_SAVE_XPOS_CENTERALIGNED = 0x08, + BUILDMODE_SAVE_YPOS_BOTTOMALIGNED = 0x10, + BUILDMODE_SAVE_YPOS_CENTERALIGNED = 0x20, + BUILDMODE_SAVE_WIDE_FULL = 0x40, + BUILDMODE_SAVE_TALL_FULL = 0x80, + BUILDMODE_SAVE_PROPORTIONAL_TO_PARENT = 0x100, + BUILDMODE_SAVE_PERCENTAGE = 0x200, + }; + + enum PanelFlags_t + { + MARKED_FOR_DELETION = 0x0001, + NEEDS_REPAINT = 0x0002, + PAINT_BORDER_ENABLED = 0x0004, + PAINT_BACKGROUND_ENABLED = 0x0008, + PAINT_ENABLED = 0x0010, + POST_CHILD_PAINT_ENABLED = 0x0020, + AUTODELETE_ENABLED = 0x0040, + NEEDS_LAYOUT = 0x0080, + NEEDS_SCHEME_UPDATE = 0x0100, + NEEDS_DEFAULT_SETTINGS_APPLIED = 0x0200, +#if defined( VGUI_USEKEYBINDINGMAPS ) + ALLOW_CHAIN_KEYBINDING_TO_PARENT = 0x0400, +#endif + IN_PERFORM_LAYOUT = 0x0800, + IS_PROPORTIONAL = 0x1000, + TRIPLE_PRESS_ALLOWED = 0x2000, + DRAG_REQUIRES_PANEL_EXIT = 0x4000, + IS_MOUSE_DISABLED_FOR_THIS_PANEL_ONLY = 0x8000, + ALL_FLAGS = 0xFFFF, + }; + + virtual Panel* GetPanel() { return this; } + + void Think(); + void PerformApplySchemeSettings(); + + void InternalPerformLayout(); + void InternalSetCursor(); + + MESSAGE_FUNC_INT_INT(InternalCursorMoved, "CursorMoved", xpos, ypos); + MESSAGE_FUNC(InternalCursorEntered, "CursorEntered"); + MESSAGE_FUNC(InternalCursorExited, "CursorExited"); + + MESSAGE_FUNC_INT(InternalMousePressed, "MousePressed", code); + MESSAGE_FUNC_INT(InternalMouseDoublePressed, "MouseDoublePressed", code); + MESSAGE_FUNC_INT(InternalMouseTriplePressed, "MouseTriplePressed", code); + MESSAGE_FUNC_INT(InternalMouseReleased, "MouseReleased", code); + MESSAGE_FUNC_INT(InternalMouseWheeled, "MouseWheeled", delta); + MESSAGE_FUNC_INT(InternalKeyCodePressed, "KeyCodePressed", code); + MESSAGE_FUNC_INT(InternalKeyCodeTyped, "KeyCodeTyped", code); + MESSAGE_FUNC_INT(InternalKeyTyped, "KeyTyped", unichar); + MESSAGE_FUNC_INT(InternalKeyCodeReleased, "KeyCodeReleased", code); + + MESSAGE_FUNC(InternalKeyFocusTicked, "KeyFocusTicked"); + MESSAGE_FUNC(InternalMouseFocusTicked, "MouseFocusTicked"); + + MESSAGE_FUNC(InternalInvalidateLayout, "Invalidate"); + + MESSAGE_FUNC(InternalMove, "Move"); + virtual void InternalFocusChanged(bool lost); + + void Init(int x, int y, int wide, int tall); + void PreparePanelMap(PanelMap_t* panelMap); + + bool InternalRequestInfo(PanelAnimationMap* map, KeyValues* outputData); + bool InternalSetInfo(PanelAnimationMap* map, KeyValues* inputData); + + PanelAnimationMapEntry* FindPanelAnimationEntry(char const* scriptname, PanelAnimationMap* map); + + void InternalApplySettings(PanelAnimationMap* map, KeyValues* inResourceData); + + void ApplyAutoResizeSettings(KeyValues* inResourceData); + + void FindDropTargetPanel_R(CUtlVector< VPANEL >& panelList, int x, int y, VPANEL check); + Panel* FindDropTargetPanel(); + + int GetProportionalScaledValue(int rootTall, int normalizedValue); + +#if defined( VGUI_USEDRAGDROP ) + DragDrop_t* m_pDragDrop; + Color m_clrDragFrame; + Color m_clrDropFrame; +#endif + + BaseTooltip* m_pTooltips; + bool m_bToolTipOverridden; + + PHandle m_SkipChild; + long m_lLastDoublePressTime; + HFont m_infoFont; + +#if defined( VGUI_USEKEYBINDINGMAPS ) + KeyBindingContextHandle_t m_hKeyBindingsContext; +#endif + + VPANEL _vpanel; + CUtlString _panelName; + IBorder* _border; + + CUtlFlags< unsigned short > _flags; + Dar _actionSignalTargetDar; + + CUtlVector m_OverridableColorEntries; + + Color _fgColor; + Color _bgColor; + + HBuildGroup _buildGroup; + + short m_nPinDeltaX; + short m_nPinDeltaY; + short m_nResizeDeltaX; + short m_nResizeDeltaY; + + HCursor _cursor; + unsigned short _buildModeFlags; + + byte _pinCorner : 4; + byte _autoResizeDirection : 4; + + GCC_DIAG_PUSH_OFF(overflow) + + DECLARE_DMXELEMENT_BITFIELD(_pinCorner, byte, Panel) + DECLARE_DMXELEMENT_BITFIELD(_autoResizeDirection, byte, Panel) + + GCC_DIAG_POP() + + unsigned char _tabPosition; + HScheme m_iScheme; + + bool m_bIsDMXSerialized : 1; + bool m_bUseSchemeColors : 1; + bool m_bIsSilent : 1; + bool m_bIsConsoleStylePanel : 1; + + DECLARE_DMXELEMENT_BITFIELD(m_bUseSchemeColors, bool, Panel) + DECLARE_DMXELEMENT_BITFIELD(m_bIsSilent, bool, Panel) + + char* _pinToSibling; + byte _pinToSiblingCorner; + byte _pinCornerToSibling; + PHandle m_pinSibling; + + char* _tooltipText; + + PHandle m_hMouseEventHandler; + + bool m_bWorldPositionCurrentFrame; + CUtlSymbol m_sBorderName; + + protected: + CUtlString m_sNavUpName; + PHandle m_NavUp; + + CUtlString m_sNavDownName; + PHandle m_NavDown; + + CUtlString m_sNavLeftName; + PHandle m_NavLeft; + + CUtlString m_sNavRightName; + PHandle m_NavRight; + protected: + static int s_NavLock; + + private: + + CPanelAnimationVar(float, m_flAlpha, "alpha", "255"); + + CPanelAnimationVar(int, m_nPaintBackgroundType, "PaintBackgroundType", "0"); + CPanelAnimationVarAliasType(int, m_nBgTextureId1, "Texture1", "vgui/hud/800corner1", "textureid"); + CPanelAnimationVarAliasType(int, m_nBgTextureId2, "Texture2", "vgui/hud/800corner2", "textureid"); + CPanelAnimationVarAliasType(int, m_nBgTextureId3, "Texture3", "vgui/hud/800corner3", "textureid"); + CPanelAnimationVarAliasType(int, m_nBgTextureId4, "Texture4", "vgui/hud/800corner4", "textureid"); + + unsigned char m_roundedCorners; + friend class BuildGroup; + friend class BuildModeDialog; + friend class PHandle; + + void OnOldMessage(KeyValues* params, VPANEL ifromPanel); + + public: + + virtual void GetSizerMinimumSize(int& wide, int& tall); + virtual void GetSizerClientArea(int& x, int& y, int& wide, int& tall); + CSizerBase* GetSizer(); + void SetSizer(CSizerBase* pSizer); + + protected: + + CSizerBase* m_pSizer; + }; + + inline void Panel::DisableMouseInputForThisPanel(bool bDisable) + { + _flags.SetFlag(IS_MOUSE_DISABLED_FOR_THIS_PANEL_ONLY, bDisable); + } + + inline bool Panel::IsMouseInputDisabledForThisPanel() const + { + return _flags.IsFlagSet(IS_MOUSE_DISABLED_FOR_THIS_PANEL_ONLY); + } + + template< class S > + inline void Panel::PostMessageToAllSiblingsOfType(KeyValues* msg, float delaySeconds ) + { + Panel* parent = GetParent(); + if (parent) + { + int nChildCount = parent->GetChildCount(); + for (int i = 0; i < nChildCount; ++i) + { + Panel* sibling = parent->GetChild(i); + if (sibling == this) + continue; + if (dynamic_cast(sibling)) + { + PostMessage(sibling->GetVPanel(), msg->MakeCopy(), delaySeconds); + } + } + } + + msg->deleteThis(); + } + +} + + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/PanelAnimationVar.h b/SpyCustom/sdk/PanelAnimationVar.h new file mode 100644 index 0000000..8b84555 --- /dev/null +++ b/SpyCustom/sdk/PanelAnimationVar.h @@ -0,0 +1,153 @@ +#ifndef PANELANIMATIONVAR_H +#define PANELANIMATIONVAR_H +#ifdef _WIN32 +#pragma once +#endif + +#include "utlvector.h" +#include "Panel.h" + +#define DECLARE_PANELANIMATION( className ) \ + static void AddToAnimationMap( char const *scriptname, char const *type, char const *var, \ + char const *defaultvalue, bool array, PANELLOOKUPFUNC func ) \ + { \ + PanelAnimationMap *map = FindOrAddPanelAnimationMap( GetPanelClassName() ); \ + \ + PanelAnimationMapEntry entry; \ + entry.m_pszScriptName = scriptname; \ + entry.m_pszVariable = var; \ + entry.m_pszType = type; \ + entry.m_pszDefaultValue = defaultvalue; \ + entry.m_pfnLookup = func; \ + entry.m_bArray = array; \ + \ + map->entries.AddToTail( entry ); \ + } \ + \ + static void ChainToAnimationMap( void ) \ + { \ + static bool chained = false; \ + if ( chained ) \ + return; \ + chained = true; \ + PanelAnimationMap *map = FindOrAddPanelAnimationMap( GetPanelClassName() ); \ + map->pfnClassName = GetPanelClassName; \ + if ( map && GetPanelBaseClassName() && GetPanelBaseClassName()[0] ) \ + { \ + map->baseMap = FindOrAddPanelAnimationMap( GetPanelBaseClassName() ); \ + } \ + } \ + \ + class className##_Register; \ + friend class className##_Register; \ + class className##_Register \ + { \ + public: \ + className##_Register() \ + { \ + className::ChainToAnimationMap(); \ + } \ + }; \ + className##_Register m_RegisterAnimationClass; \ + \ + virtual PanelAnimationMap *GetAnimMap() \ + { \ + return FindOrAddPanelAnimationMap( GetPanelClassName() ); \ + } + +typedef void* (*PANELLOOKUPFUNC)(vgui::Panel* panel); + +#define CPanelAnimationVarAliasType( type, name, scriptname, defaultvalue, typealias ) \ + class PanelAnimationVar_##name; \ + friend class PanelAnimationVar_##name; \ + static void *GetVar_##name( vgui::Panel *panel ) \ + { \ + return &(( ThisClass *)panel)->name; \ + } \ + class PanelAnimationVar_##name \ + { \ + public: \ + static void InitVar() \ + { \ + static bool bAdded = false; \ + if ( !bAdded ) \ + { \ + bAdded = true; \ + AddToAnimationMap( scriptname, typealias, #name, defaultvalue, false, ThisClass::GetVar_##name ); \ + } \ + } \ + PanelAnimationVar_##name() \ + { \ + PanelAnimationVar_##name::InitVar(); \ + } \ + }; \ + PanelAnimationVar_##name m_##name##_register; \ + type name; + +#define CPanelAnimationVar( type, name, scriptname, defaultvalue ) \ + CPanelAnimationVarAliasType( type, name, scriptname, defaultvalue, #type ) + +#define CPanelAnimationStringVarAliasType( count, name, scriptname, defaultvalue, typealias ) \ + class PanelAnimationVar_##name; \ + friend class PanelAnimationVar_##name; \ + static void *GetVar_##name( vgui::Panel *panel ) \ + { \ + return &(( ThisClass *)panel)->name; \ + } \ + class PanelAnimationVar_##name \ + { \ + public: \ + static void InitVar() \ + { \ + static bool bAdded = false; \ + if ( !bAdded ) \ + { \ + bAdded = true; \ + AddToAnimationMap( scriptname, typealias, #name, defaultvalue, true, ThisClass::GetVar_##name ); \ + } \ + } \ + PanelAnimationVar_##name() \ + { \ + PanelAnimationVar_##name::InitVar(); \ + } \ + }; \ + PanelAnimationVar_##name m_##name##_register; \ + char name[ count ]; + +#define CPanelAnimationStringVar( count, name, scriptname, defaultvalue ) \ + CPanelAnimationStringVarAliasType( count, name, scriptname, defaultvalue, "string" ) + +struct PanelAnimationMapEntry +{ + char const* name() { return m_pszScriptName; } + char const* type() { return m_pszType; } + char const* defaultvalue() { return m_pszDefaultValue; } + bool isarray() { return m_bArray; } + + char const* m_pszScriptName; + char const* m_pszVariable; + char const* m_pszType; + char const* m_pszDefaultValue; + bool m_bArray; + + PANELLOOKUPFUNC m_pfnLookup; +}; + +struct PanelAnimationMap +{ + PanelAnimationMap() + { + baseMap = NULL; + pfnClassName = NULL; + } + + CUtlVector< PanelAnimationMapEntry > entries; + PanelAnimationMap* baseMap; + char const* (*pfnClassName)(void); +}; + +PanelAnimationMap* FindPanelAnimationMap(char const* className); +PanelAnimationMap* FindOrAddPanelAnimationMap(char const* className); +void PanelAnimationDumpVars(char const* className); + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/ParticleSphereRenderer.h b/SpyCustom/sdk/ParticleSphereRenderer.h new file mode 100644 index 0000000..ac7316a --- /dev/null +++ b/SpyCustom/sdk/ParticleSphereRenderer.h @@ -0,0 +1,210 @@ +#ifndef PARTICLESPHERERENDERER_H +#define PARTICLESPHERERENDERER_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "particlemgr.h" +#include "particle_util.h" + + +class CParticleSphereRenderer +{ +public: + + CParticleSphereRenderer(); + + void Init(CParticleMgr* pParticleMgr, IMaterial* pMaterial); + + void StartRender(VMatrix& effectMatrix); + + void RenderParticle( + ParticleDraw* pDraw, + const Vector& vOriginalPos, + const Vector& vTransformedPos, + float flAlpha, + float flParticleSize, + float flAngle = 0.0f); + + void RenderParticle_AddColor( + ParticleDraw* pDraw, + const Vector& vOriginalPos, + const Vector& vTransformedPos, + float flAlpha, + float flParticleSize, + const Vector& vToAdd0to1 + ); + + + const Vector& GetBaseColor() const; + void SetBaseColor(const Vector& vColor); + + const CParticleLightInfo& GetAmbientLight() const; + void SetAmbientLight(const CParticleLightInfo& info); + + const CParticleLightInfo& GetDirectionalLight() const; + void SetDirectionalLight(const CParticleLightInfo& info); + + +private: + + void AddLightColor( + Vector const* pPos, + Vector const* pLightPos, + Vector const* pLightColor, + float flLightIntensity, + Vector* pOutColor); + + inline void ClampColor(Vector& vColor); + + +private: + + int m_iLastTickStartRenderCalled; + + CParticleMgr* m_pParticleMgr; + + Vector m_vBaseColor; + CParticleLightInfo m_AmbientLight; + CParticleLightInfo m_DirectionalLight; + bool m_bUsingPixelShaders; +}; + + +inline void CParticleSphereRenderer::AddLightColor( + Vector const* pPos, + Vector const* pLightPos, + Vector const* pLightColor, + float flLightIntensity, + Vector* pOutColor) +{ + if (flLightIntensity) + { + float fDist = pPos->DistToSqr(*pLightPos); + float fAmt; + if (fDist > 0.0001f) + fAmt = flLightIntensity / fDist; + else + fAmt = 1000.f; + + *pOutColor += *pLightColor * fAmt; + } +} + + +inline void CParticleSphereRenderer::ClampColor(Vector& vColor) +{ + float flMax = MAX(vColor.x, MAX(vColor.y, vColor.z)); + if (flMax > 1) + { + vColor *= 255.0f / flMax; + } + else + { + vColor *= 255.0; + } +} + + +inline const Vector& CParticleSphereRenderer::GetBaseColor() const +{ + return m_vBaseColor; +} + +inline void CParticleSphereRenderer::SetBaseColor(const Vector& vColor) +{ + m_vBaseColor = vColor; +} + +inline const CParticleLightInfo& CParticleSphereRenderer::GetAmbientLight() const +{ + return m_AmbientLight; +} + +inline void CParticleSphereRenderer::SetAmbientLight(const CParticleLightInfo& info) +{ + m_AmbientLight = info; +} + +inline const CParticleLightInfo& CParticleSphereRenderer::GetDirectionalLight() const +{ + return m_DirectionalLight; +} + +inline void CParticleSphereRenderer::SetDirectionalLight(const CParticleLightInfo& info) +{ + m_DirectionalLight = info; +} + +inline void CParticleSphereRenderer::RenderParticle( + ParticleDraw* pDraw, + const Vector& vOriginalPos, + const Vector& vTransformedPos, + float flAlpha, + float flParticleSize, + float flAngle) +{ +#ifdef _DEBUG + if (pDraw->GetMeshBuilder()) + { + Assert(m_iLastTickStartRenderCalled == gpGlobals->tickcount); + } +#endif + + Vector vColor = m_vBaseColor; + AddLightColor(&vOriginalPos, &m_AmbientLight.m_vPos, &m_AmbientLight.m_vColor, m_AmbientLight.m_flIntensity, &vColor); + + if (!m_bUsingPixelShaders) + { + AddLightColor(&vOriginalPos, &m_DirectionalLight.m_vPos, &m_DirectionalLight.m_vColor, m_DirectionalLight.m_flIntensity, &vColor); + } + + ClampColor(vColor); + + RenderParticle_Color255SizeNormalAngle( + pDraw, + vTransformedPos, + vColor, + flAlpha, + flParticleSize, + vec3_origin, + flAngle); +} + +inline void CParticleSphereRenderer::RenderParticle_AddColor( + ParticleDraw* pDraw, + const Vector& vOriginalPos, + const Vector& vTransformedPos, + float flAlpha, + float flParticleSize, + const Vector& vToAdd0to1 +) +{ +#ifdef _DEBUG + if (pDraw->GetMeshBuilder()) + { + Assert(m_iLastTickStartRenderCalled == gpGlobals->tickcount); + } +#endif + + Vector vColor = m_vBaseColor + vToAdd0to1; + AddLightColor(&vOriginalPos, &m_AmbientLight.m_vPos, &m_AmbientLight.m_vColor, m_AmbientLight.m_flIntensity, &vColor); + + if (!m_bUsingPixelShaders) + { + AddLightColor(&vOriginalPos, &m_DirectionalLight.m_vPos, &m_DirectionalLight.m_vColor, m_DirectionalLight.m_flIntensity, &vColor); + } + + ClampColor(vColor); + + RenderParticle_Color255Size( + pDraw, + vTransformedPos, + vColor, + flAlpha, + flParticleSize); +} + + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/RichText.h b/SpyCustom/sdk/RichText.h new file mode 100644 index 0000000..ffc2397 --- /dev/null +++ b/SpyCustom/sdk/RichText.h @@ -0,0 +1,234 @@ +#ifndef RICHTEXT_H +#define RICHTEXT_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "Panel.h" +#include "utlvector.h" + +namespace vgui +{ + + class ClickPanel; + + class RichText : public Panel + { + DECLARE_CLASS_SIMPLE(RichText, Panel); + + public: + RichText(Panel* parent, const char* panelName); + ~RichText(); + + virtual void SetText(const char* text); + virtual void SetText(const wchar_t* text); + void GetText(int offset, OUT_Z_BYTECAP(bufLenInBytes) wchar_t* buf, int bufLenInBytes); + void GetText(int offset, OUT_Z_BYTECAP(bufLenInBytes) char* pch, int bufLenInBytes); + + void SetFont(HFont font); + + void InsertChar(wchar_t ch); + void InsertString(const char* text); + void InsertString(const wchar_t* wszText); + + void SelectNone(); + void SelectAllText(); + void SelectNoText(); + MESSAGE_FUNC(CutSelected, "DoCutSelected"); + MESSAGE_FUNC(CopySelected, "DoCopySelected"); + + void SetPanelInteractive(bool bInteractive) { m_bInteractive = bInteractive; } + + void SetUnusedScrollbarInvisible(bool bInvis) { m_bUnusedScrollbarInvis = bInvis; } + + void GotoTextStart(); + void GotoTextEnd(); + + void SetVerticalScrollbar(bool state); + void SetMaximumCharCount(int maxChars); + + void InsertColorChange(Color col); + void InsertIndentChange(int pixelsIndent); + void InsertClickableTextStart(const char* pchClickAction = NULL); + void InsertClickableTextEnd(); + void InsertPossibleURLString(const char* text, Color URLTextColor, Color normalTextColor); + + void InsertFade(float flSustain, float flLength); + + void ResetAllFades(bool bHold, bool bOnlyExpired = false, float flNewSustain = -1.0f); + + void SetToFullHeight(); + int GetNumLines(); + + + virtual bool RequestInfo(KeyValues* outputData); + virtual void SetFgColor(Color color); + virtual void SetDrawOffsets(int ofsx, int ofsy); + bool IsScrollbarVisible(); + + void SetURLClickedHandler(Panel* pPanelToHandleClickMsg); + + void SetUnderlineFont(HFont font); + + bool IsAllTextAlphaZero() const; + bool HasText() const; + + void SetDrawTextOnly(); + + protected: + virtual void OnThink(); + virtual void PerformLayout(); + virtual void ApplySchemeSettings(IScheme* pScheme); + virtual void Paint(); + + virtual void ApplySettings(KeyValues* inResourceData); + virtual void GetSettings(KeyValues* outResourceData); + virtual const char* GetDescription(void); + MESSAGE_FUNC_WCHARPTR(OnSetText, "SetText", text); + MESSAGE_FUNC(OnSliderMoved, "ScrollBarSliderMoved"); + virtual void OnKillFocus(); + virtual void OnMouseWheeled(int delta); + virtual void OnKeyCodeTyped(KeyCode code); + + MESSAGE_FUNC_INT(OnClickPanel, "ClickPanel", index); + + virtual void OnCursorMoved(int x, int y); + virtual void OnMousePressed(MouseCode code); + virtual void OnMouseDoublePressed(MouseCode code); + virtual void OnMouseReleased(MouseCode code); + + virtual void OnMouseFocusTicked(); + virtual void OnCursorEntered(); + virtual void OnCursorExited(); + + virtual void OnMouseCaptureLost(); + virtual void OnSizeChanged(int newWide, int newTall); + virtual void OnSetFocus(); + + int ParseTextStringForUrls(const char* text, int startPos, char* pchURLText, int cchURLText, char* pchURL, int cchURL, bool& clickable); + virtual void OnTextClicked(const wchar_t* text); + +#ifdef DBGFLAG_VALIDATE + virtual void Validate(CValidator& validator, char* pchName); +#endif + + protected: + ScrollBar* _vertScrollBar; + + private: + int GetLineHeight(); + HFont GetDefaultFont(); + + const wchar_t* ResolveLocalizedTextAndVariables(char const* pchLookup, OUT_Z_BYTECAP(outbufsizeinbytes) wchar_t* outbuf, size_t outbufsizeinbytes); + void CheckRecalcLineBreaks(); + + void GotoWordRight(); + void GotoWordLeft(); + + void TruncateTextStream(); + bool GetSelectedRange(int& cx0, int& cx1); + void CursorToPixelSpace(int cursorPos, int& cx, int& cy); + int PixelToCursorSpace(int cx, int cy); + void AddAnotherLine(int& cx, int& cy); + void RecalculateDefaultState(int startIndex); + + void LayoutVerticalScrollBarSlider(); + void OpenEditMenu(); + void FinishingURL(int x, int y); + int GetStartDrawIndex(int& lineBreakIndexIndex); + int GetCursorLine(); + int GetClickableTextIndexStart(int startIndex); + void CreateEditMenu(); + + MESSAGE_FUNC_INT(MoveScrollBar, "MoveScrollBar", delta); + MESSAGE_FUNC_INT(MoveScrollBarDirect, "MoveScrollBarDirect", delta); + + void InvalidateLineBreakStream(); + void RecalculateLineBreaks(); + + struct TFade + { + float flFadeStartTime; + float flFadeLength; + float flFadeSustain; + int iOriginalAlpha; + }; + + struct TFormatStream + { + Color color; + int pixelsIndent; + bool textClickable; + CUtlSymbol m_sClickableTextAction; + + TFade fade; + + int textStreamIndex; + }; + + bool m_bResetFades; + bool m_bInteractive; + bool m_bUnusedScrollbarInvis; + bool m_bAllTextAlphaIsZero; + + CUtlVector m_TextStream; + CUtlVector m_LineBreaks; + CUtlVector m_FormatStream; + + bool m_bRecalcLineBreaks; + + int _recalculateBreaksIndex; + bool _invalidateVerticalScrollbarSlider; + int _cursorPos; + bool _mouseSelection; + bool _mouseDragSelection; + int _select[2]; + int _pixelsIndent; + int _maxCharCount; + HFont _font; + HFont m_hFontUnderline; + Color _selectionColor; + Color _selectionTextColor; + bool _currentTextClickable; + CUtlVector _clickableTextPanels; + int _clickableTextIndex; + Color _defaultTextColor; + int _drawOffsetX; + int _drawOffsetY; + + Panel* m_pInterior; + PHandle m_hPanelToHandleClickingURLs; + + + Menu* m_pEditMenu; + + char* m_pszInitialText; + + bool _recalcSavedRenderState; + + struct TRenderState + { + int x, y; + + Color textColor; + int pixelsIndent; + bool textClickable; + + int formatStreamIndex; + }; + TRenderState m_CachedRenderState; + + bool UpdateRenderState(int textStreamPos, TRenderState& renderState); + void CalculateFade(TRenderState& renderState); + + void GenerateRenderStateForTextStreamIndex(int textStreamIndex, TRenderState& renderState); + int FindFormatStreamIndexForTextStreamPos(int textStreamIndex); + + int DrawString(int iFirst, int iLast, TRenderState& renderState, HFont font); + }; + +} + + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/SndInfo.h b/SpyCustom/sdk/SndInfo.h new file mode 100644 index 0000000..6eed2e8 --- /dev/null +++ b/SpyCustom/sdk/SndInfo.h @@ -0,0 +1,51 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#ifndef SNDINFO_H +#define SNDINFO_H +#ifdef _WIN32 +#pragma once +#endif + +class Vector; +#include "utlsymbol.h" + +//----------------------------------------------------------------------------- +// Purpose: Client side only +//----------------------------------------------------------------------------- +struct SndInfo_t +{ + // Sound Guid + int m_nGuid; + FileNameHandle_t m_filenameHandle; // filesystem filename handle - call IFilesystem to conver this to a string + int m_nSoundSource; + int m_nChannel; + // If a sound is being played through a speaker entity (e.g., on a monitor,), this is the + // entity upon which to show the lips moving, if the sound has sentence data + int m_nSpeakerEntity; + float m_flVolume; + float m_flLastSpatializedVolume; + // Radius of this sound effect (spatialization is different within the radius) + float m_flRadius; + int m_nPitch; + Vector* m_pOrigin; + Vector* m_pDirection; + + // if true, assume sound source can move and update according to entity + bool m_bUpdatePositions; + // true if playing linked sentence + bool m_bIsSentence; + // if true, bypass all dsp processing for this sound (ie: music) + bool m_bDryMix; + // true if sound is playing through in-game speaker entity. + bool m_bSpeaker; + // true if sound is playing with special DSP effect + bool m_bSpecialDSP; + // for snd_show, networked sounds get colored differently than local sounds + bool m_bFromServer; +}; + +#endif // SNDINFO_H \ No newline at end of file diff --git a/SpyCustom/sdk/SteamCommon.h b/SpyCustom/sdk/SteamCommon.h new file mode 100644 index 0000000..bbc6e38 --- /dev/null +++ b/SpyCustom/sdk/SteamCommon.h @@ -0,0 +1,623 @@ + +#ifndef INCLUDED_STEAM2_USERID_STRUCTS +#define INCLUDED_STEAM2_USERID_STRUCTS + +#if defined(_MSC_VER) && (_MSC_VER > 1000) +#pragma once +#endif + + +#ifdef __cplusplus +extern "C" +{ +#endif + +#if defined ( _WIN32 ) + +#ifdef STEAM_EXPORTS +#define STEAM_API __declspec(dllexport) +#else +#define STEAM_API __declspec(dllimport) +#endif + +#define STEAM_CALL __cdecl + +#else + +#define STEAM_API +#define STEAM_CALL + +#endif + + typedef void (STEAM_CALL* KeyValueIteratorCallback_t)(const char* Key, const char* Val, void* pvParam); + + +#define STEAM_USING_FILESYSTEM (0x00000001) +#define STEAM_USING_LOGGING (0x00000002) +#define STEAM_USING_USERID (0x00000004) +#define STEAM_USING_ACCOUNT (0x00000008) +#define STEAM_USING_ALL (0x0000000f) +#define STEAM_MAX_PATH (255) +#define STEAM_QUESTION_MAXLEN (255) +#define STEAM_SALT_SIZE (8) +#define STEAM_PROGRESS_PERCENT_SCALE (0x00001000) + +#define STEAM_CARD_NUMBER_SIZE (17) +#define STEAM_CARD_HOLDERNAME_SIZE (100) +#define STEAM_CARD_EXPYEAR_SIZE (4) +#define STEAM_CARD_EXPMONTH_SIZE (2) +#define STEAM_CARD_CVV2_SIZE (5) +#define STEAM_BILLING_ADDRESS1_SIZE (128) +#define STEAM_BILLING_ADDRESS2_SIZE (128) +#define STEAM_BILLING_CITY_SIZE (50) +#define STEAM_BILLING_ZIP_SIZE (16) +#define STEAM_BILLING_STATE_SIZE (32) +#define STEAM_BILLING_COUNTRY_SIZE (32) +#define STEAM_BILLING_PHONE_SIZE (20) +#define STEAM_BILLING_EMAIL_ADDRESS_SIZE (100) +#define STEAM_TYPE_OF_PROOF_OF_PURCHASE_SIZE (20) +#define STEAM_PROOF_OF_PURCHASE_TOKEN_SIZE (200) +#define STEAM_EXTERNAL_ACCOUNTNAME_SIZE (100) +#define STEAM_EXTERNAL_ACCOUNTPASSWORD_SIZE (80) +#define STEAM_BILLING_CONFIRMATION_CODE_SIZE (22) +#define STEAM_BILLING_CARD_APPROVAL_CODE_SIZE (100) +#define STEAM_BILLING_TRANS_DATE_SIZE (9) +#define STEAM_BILLING_TRANS_TIME_SIZE (9) + + + typedef unsigned int SteamHandle_t; + + typedef void* SteamUserIDTicketValidationHandle_t; + + typedef unsigned int SteamCallHandle_t; + +#if defined(_MSC_VER) + typedef unsigned __int64 SteamUnsigned64_t; +#else + typedef unsigned long long SteamUnsigned64_t; +#endif + + typedef enum + { + eSteamSeekMethodSet = 0, + eSteamSeekMethodCur = 1, + eSteamSeekMethodEnd = 2 + } ESteamSeekMethod; + + typedef enum + { + eSteamBufferMethodFBF = 0, + eSteamBufferMethodNBF = 1 + } ESteamBufferMethod; + + typedef enum + { + eSteamErrorNone = 0, + eSteamErrorUnknown = 1, + eSteamErrorLibraryNotInitialized = 2, + eSteamErrorLibraryAlreadyInitialized = 3, + eSteamErrorConfig = 4, + eSteamErrorContentServerConnect = 5, + eSteamErrorBadHandle = 6, + eSteamErrorHandlesExhausted = 7, + eSteamErrorBadArg = 8, + eSteamErrorNotFound = 9, + eSteamErrorRead = 10, + eSteamErrorEOF = 11, + eSteamErrorSeek = 12, + eSteamErrorCannotWriteNonUserConfigFile = 13, + eSteamErrorCacheOpen = 14, + eSteamErrorCacheRead = 15, + eSteamErrorCacheCorrupted = 16, + eSteamErrorCacheWrite = 17, + eSteamErrorCacheSession = 18, + eSteamErrorCacheInternal = 19, + eSteamErrorCacheBadApp = 20, + eSteamErrorCacheVersion = 21, + eSteamErrorCacheBadFingerPrint = 22, + + eSteamErrorNotFinishedProcessing = 23, + eSteamErrorNothingToDo = 24, + eSteamErrorCorruptEncryptedUserIDTicket = 25, + eSteamErrorSocketLibraryNotInitialized = 26, + eSteamErrorFailedToConnectToUserIDTicketValidationServer = 27, + eSteamErrorBadProtocolVersion = 28, + eSteamErrorReplayedUserIDTicketFromClient = 29, + eSteamErrorReceiveResultBufferTooSmall = 30, + eSteamErrorSendFailed = 31, + eSteamErrorReceiveFailed = 32, + eSteamErrorReplayedReplyFromUserIDTicketValidationServer = 33, + eSteamErrorBadSignatureFromUserIDTicketValidationServer = 34, + eSteamErrorValidationStalledSoAborted = 35, + eSteamErrorInvalidUserIDTicket = 36, + eSteamErrorClientLoginRateTooHigh = 37, + eSteamErrorClientWasNeverValidated = 38, + eSteamErrorInternalSendBufferTooSmall = 39, + eSteamErrorInternalReceiveBufferTooSmall = 40, + eSteamErrorUserTicketExpired = 41, + eSteamErrorCDKeyAlreadyInUseOnAnotherClient = 42, + + eSteamErrorNotLoggedIn = 101, + eSteamErrorAlreadyExists = 102, + eSteamErrorAlreadySubscribed = 103, + eSteamErrorNotSubscribed = 104, + eSteamErrorAccessDenied = 105, + eSteamErrorFailedToCreateCacheFile = 106, + eSteamErrorCallStalledSoAborted = 107, + eSteamErrorEngineNotRunning = 108, + eSteamErrorEngineConnectionLost = 109, + eSteamErrorLoginFailed = 110, + eSteamErrorAccountPending = 111, + eSteamErrorCacheWasMissingRetry = 112, + eSteamErrorLocalTimeIncorrect = 113, + eSteamErrorCacheNeedsDecryption = 114, + eSteamErrorAccountDisabled = 115, + eSteamErrorCacheNeedsRepair = 116, + eSteamErrorRebootRequired = 117, + + eSteamErrorNetwork = 200, + eSteamErrorOffline = 201 + + + } ESteamError; + + + typedef enum + { + eNoDetailedErrorAvailable, + eStandardCerrno, + eWin32LastError, + eWinSockLastError, + eDetailedPlatformErrorCount + } EDetailedPlatformErrorType; + + typedef enum + { + eSteamFindLocalOnly, + eSteamFindRemoteOnly, + eSteamFindAll + } ESteamFindFilter; + + + + typedef struct + { + ESteamError eSteamError; + EDetailedPlatformErrorType eDetailedErrorType; + int nDetailedErrorCode; + char szDesc[STEAM_MAX_PATH]; + } TSteamError; + + + + typedef struct + { + int bIsDir; + unsigned int uSizeOrCount; + int bIsLocal; + char cszName[STEAM_MAX_PATH]; + long lLastAccessTime; + long lLastModificationTime; + long lCreationTime; + } TSteamElemInfo; + + + typedef struct + { + unsigned int uNumSubscriptions; + unsigned int uMaxNameChars; + unsigned int uMaxApps; + + } TSteamSubscriptionStats; + + + typedef struct + { + unsigned int uNumApps; + unsigned int uMaxNameChars; + unsigned int uMaxInstallDirNameChars; + unsigned int uMaxVersionLabelChars; + unsigned int uMaxLaunchOptions; + unsigned int uMaxLaunchOptionDescChars; + unsigned int uMaxLaunchOptionCmdLineChars; + unsigned int uMaxNumIcons; + unsigned int uMaxIconSize; + unsigned int uMaxDependencies; + + } TSteamAppStats; + + typedef struct + { + char* szLabel; + unsigned int uMaxLabelChars; + unsigned int uVersionId; + int bIsNotAvailable; + } TSteamAppVersion; + + typedef struct + { + char* szDesc; + unsigned int uMaxDescChars; + char* szCmdLine; + unsigned int uMaxCmdLineChars; + unsigned int uIndex; + unsigned int uIconIndex; + int bNoDesktopShortcut; + int bNoStartMenuShortcut; + int bIsLongRunningUnattended; + + } TSteamAppLaunchOption; + + + typedef struct + { + char* szName; + unsigned int uMaxNameChars; + char* szLatestVersionLabel; + unsigned int uMaxLatestVersionLabelChars; + char* szCurrentVersionLabel; + unsigned int uMaxCurrentVersionLabelChars; + char* szInstallDirName; + unsigned int uMaxInstallDirNameChars; + unsigned int uId; + unsigned int uLatestVersionId; + unsigned int uCurrentVersionId; + unsigned int uMinCacheFileSizeMB; + unsigned int uMaxCacheFileSizeMB; + unsigned int uNumLaunchOptions; + unsigned int uNumIcons; + unsigned int uNumVersions; + unsigned int uNumDependencies; + + } TSteamApp; + + typedef enum + { + eNoCost = 0, + eBillOnceOnly = 1, + eBillMonthly = 2, + eProofOfPrepurchaseOnly = 3, + eGuestPass = 4, + eHardwarePromo = 5, + eNumBillingTypes, + } EBillingType; + + typedef struct + { + char* szName; + unsigned int uMaxNameChars; + unsigned int* puAppIds; + unsigned int uMaxAppIds; + unsigned int uId; + unsigned int uNumApps; + EBillingType eBillingType; + unsigned int uCostInCents; + unsigned int uNumDiscounts; + int bIsPreorder; + int bRequiresShippingAddress; + unsigned int uDomesticShippingCostInCents; + unsigned int uInternationalShippingCostInCents; + bool bIsCyberCafeSubscription; + unsigned int uGameCode; + char szGameCodeDesc[STEAM_MAX_PATH]; + bool bIsDisabled; + bool bRequiresCD; + unsigned int uTerritoryCode; + bool bIsSteam3Subscription; + + } TSteamSubscription; + + typedef struct + { + char szName[STEAM_MAX_PATH]; + unsigned int uDiscountInCents; + unsigned int uNumQualifiers; + + } TSteamSubscriptionDiscount; + + typedef struct + { + char szName[STEAM_MAX_PATH]; + unsigned int uRequiredSubscription; + int bIsDisqualifier; + + } TSteamDiscountQualifier; + + typedef struct TSteamProgress + { + int bValid; + unsigned int uPercentDone; + char szProgress[STEAM_MAX_PATH]; + } TSteamProgress; + + typedef enum + { + eSteamNotifyTicketsWillExpire, + eSteamNotifyAccountInfoChanged, + eSteamNotifyContentDescriptionChanged, + eSteamNotifyPleaseShutdown, + eSteamNotifyNewContentServer, + eSteamNotifySubscriptionStatusChanged, + eSteamNotifyContentServerConnectionLost, + eSteamNotifyCacheLoadingCompleted, + eSteamNotifyCacheNeedsDecryption, + eSteamNotifyCacheNeedsRepair + } ESteamNotificationCallbackEvent; + + + typedef void(*SteamNotificationCallback_t)(ESteamNotificationCallbackEvent eEvent, unsigned int nData); + + + typedef char SteamPersonalQuestion_t[STEAM_QUESTION_MAXLEN + 1]; + + typedef struct + { + unsigned char uchSalt[STEAM_SALT_SIZE]; + } SteamSalt_t; + + typedef enum + { + eVisa = 1, + eMaster = 2, + eAmericanExpress = 3, + eDiscover = 4, + eDinnersClub = 5, + eJCB = 6 + } ESteamPaymentCardType; + + typedef struct + { + ESteamPaymentCardType eCardType; + char szCardNumber[STEAM_CARD_NUMBER_SIZE + 1]; + char szCardHolderName[STEAM_CARD_HOLDERNAME_SIZE + 1]; + char szCardExpYear[STEAM_CARD_EXPYEAR_SIZE + 1]; + char szCardExpMonth[STEAM_CARD_EXPMONTH_SIZE + 1]; + char szCardCVV2[STEAM_CARD_CVV2_SIZE + 1]; + char szBillingAddress1[STEAM_BILLING_ADDRESS1_SIZE + 1]; + char szBillingAddress2[STEAM_BILLING_ADDRESS2_SIZE + 1]; + char szBillingCity[STEAM_BILLING_CITY_SIZE + 1]; + char szBillingZip[STEAM_BILLING_ZIP_SIZE + 1]; + char szBillingState[STEAM_BILLING_STATE_SIZE + 1]; + char szBillingCountry[STEAM_BILLING_COUNTRY_SIZE + 1]; + char szBillingPhone[STEAM_BILLING_PHONE_SIZE + 1]; + char szBillingEmailAddress[STEAM_BILLING_EMAIL_ADDRESS_SIZE + 1]; + unsigned int uExpectedCostInCents; + unsigned int uExpectedTaxInCents; + char szShippingName[STEAM_CARD_HOLDERNAME_SIZE + 1]; + char szShippingAddress1[STEAM_BILLING_ADDRESS1_SIZE + 1]; + char szShippingAddress2[STEAM_BILLING_ADDRESS2_SIZE + 1]; + char szShippingCity[STEAM_BILLING_CITY_SIZE + 1]; + char szShippingZip[STEAM_BILLING_ZIP_SIZE + 1]; + char szShippingState[STEAM_BILLING_STATE_SIZE + 1]; + char szShippingCountry[STEAM_BILLING_COUNTRY_SIZE + 1]; + char szShippingPhone[STEAM_BILLING_PHONE_SIZE + 1]; + unsigned int uExpectedShippingCostInCents; + + } TSteamPaymentCardInfo; + + typedef struct + { + char szTypeOfProofOfPurchase[STEAM_TYPE_OF_PROOF_OF_PURCHASE_SIZE + 1]; + + unsigned int uLengthOfBinaryProofOfPurchaseToken; + char cBinaryProofOfPurchaseToken[STEAM_PROOF_OF_PURCHASE_TOKEN_SIZE + 1]; + } TSteamPrepurchaseInfo; + + typedef struct + { + char szAccountName[STEAM_EXTERNAL_ACCOUNTNAME_SIZE + 1]; + char szPassword[STEAM_EXTERNAL_ACCOUNTPASSWORD_SIZE + 1]; + } TSteamExternalBillingInfo; + + typedef enum + { + ePaymentCardInfo = 1, + ePrepurchasedInfo = 2, + eAccountBillingInfo = 3, + eExternalBillingInfo = 4, + ePaymentCardReceipt = 5, + ePrepurchaseReceipt = 6, + eEmptyReceipt = 7 + } ESteamSubscriptionBillingInfoType; + + typedef struct + { + ESteamSubscriptionBillingInfoType eBillingInfoType; + union { + TSteamPaymentCardInfo PaymentCardInfo; + TSteamPrepurchaseInfo PrepurchaseInfo; + TSteamExternalBillingInfo ExternalBillingInfo; + char bUseAccountBillingInfo; + }; + + } TSteamSubscriptionBillingInfo; + + typedef enum + { + eSteamSubscriptionOK = 0, + eSteamSubscriptionPending = 1, + eSteamSubscriptionPreorder = 2, + eSteamSubscriptionPrepurchaseTransferred = 3, + eSteamSubscriptionPrepurchaseInvalid = 4, + eSteamSubscriptionPrepurchaseRejected = 5, + eSteamSubscriptionPrepurchaseRevoked = 6, + eSteamSubscriptionPaymentCardDeclined = 7, + eSteamSubscriptionCancelledByUser = 8, + eSteamSubscriptionCancelledByVendor = 9, + eSteamSubscriptionPaymentCardUseLimit = 10, + eSteamSubscriptionPaymentCardAlert = 11, + eSteamSubscriptionFailed = 12, + eSteamSubscriptionPaymentCardAVSFailure = 13, + eSteamSubscriptionPaymentCardInsufficientFunds = 14, + eSteamSubscriptionRestrictedCountry = 15 + + } ESteamSubscriptionStatus; + + typedef struct + { + ESteamPaymentCardType eCardType; + char szCardLastFourDigits[4 + 1]; + char szCardHolderName[STEAM_CARD_HOLDERNAME_SIZE + 1]; + char szBillingAddress1[STEAM_BILLING_ADDRESS1_SIZE + 1]; + char szBillingAddress2[STEAM_BILLING_ADDRESS2_SIZE + 1]; + char szBillingCity[STEAM_BILLING_CITY_SIZE + 1]; + char szBillingZip[STEAM_BILLING_ZIP_SIZE + 1]; + char szBillingState[STEAM_BILLING_STATE_SIZE + 1]; + char szBillingCountry[STEAM_BILLING_COUNTRY_SIZE + 1]; + + char szCardApprovalCode[STEAM_BILLING_CARD_APPROVAL_CODE_SIZE + 1]; + char szTransDate[STEAM_BILLING_TRANS_DATE_SIZE + 1]; + char szTransTime[STEAM_BILLING_TRANS_TIME_SIZE + 1]; + unsigned int uPriceWithoutTax; + unsigned int uTaxAmount; + unsigned int uShippingCost; + + } TSteamPaymentCardReceiptInfo; + + typedef struct + { + char szTypeOfProofOfPurchase[STEAM_TYPE_OF_PROOF_OF_PURCHASE_SIZE + 1]; + } TSteamPrepurchaseReceiptInfo; + + typedef struct + { + ESteamSubscriptionStatus eStatus; + ESteamSubscriptionStatus ePreviousStatus; + ESteamSubscriptionBillingInfoType eReceiptInfoType; + char szConfirmationCode[STEAM_BILLING_CONFIRMATION_CODE_SIZE + 1]; + union { + TSteamPaymentCardReceiptInfo PaymentCardReceiptInfo; + TSteamPrepurchaseReceiptInfo PrepurchaseReceiptInfo; + }; + + } TSteamSubscriptionReceipt; + + typedef enum + { + ePhysicalBytesReceivedThisSession = 1, + eAppReadyToLaunchStatus = 2, + eAppPreloadStatus = 3, + eAppEntireDepot = 4, + eCacheBytesPresent = 5 + } ESteamAppUpdateStatsQueryType; + + typedef struct + { + SteamUnsigned64_t uBytesTotal; + SteamUnsigned64_t uBytesPresent; + } TSteamUpdateStats; + + typedef enum + { + eSteamUserAdministrator = 0x00000001, + eSteamUserDeveloper = 0x00000002, + eSteamUserCyberCafe = 0x00000004 + } ESteamUserTypeFlags; + + typedef enum + { + eSteamAccountStatusDefault = 0x00000000, + eSteamAccountStatusEmailVerified = 0x00000001, + eSteamAccountDisabled = 0x00000004 + } ESteamAccountStatusBitFields; + + + typedef enum + { + eSteamBootstrapperError = -1, + eSteamBootstrapperDontCheckForUpdate = 0, + eSteamBootstrapperCheckForUpdateAndRerun = 7 + + } ESteamBootStrapperClientAppResult; + + typedef enum + { + eSteamOnline = 0, + eSteamOffline = 1, + eSteamNoAuthMode = 2, + eSteamBillingOffline = 3 + } eSteamOfflineStatus; + + typedef struct + { + int eOfflineNow; + int eOfflineNextSession; + } TSteamOfflineStatus; + + typedef struct + { + unsigned int uAppId; + int bIsSystemDefined; + char szMountPath[STEAM_MAX_PATH]; + } TSteamAppDependencyInfo; + + typedef enum + { + eSteamOpenFileRegular = 0x0, + eSteamOpenFileIgnoreLocal = 0x1, + eSteamOpenFileChecksumReads = 0x2 + } ESteamOpenFileFlags; + + typedef enum + { + eSteamValveCDKeyValidationServer = 0, + eSteamHalfLifeMasterServer = 1, + eSteamFriendsServer = 2, + eSteamCSERServer = 3, + eSteamHalfLife2MasterServer = 4, + eSteamRDKFMasterServer = 5, + eMaxServerTypes = 6 + } ESteamServerType; + + +#ifdef __cplusplus + + const SteamHandle_t STEAM_INVALID_HANDLE = 0; + const SteamCallHandle_t STEAM_INVALID_CALL_HANDLE = 0; + const SteamUserIDTicketValidationHandle_t STEAM_INACTIVE_USERIDTICKET_VALIDATION_HANDLE = 0; + const unsigned int STEAM_USE_LATEST_VERSION = 0xFFFFFFFF; + +#else + +#define STEAM_INVALID_HANDLE ((SteamHandle_t)(0)) +#define STEAM_INVALID_CALL_HANDLE ((SteamCallHandle_t)(0)) +#define STEAM_INACTIVE_USERIDTICKET_VALIDATION_HANDLE ((SteamUserIDTicketValidationHandle_t)(0)) +#define STEAM_USE_LATEST_VERSION (0xFFFFFFFFu); + +#endif + + + typedef unsigned short SteamInstanceID_t; + + +#if defined ( _WIN32 ) + typedef unsigned __int64 SteamLocalUserID_t; +#else + typedef unsigned long long SteamLocalUserID_t; +#endif + + typedef struct + { + unsigned int Low32bits; + unsigned int High32bits; + } TSteamSplitLocalUserID; + + typedef struct + { + SteamInstanceID_t m_SteamInstanceID; + + union + { + SteamLocalUserID_t As64bits; + TSteamSplitLocalUserID Split; + } m_SteamLocalUserID; + + } TSteamGlobalUserID; + + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/SpyCustom/sdk/TextEntry.h b/SpyCustom/sdk/TextEntry.h new file mode 100644 index 0000000..5b2311a --- /dev/null +++ b/SpyCustom/sdk/TextEntry.h @@ -0,0 +1,280 @@ +#ifndef TEXTENTRY_H +#define TEXTENTRY_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "VGUI.h" +#include "Color.h" +#include "Panel.h" +#include "Label.h" +#include "ListPanel.h" + +#include "utlvector.h" + +namespace vgui +{ + + class TextEntry : public Panel + { + DECLARE_CLASS_SIMPLE(TextEntry, Panel); + + public: + TextEntry(Panel* parent, const char* panelName); + virtual ~TextEntry(); + + virtual void SetText(const wchar_t* wszText); + virtual void SetText(const char* text); + virtual void GetText(OUT_Z_BYTECAP(bufLenInBytes) char* buf, int bufLenInBytes); + virtual void GetText(OUT_Z_BYTECAP(bufLenInBytes) wchar_t* buf, int bufLenInBytes); + virtual int GetTextLength() const; + virtual bool IsTextFullySelected() const; + + virtual void GotoLeft(); + virtual void GotoRight(); + virtual void GotoUp(); + virtual void GotoDown(); + virtual void GotoWordRight(); + virtual void GotoWordLeft(); + virtual void GotoFirstOfLine(); + virtual void GotoEndOfLine(); + virtual void GotoTextStart(); + virtual void GotoTextEnd(); + + virtual void InsertChar(wchar_t ch); + virtual void InsertString(const char* text); + virtual void InsertString(const wchar_t* wszText); + virtual void Backspace(); + virtual void Delete(); + virtual void SelectNone(); + virtual void OpenEditMenu(); + MESSAGE_FUNC(CutSelected, "DoCutSelected"); + MESSAGE_FUNC(CopySelected, "DoCopySelected"); + MESSAGE_FUNC(Paste, "DoPaste"); + + MESSAGE_FUNC_INT(LanguageChanged, "DoLanguageChanged", handle); + MESSAGE_FUNC_INT(ConversionModeChanged, "DoConversionModeChanged", handle); + MESSAGE_FUNC_INT(SentenceModeChanged, "DoSentenceModeChanged", handle); + + MESSAGE_FUNC_WCHARPTR(CompositionString, "DoCompositionString", string); + + MESSAGE_FUNC(ShowIMECandidates, "DoShowIMECandidates"); + MESSAGE_FUNC(HideIMECandidates, "DoHideIMECandidates"); + MESSAGE_FUNC(UpdateIMECandidates, "DoUpdateIMECandidates"); + + virtual void DeleteSelected(); + virtual void Undo(); + virtual void SaveUndoState(); + virtual void SetFont(HFont font); + virtual void SetTextHidden(bool bHideText); + virtual void SetEditable(bool state); + virtual bool IsEditable(); + virtual void SetEnabled(bool state); + virtual void MoveCursor(int line, int pixelsAcross); + + virtual void SetDisabledBgColor(Color col); + + virtual void SetMultiline(bool state); + virtual bool IsMultiline(); + + virtual void SetVerticalScrollbar(bool state); + + virtual void SetCatchEnterKey(bool state); + + virtual void SendNewLine(bool send); + + virtual void SetMaximumCharCount(int maxChars); + virtual int GetMaximumCharCount(); + virtual void SetAutoProgressOnHittingCharLimit(bool state); + + virtual void SetWrap(bool wrap); + + virtual void RecalculateLineBreaks(); + virtual void LayoutVerticalScrollBarSlider(); + + virtual bool RequestInfo(KeyValues* outputData); + + void SetToFullHeight(); + + void SetToFullWidth(); + + int GetNumLines(); + + void SelectAllText(bool bResetCursorPos); + void SelectNoText(); + void SelectAllOnFirstFocus(bool status); + void SetDrawWidth(int width); + int GetDrawWidth(); + void SetHorizontalScrolling(bool status); + + void SetAllowNonAsciiCharacters(bool state); + + void SetAllowNumericInputOnly(bool state); + + void SetDrawLanguageIDAtLeft(bool state); + + virtual bool GetDropContextMenu(Menu* menu, CUtlVector< KeyValues* >& data); + virtual bool IsDroppable(CUtlVector< KeyValues* >& data); + virtual void OnPanelDropped(CUtlVector< KeyValues* >& data); + virtual Panel* GetDragPanel(); + virtual void OnCreateDragData(KeyValues* msg); + + void SelectAllOnFocusAlways(bool status); + void SetSelectionTextColor(const Color& clr); + void SetSelectionBgColor(const Color& clr); + void SetSelectionUnfocusedBgColor(const Color& clr); + + void SetUseFallbackFont(bool bState, HFont hFallback); + + protected: + virtual void ResetCursorBlink(); + virtual void PerformLayout(); + virtual void ApplySchemeSettings(IScheme* pScheme); + virtual void PaintBackground(); + virtual int DrawChar(wchar_t ch, HFont font, int index, int x, int y); + virtual bool DrawCursor(int x, int y); + + virtual void SetCharAt(wchar_t ch, int index); + virtual void ApplySettings(KeyValues* inResourceData); + virtual void GetSettings(KeyValues* outResourceData); + virtual const char* GetDescription(void); + virtual void FireActionSignal(); + virtual bool GetSelectedRange(int& cx0, int& cx1); + virtual void CursorToPixelSpace(int cursorPos, int& cx, int& cy); + virtual int PixelToCursorSpace(int cx, int cy); + virtual void AddAnotherLine(int& cx, int& cy); + virtual int GetYStart(); + + virtual bool SelectCheck(bool fromMouse = false); + MESSAGE_FUNC_WCHARPTR(OnSetText, "SetText", text); + MESSAGE_FUNC(OnSliderMoved, "ScrollBarSliderMoved"); + virtual void OnKillFocus(); + virtual void OnMouseWheeled(int delta); + virtual void OnKeyCodePressed(KeyCode code); + virtual void OnKeyCodeTyped(KeyCode code); + virtual void OnKeyTyped(wchar_t unichar); + + virtual void OnCursorMoved(int x, int y); + virtual void OnMousePressed(MouseCode code); + virtual void OnMouseDoublePressed(MouseCode code); + virtual void OnMouseTriplePressed(MouseCode code); + virtual void OnMouseReleased(MouseCode code); + + virtual void OnKeyFocusTicked(); + virtual void OnMouseFocusTicked(); + virtual void OnCursorEntered(); + virtual void OnCursorExited(); + + virtual void OnMouseCaptureLost(); + virtual void OnSizeChanged(int newWide, int newTall); + + virtual int GetStartDrawIndex(int& lineBreakIndexIndex); + + public: + virtual float GetValueAsFloat(); + virtual int GetValueAsInt(); + + protected: + void ScrollRight(); + void ScrollLeft(); + bool IsCursorOffRightSideOfWindow(int cursorPos); + bool IsCursorOffLeftSideOfWindow(int cursorPos); + void ScrollLeftForResize(); + + void OnSetFocus(); + void OnChangeIME(bool forward); + + bool NeedsEllipses(HFont font, int* pIndex); + + private: + MESSAGE_FUNC_INT(OnSetState, "SetState", state); + int GetCurrentLineStart(); + int GetCurrentLineEnd(); + bool IsLineBreak(int index); + int GetCursorLine(); + void MoveScrollBar(int delta); + void CalcBreakIndex(); + void CreateEditMenu(); + + public: + Menu* GetEditMenu(); + + private: + void FlipToLastIME(); + + public: + virtual void GetTextRange(wchar_t* buf, int from, int numchars); + virtual void GetTextRange(char* buf, int from, int numchars); + + private: + + CUtlVector m_TextStream; + CUtlVector m_UndoTextStream; + CUtlVector m_LineBreaks; + + int _cursorPos; + bool _cursorIsAtEnd; + bool _putCursorAtEnd; + int _undoCursorPos; + bool _cursorBlink; + bool _hideText; + bool _editable; + bool _mouseSelection; + bool _mouseDragSelection; + int _mouseSelectCursorStart; + long _cursorNextBlinkTime; + int _cursorBlinkRate; + int _select[2]; + int _pixelsIndent; + int _charCount; + int _maxCharCount; + HFont _font; + HFont _smallfont; + bool _dataChanged; + bool _multiline; + bool _verticalScrollbar; + ScrollBar* _vertScrollBar; + Color _cursorColor; + Color _disabledFgColor; + Color _disabledBgColor; + Color _selectionColor; + Color _selectionTextColor; + Color _defaultSelectionBG2Color; + int _currentStartLine; + int _currentStartIndex; + bool _horizScrollingAllowed; + Color _focusEdgeColor; + bool _catchEnterKey; + bool _wrap; + bool _sendNewLines; + int _drawWidth; + + Menu* m_pEditMenu; + + int _recalculateBreaksIndex; + bool _selectAllOnFirstFocus : 1; + bool _selectAllOnFocusAlways : 1; + bool _firstFocusStatus; + bool m_bAllowNumericInputOnly; + bool m_bAllowNonAsciiCharacters; + bool m_bAutoProgressOnHittingCharLimit; + + enum + { + MAX_COMPOSITION_STRING = 256, + }; + + wchar_t m_szComposition[MAX_COMPOSITION_STRING]; + Menu* m_pIMECandidates; + int m_hPreviousIME; + bool m_bDrawLanguageIDAtLeft; + int m_nLangInset; + + bool m_bUseFallbackFont : 1; + HFont m_hFallbackFont; + }; + +} + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/TextImage.h b/SpyCustom/sdk/TextImage.h new file mode 100644 index 0000000..91aaf4a --- /dev/null +++ b/SpyCustom/sdk/TextImage.h @@ -0,0 +1,118 @@ +#ifndef TEXTIMAGE_H +#define TEXTIMAGE_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "VGUI.h" +#include "ILocalize.h" +#include "Image.h" + +#include "utlvector.h" +#include "UtlSortVector.h" + +class KeyValues; + +namespace vgui +{ + + struct label_colorchange_t + { + Color color; + int textStreamIndex; + }; + + class CColorChangeListLess + { + public: + bool Less(const label_colorchange_t& src1, const label_colorchange_t& src2, void* pCtx) + { + if (src1.textStreamIndex < src2.textStreamIndex) + return true; + + return false; + } + }; + + class TextImage : public Image + { + public: + TextImage(const char* text); + TextImage(const wchar_t* wszText); + ~TextImage(); + + public: + virtual void SetText(const char* text); + virtual void SetText(const wchar_t* text, bool bClearUnlocalizedSymbol = false); + virtual void GetText(char* buffer, int bufferSize); + virtual void GetText(wchar_t* buffer, int bufferLength); + virtual void GetUnlocalizedText(char* buffer, int bufferSize); + virtual StringIndex_t GetUnlocalizedTextSymbol(); + + virtual void SetFont(vgui::HFont font); + virtual vgui::HFont GetFont(); + + void SetDrawWidth(int width); + void GetDrawWidth(int& width); + + void ResizeImageToContent(); + void ResizeImageToContentMaxWidth(int nMaxWidth); + + virtual void SetSize(int wide, int tall); + + virtual void GetContentSize(int& wide, int& tall); + + virtual void Paint(); + + void SetWrap(bool bWrap); + void RecalculateNewLinePositions(); + + void SetUseFallbackFont(bool bState, HFont hFallback); + + void SetAllCaps(bool bAllCaps); + + void SetCenterWrap(bool bWrap); + void RecalculateCenterWrapIndents(); + + const wchar_t* GetUText(void) { return _utext; } + + void AddColorChange(Color col, int iTextStreamIndex); + void SetColorChangeStream(CUtlSortVector* pUtlVecStream); + void ClearColorChangeStream(void) { m_ColorChangeStream.Purge(); } + + const wchar_t* GetEllipsesPosition(void) const { return m_pwszEllipsesPosition; } + bool IsWrapping() const { return m_LineBreaks.Count() != 0; } + + protected: + void SizeText(wchar_t* tempText, int stringLength); + virtual void GetTextSize(int& wide, int& tall); + + private: + void RecalculateEllipsesPosition(); + + wchar_t* _utext; + short _textBufferLen; + short _textLen; + vgui::HFont _font; + vgui::HFont _fallbackFont; + int _drawWidth; + StringIndex_t _unlocalizedTextSymbol; + wchar_t* m_pwszEllipsesPosition; + + bool m_bRecalculateTruncation : 1; + bool m_bWrap : 1; + bool m_bUseFallbackFont : 1; + bool m_bRenderUsingFallbackFont : 1; + bool m_bAllCaps : 1; + CUtlVector m_LineBreaks; + + bool m_bWrapCenter; + CUtlVector m_LineXIndent; + + CUtlSortVector m_ColorChangeStream; + }; + +} + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/ToggleButton.h b/SpyCustom/sdk/ToggleButton.h new file mode 100644 index 0000000..031338c --- /dev/null +++ b/SpyCustom/sdk/ToggleButton.h @@ -0,0 +1,38 @@ +#ifndef TOGGLEBUTTON_H +#define TOGGLEBUTTON_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "VGUI.h" +#include "Button.h" + +namespace vgui +{ + + class ToggleButton : public Button + { + DECLARE_CLASS_SIMPLE(ToggleButton, Button); + + public: + ToggleButton(Panel* parent, const char* panelName, const char* text); + + virtual void DoClick(); + + protected: + virtual void OnMouseDoublePressed(MouseCode code); + + virtual Color GetButtonFgColor(); + virtual void ApplySchemeSettings(IScheme* pScheme); + + virtual bool CanBeDefaultButton(void); + virtual void OnKeyCodePressed(KeyCode code); + + private: + Color _selectedColor; + }; + +} + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/Tooltip.h b/SpyCustom/sdk/Tooltip.h new file mode 100644 index 0000000..a0ecc08 --- /dev/null +++ b/SpyCustom/sdk/Tooltip.h @@ -0,0 +1,66 @@ +#ifndef TOOLTIP_H +#define TOOLTIP_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "VGUI.h" +#include "Controls.h" +#include "utlvector.h" + +namespace vgui +{ + + class BaseTooltip + { + public: + BaseTooltip(Panel* parent, const char* text = NULL); + + virtual void SetText(const char* text); + virtual const char* GetText(); + + virtual void ShowTooltip(Panel* currentPanel); + virtual void HideTooltip(); + + bool ShouldLayout(void); + virtual void PerformLayout() { return; } + virtual void PositionWindow(Panel* pTipPanel); + + void ResetDelay(); + void SetTooltipFormatToSingleLine(); + void SetTooltipFormatToMultiLine(); + void SetTooltipDelay(int tooltipDelayMilliseconds); + int GetTooltipDelay(); + void SetEnabled(bool bState); + + private: + Panel* m_pParent; + virtual void ApplySchemeSettings(IScheme* pScheme) {}; + protected: + CUtlVector m_Text; + int _delay; + int _tooltipDelay; + bool _makeVisible : 1; + bool _displayOnOneLine : 1; + bool _isDirty : 1; + bool _enabled : 1; + }; + + class TextTooltip : public BaseTooltip + { + public: + TextTooltip(Panel* parent, const char* text = NULL); + ~TextTooltip(); + + virtual void SetText(const char* text); + virtual void ShowTooltip(Panel* currentPanel); + virtual void HideTooltip(); + virtual void SizeTextWindow(); + virtual void PerformLayout(); + virtual void ApplySchemeSettings(IScheme* pScheme); + }; + +}; + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/lightdesc.h b/SpyCustom/sdk/lightdesc.h new file mode 100644 index 0000000..d896a31 --- /dev/null +++ b/SpyCustom/sdk/lightdesc.h @@ -0,0 +1,139 @@ +#ifndef LIGHTDESC_H +#define LIGHTDESC_H + +#include "ssemath.h" +#include "vector.h" + +enum LightType_t +{ + MATERIAL_LIGHT_DISABLE = 0, + MATERIAL_LIGHT_POINT, + MATERIAL_LIGHT_DIRECTIONAL, + MATERIAL_LIGHT_SPOT, +}; + +enum LightType_OptimizationFlags_t +{ + LIGHTTYPE_OPTIMIZATIONFLAGS_HAS_ATTENUATION0 = 1, + LIGHTTYPE_OPTIMIZATIONFLAGS_HAS_ATTENUATION1 = 2, + LIGHTTYPE_OPTIMIZATIONFLAGS_HAS_ATTENUATION2 = 4, + LIGHTTYPE_OPTIMIZATIONFLAGS_DERIVED_VALUES_CALCED = 8, +}; + +struct LightDesc_t +{ + LightType_t m_Type; + Vector m_Color; + Vector m_Position; + Vector m_Direction; + float m_Range; + float m_Falloff; + float m_Attenuation0; + float m_Attenuation1; + float m_Attenuation2; + float m_Theta; + float m_Phi; + + float m_ThetaDot; + float m_PhiDot; + unsigned int m_Flags; +protected: + float OneOver_ThetaDot_Minus_PhiDot; + float m_RangeSquared; +public: + + void RecalculateDerivedValues(void); + + LightDesc_t(void) + { + } + + LightDesc_t(const Vector& pos, const Vector& color) + { + InitPoint(pos, color); + } + + LightDesc_t(const Vector& pos, const Vector& color, const Vector& point_at, + float inner_cone_boundary, float outer_cone_boundary) + { + InitSpot(pos, color, point_at, inner_cone_boundary, outer_cone_boundary); + } + + void InitPoint(const Vector& pos, const Vector& color); + void InitDirectional(const Vector& dir, const Vector& color); + void InitSpot(const Vector& pos, const Vector& color, const Vector& point_at, + float inner_cone_boundary, float outer_cone_boundary); + + void ComputeLightAtPoints(const FourVectors& pos, const FourVectors& normal, + FourVectors& color, bool DoHalfLambert = false) const; + void ComputeNonincidenceLightAtPoints(const FourVectors& pos, FourVectors& color) const; + void ComputeLightAtPointsForDirectional(const FourVectors& pos, + const FourVectors& normal, + FourVectors& color, bool DoHalfLambert = false) const; + + void SetupOldStyleAttenuation(float fQuadatricAttn, float fLinearAttn, float fConstantAttn); + + void SetupNewStyleAttenuation(float fFiftyPercentDistance, float fZeroPercentDistance); + + + bool IsDirectionWithinLightCone(const Vector& rdir) const + { + return ((m_Type != MATERIAL_LIGHT_SPOT) || (rdir.Dot(m_Direction) >= m_PhiDot)); + } + + float OneOverThetaDotMinusPhiDot() const + { + return OneOver_ThetaDot_Minus_PhiDot; + } +}; + + +inline void LightDesc_t::InitPoint(const Vector& pos, const Vector& color) +{ + m_Type = MATERIAL_LIGHT_POINT; + m_Color = color; + m_Position = pos; + m_Range = 0.0; + m_Attenuation0 = 1.0; + m_Attenuation1 = 0; + m_Attenuation2 = 0; + RecalculateDerivedValues(); +} + + +inline void LightDesc_t::InitDirectional(const Vector& dir, const Vector& color) +{ + m_Type = MATERIAL_LIGHT_DIRECTIONAL; + m_Color = color; + m_Direction = dir; + m_Range = 0.0; + m_Attenuation0 = 1.0; + m_Attenuation1 = 0; + m_Attenuation2 = 0; + RecalculateDerivedValues(); +} + + +inline void LightDesc_t::InitSpot(const Vector& pos, const Vector& color, const Vector& point_at, + float inner_cone_boundary, float outer_cone_boundary) +{ + m_Type = MATERIAL_LIGHT_SPOT; + m_Color = color; + m_Position = pos; + m_Direction = point_at; + m_Direction -= pos; + VectorNormalizeFast(m_Direction); + m_Falloff = 5.0; + m_Theta = inner_cone_boundary; + m_Phi = outer_cone_boundary; + + m_Range = 0.0; + + m_Attenuation0 = 1.0; + m_Attenuation1 = 0; + m_Attenuation2 = 0; + RecalculateDerivedValues(); +} + + +#endif diff --git a/SpyCustom/sdk/localflexcontroller.h b/SpyCustom/sdk/localflexcontroller.h new file mode 100644 index 0000000..60f2c36 --- /dev/null +++ b/SpyCustom/sdk/localflexcontroller.h @@ -0,0 +1,21 @@ +#ifndef LOCALFLEXCONTROLLER_H +#define LOCALFLEXCONTROLLER_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "platform.h" + +enum LocalFlexController_t +{ + DUMMY_FLEX_CONTROLLER = 0x7fffffff +}; + +inline LocalFlexController_t& operator++(LocalFlexController_t& a) { return a = LocalFlexController_t(int(a) + 1); } +inline LocalFlexController_t& operator--(LocalFlexController_t& a) { return a = LocalFlexController_t(int(a) - 1); } +inline LocalFlexController_t operator++(LocalFlexController_t& a, int) { LocalFlexController_t t = a; a = LocalFlexController_t(int(a) + 1); return t; } +inline LocalFlexController_t operator--(LocalFlexController_t& a, int) { LocalFlexController_t t = a; a = LocalFlexController_t(int(a) - 1); return t; } + + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/logging.h b/SpyCustom/sdk/logging.h new file mode 100644 index 0000000..a9fdfab --- /dev/null +++ b/SpyCustom/sdk/logging.h @@ -0,0 +1,421 @@ +#ifndef LOGGING_H +#define LOGGING_H + +#if !defined(__SPU__) + +#if defined( COMPILER_MSVC ) +#pragma once +#endif + +#include "color.h" +#include "icommandline.h" +#include + +#if defined( _X360 ) +#include "xbox/xbox_console.h" +#endif + +#if defined( _WIN32 ) || (defined(POSIX) && !defined(_GAMECONSOLE)) +#include "win32consoleio.h" +#endif + +class CLoggingSystem; +class CThreadFastMutex; + +const int MAX_LOGGING_MESSAGE_LENGTH = 2048; + +const int MAX_LOGGING_IDENTIFIER_LENGTH = 32; + +const int MAX_LOGGING_CHANNEL_COUNT = 256; + +const int MAX_LOGGING_TAG_COUNT = 1024; + +const int MAX_LOGGING_TAG_CHARACTER_COUNT = 8192; + +const int MAX_LOGGING_LISTENER_COUNT = 16; + +const Color UNSPECIFIED_LOGGING_COLOR(0, 0, 0, 0); + +typedef int LoggingChannelID_t; + +const LoggingChannelID_t INVALID_LOGGING_CHANNEL_ID = -1; + +enum LoggingSeverity_t +{ + LS_MESSAGE = 0, + + LS_WARNING = 1, + + LS_ASSERT = 2, + + LS_ERROR = 3, + + LS_HIGHEST_SEVERITY = 4, +}; + +enum LoggingResponse_t +{ + LR_CONTINUE, + LR_DEBUGGER, + LR_ABORT, +}; + +enum LoggingChannelFlags_t +{ + LCF_CONSOLE_ONLY = 0x00000001, + + LCF_DO_NOT_ECHO = 0x00000002, +}; + +typedef void (*RegisterTagsFunc)(); + +struct LoggingContext_t +{ + LoggingChannelID_t m_ChannelID; + LoggingChannelFlags_t m_Flags; + LoggingSeverity_t m_Severity; + Color m_Color; +}; + +class ILoggingListener +{ +public: + virtual void Log(const LoggingContext_t* pContext, const tchar* pMessage) = 0; +}; + +class ILoggingResponsePolicy +{ +public: + virtual LoggingResponse_t OnLog(const LoggingContext_t* pContext) = 0; +}; + +class CSimpleLoggingListener : public ILoggingListener +{ +public: + CSimpleLoggingListener(bool bQuietPrintf = false, bool bQuietDebugger = false) : + m_bQuietPrintf(bQuietPrintf), + m_bQuietDebugger(bQuietDebugger) + { + } + + virtual void Log(const LoggingContext_t* pContext, const tchar* pMessage) + { +#ifdef _X360 + if (!m_bQuietDebugger && XBX_IsConsoleConnected()) + { + XBX_DebugString(XMAKECOLOR(0, 0, 0), pMessage); + } + else +#endif + { +#if !defined( _CERT ) && !defined( DBGFLAG_STRINGS_STRIP ) + if (!m_bQuietPrintf) + { + _tprintf(_T("%s"), pMessage); + } +#endif + +#ifdef _WIN32 + if (!m_bQuietDebugger && Plat_IsInDebugSession()) + { + Plat_DebugString(pMessage); + } +#endif + } + } + + bool m_bQuietPrintf; + bool m_bQuietDebugger; +}; + +class CSimpleWindowsLoggingListener : public ILoggingListener +{ +public: + virtual void Log(const LoggingContext_t* pContext, const tchar* pMessage) + { + if (Plat_IsInDebugSession()) + { + Plat_DebugString(pMessage); + } + if (pContext->m_Severity == LS_ERROR) + { + if (Plat_IsInDebugSession()) + DebuggerBreak(); + + Plat_MessageBox("Error", pMessage); + } + } +}; + + +#if !defined(_GAMECONSOLE) +class CColorizedLoggingListener : public CSimpleLoggingListener +{ +public: + CColorizedLoggingListener(bool bQuietPrintf = false, bool bQuietDebugger = false) : CSimpleLoggingListener(bQuietPrintf, bQuietDebugger) + { + InitWin32ConsoleColorContext(&m_ColorContext); + } + + virtual void Log(const LoggingContext_t* pContext, const tchar* pMessage) + { + if (!m_bQuietPrintf) + { + int nPrevColor = -1; + + if (pContext->m_Color != UNSPECIFIED_LOGGING_COLOR) + { + nPrevColor = SetWin32ConsoleColor(&m_ColorContext, + pContext->m_Color.r(), pContext->m_Color.g(), pContext->m_Color.b(), + MAX(MAX(pContext->m_Color.r(), pContext->m_Color.g()), pContext->m_Color.b()) > 128); + } + + _tprintf(_T("%s"), pMessage); + + if (nPrevColor >= 0) + { + RestoreWin32ConsoleColor(&m_ColorContext, nPrevColor); + } + } + +#ifdef _WIN32 + if (!m_bQuietDebugger && Plat_IsInDebugSession()) + { + Plat_DebugString(pMessage); + } +#endif + } + + Win32ConsoleColorContext_t m_ColorContext; +}; +#endif + + +class CDefaultLoggingResponsePolicy : public ILoggingResponsePolicy +{ +public: + virtual LoggingResponse_t OnLog(const LoggingContext_t* pContext) + { + if (pContext->m_Severity == LS_ASSERT && !CommandLine()->FindParm("-noassert")) + { + return LR_DEBUGGER; + } + else if (pContext->m_Severity == LS_ERROR) + { + return LR_ABORT; + } + else + { + return LR_CONTINUE; + } + } +}; + +class CNonFatalLoggingResponsePolicy : public ILoggingResponsePolicy +{ +public: + virtual LoggingResponse_t OnLog(const LoggingContext_t* pContext) + { + if ((pContext->m_Severity == LS_ASSERT && !CommandLine()->FindParm("-noassert")) || pContext->m_Severity == LS_ERROR) + { + return LR_DEBUGGER; + } + else + { + return LR_CONTINUE; + } + } +}; + +class CLoggingSystem +{ +public: + struct LoggingChannel_t; + + CLoggingSystem(); + ~CLoggingSystem(); + + LoggingChannelID_t RegisterLoggingChannel(const char* pChannelName, RegisterTagsFunc registerTagsFunc, int flags = 0, LoggingSeverity_t minimumSeverity = LS_MESSAGE, Color spewColor = UNSPECIFIED_LOGGING_COLOR); + + LoggingChannelID_t FindChannel(const char* pChannelName) const; + + int GetChannelCount() const { return m_nChannelCount; } + + LoggingChannel_t* GetChannel(LoggingChannelID_t channelID); + const LoggingChannel_t* GetChannel(LoggingChannelID_t channelID) const; + + bool HasTag(LoggingChannelID_t channelID, const char* pTag) const { return GetChannel(channelID)->HasTag(pTag); } + + bool IsValidChannelID(LoggingChannelID_t channelID) const { return (channelID >= 0) && (channelID < m_nChannelCount); } + + bool IsChannelEnabled(LoggingChannelID_t channelID, LoggingSeverity_t severity) const { return IsValidChannelID(channelID) && GetChannel(channelID)->IsEnabled(severity); } + + void SetChannelSpewLevel(LoggingChannelID_t channelID, LoggingSeverity_t minimumSeverity); + void SetChannelSpewLevelByName(const char* pName, LoggingSeverity_t minimumSeverity); + void SetChannelSpewLevelByTag(const char* pTag, LoggingSeverity_t minimumSeverity); + void SetGlobalSpewLevel(LoggingSeverity_t minimumSeverity); + + Color GetChannelColor(LoggingChannelID_t channelID) const { return GetChannel(channelID)->m_SpewColor; } + void SetChannelColor(LoggingChannelID_t channelID, Color color) { GetChannel(channelID)->m_SpewColor = color; } + + LoggingChannelFlags_t GetChannelFlags(LoggingChannelID_t channelID) const { return GetChannel(channelID)->m_Flags; } + void SetChannelFlags(LoggingChannelID_t channelID, LoggingChannelFlags_t flags) { GetChannel(channelID)->m_Flags = flags; } + + void AddTagToCurrentChannel(const char* pTagName); + + void PushLoggingState(bool bThreadLocal = false, bool bClearState = true); + void PopLoggingState(bool bThreadLocal = false); + + void RegisterLoggingListener(ILoggingListener* pListener); + + bool IsListenerRegistered(ILoggingListener* pListener); + + void ResetCurrentLoggingState(); + + void SetLoggingResponsePolicy(ILoggingResponsePolicy* pLoggingResponse); + + LoggingResponse_t LogDirect(LoggingChannelID_t channelID, LoggingSeverity_t severity, Color color, const tchar* pMessage); + + struct LoggingTag_t + { + const char* m_pTagName; + LoggingTag_t* m_pNextTag; + }; + + struct LoggingChannel_t + { + bool HasTag(const char* pTag) const + { + LoggingTag_t* pCurrentTag = m_pFirstTag; + while (pCurrentTag != NULL) + { + if (stricmp(pCurrentTag->m_pTagName, pTag) == 0) + { + return true; + } + pCurrentTag = pCurrentTag->m_pNextTag; + } + return false; + } + bool IsEnabled(LoggingSeverity_t severity) const { return severity >= m_MinimumSeverity; } + void SetSpewLevel(LoggingSeverity_t severity) { m_MinimumSeverity = severity; } + + LoggingChannelID_t m_ID; + LoggingChannelFlags_t m_Flags; + LoggingSeverity_t m_MinimumSeverity; + Color m_SpewColor; + char m_Name[MAX_LOGGING_IDENTIFIER_LENGTH]; + LoggingTag_t* m_pFirstTag; + }; + +private: + struct LoggingState_t + { + int m_nPreviousStackEntry; + + int m_nListenerCount; + ILoggingListener* m_RegisteredListeners[MAX_LOGGING_LISTENER_COUNT]; + + ILoggingResponsePolicy* m_pLoggingResponse; + }; + + LoggingState_t* GetCurrentState(); + const LoggingState_t* GetCurrentState() const; + + int FindUnusedStateIndex(); + LoggingTag_t* AllocTag(const char* pTagName); + + int m_nChannelCount; + LoggingChannel_t m_RegisteredChannels[MAX_LOGGING_CHANNEL_COUNT]; + + int m_nChannelTagCount; + LoggingTag_t m_ChannelTags[MAX_LOGGING_TAG_COUNT]; + + int m_nTagNamePoolIndex; + char m_TagNamePool[MAX_LOGGING_TAG_CHARACTER_COUNT]; + + CThreadFastMutex* m_pStateMutex; + + int m_nGlobalStateIndex; + + static const int MAX_LOGGING_STATE_COUNT = 16; + LoggingState_t m_LoggingStates[MAX_LOGGING_STATE_COUNT]; + + CDefaultLoggingResponsePolicy m_DefaultLoggingResponse; + + CSimpleLoggingListener m_DefaultLoggingListener; + +}; + +#ifdef DBGFLAG_STRINGS_STRIP +#define InternalMsg( Channel, Severity, ... ) do { if ( Severity == LS_ERROR && LoggingSystem_IsChannelEnabled( Channel, Severity ) ) LoggingSystem_Log( Channel, Severity, ##__VA_ARGS__ ); } while( 0 ) +#else +#define InternalMsg( Channel, Severity, ... ) do { if ( LoggingSystem_IsChannelEnabled( Channel, Severity ) ) LoggingSystem_Log( Channel, Severity, ##__VA_ARGS__ ); } while( 0 ) +#endif + +#define Log_Msg( Channel, ... ) InternalMsg( Channel, LS_MESSAGE, ##__VA_ARGS__ ) +#define Log_Warning( Channel, ... ) InternalMsg( Channel, LS_WARNING, ##__VA_ARGS__ ) +#define Log_Error( Channel, ... ) InternalMsg( Channel, LS_ERROR, ##__VA_ARGS__ ) +#ifdef DBGFLAG_STRINGS_STRIP +#define Log_Assert( ... ) LR_CONTINUE +#else +#define Log_Assert( Message, ... ) LoggingSystem_LogAssert( Message, ##__VA_ARGS__ ) +#endif + + +#define DECLARE_LOGGING_CHANNEL( Channel ) extern LoggingChannelID_t Channel + +#define DEFINE_LOGGING_CHANNEL_NO_TAGS( Channel, ChannelName, ... ) \ + LoggingChannelID_t Channel = LoggingSystem_RegisterLoggingChannel( ChannelName, NULL, ##__VA_ARGS__ ) + +#define BEGIN_DEFINE_LOGGING_CHANNEL( Channel, ChannelName, ... ) \ + static void Register_##Channel##_Tags(); \ + LoggingChannelID_t Channel = LoggingSystem_RegisterLoggingChannel( ChannelName, Register_##Channel##_Tags, ##__VA_ARGS__ ); \ + void Register_##Channel##_Tags() \ + { + +#define ADD_LOGGING_CHANNEL_TAG( Tag ) LoggingSystem_AddTagToCurrentChannel( Tag ) + +#define END_DEFINE_LOGGING_CHANNEL() \ + } + +PLATFORM_INTERFACE LoggingChannelID_t LoggingSystem_RegisterLoggingChannel(const char* pName, RegisterTagsFunc registerTagsFunc, int flags = 0, LoggingSeverity_t severity = LS_MESSAGE, Color color = UNSPECIFIED_LOGGING_COLOR); + +PLATFORM_INTERFACE void LoggingSystem_RegisterLoggingListener(ILoggingListener* pListener); +PLATFORM_INTERFACE void LoggingSystem_UnregisterLoggingListener(ILoggingListener* pListener); +PLATFORM_INTERFACE void LoggingSystem_ResetCurrentLoggingState(); +PLATFORM_INTERFACE void LoggingSystem_SetLoggingResponsePolicy(ILoggingResponsePolicy* pResponsePolicy); +PLATFORM_INTERFACE void LoggingSystem_PushLoggingState(bool bThreadLocal = false, bool bClearState = true); +PLATFORM_INTERFACE void LoggingSystem_PopLoggingState(bool bThreadLocal = false); + +PLATFORM_INTERFACE void LoggingSystem_AddTagToCurrentChannel(const char* pTagName); + +PLATFORM_INTERFACE LoggingChannelID_t LoggingSystem_FindChannel(const char* pChannelName); +PLATFORM_INTERFACE int LoggingSystem_GetChannelCount(); +PLATFORM_INTERFACE LoggingChannelID_t LoggingSystem_GetFirstChannelID(); +PLATFORM_INTERFACE LoggingChannelID_t LoggingSystem_GetNextChannelID(LoggingChannelID_t channelID); +PLATFORM_INTERFACE const CLoggingSystem::LoggingChannel_t* LoggingSystem_GetChannel(LoggingChannelID_t channelID); + +PLATFORM_INTERFACE bool LoggingSystem_HasTag(LoggingChannelID_t channelID, const char* pTag); + +PLATFORM_INTERFACE bool LoggingSystem_IsChannelEnabled(LoggingChannelID_t channelID, LoggingSeverity_t severity); +PLATFORM_INTERFACE void LoggingSystem_SetChannelSpewLevel(LoggingChannelID_t channelID, LoggingSeverity_t minimumSeverity); +PLATFORM_INTERFACE void LoggingSystem_SetChannelSpewLevelByName(const char* pName, LoggingSeverity_t minimumSeverity); +PLATFORM_INTERFACE void LoggingSystem_SetChannelSpewLevelByTag(const char* pTag, LoggingSeverity_t minimumSeverity); +PLATFORM_INTERFACE void LoggingSystem_SetGlobalSpewLevel(LoggingSeverity_t minimumSeverity); + +PLATFORM_INTERFACE int32 LoggingSystem_GetChannelColor(LoggingChannelID_t channelID); +PLATFORM_INTERFACE void LoggingSystem_SetChannelColor(LoggingChannelID_t channelID, int color); + +PLATFORM_INTERFACE LoggingChannelFlags_t LoggingSystem_GetChannelFlags(LoggingChannelID_t channelID); +PLATFORM_INTERFACE void LoggingSystem_SetChannelFlags(LoggingChannelID_t channelID, LoggingChannelFlags_t flags); + +PLATFORM_INTERFACE LoggingResponse_t LoggingSystem_Log(LoggingChannelID_t channelID, LoggingSeverity_t severity, PRINTF_FORMAT_STRING const char* pMessageFormat, ...) FMTFUNCTION(3, 4); +PLATFORM_OVERLOAD LoggingResponse_t LoggingSystem_Log(LoggingChannelID_t channelID, LoggingSeverity_t severity, Color spewColor, PRINTF_FORMAT_STRING const char* pMessageFormat, ...) FMTFUNCTION(4, 5); + +PLATFORM_INTERFACE LoggingResponse_t LoggingSystem_LogDirect(LoggingChannelID_t channelID, LoggingSeverity_t severity, Color spewColor, const char* pMessage); +PLATFORM_INTERFACE LoggingResponse_t LoggingSystem_LogAssert(PRINTF_FORMAT_STRING const char* pMessageFormat, ...) FMTFUNCTION(1, 2); + +#endif + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/math_pfns.h b/SpyCustom/sdk/math_pfns.h new file mode 100644 index 0000000..52292fe --- /dev/null +++ b/SpyCustom/sdk/math_pfns.h @@ -0,0 +1,66 @@ +#ifndef _MATH_PFNS_H_ +#define _MATH_PFNS_H_ + +#if defined( _X360 ) +#include +#endif + +#if !defined( _X360 ) + +extern float (*pfSqrt)(float x); +extern float (*pfRSqrt)(float x); +extern float (*pfRSqrtFast)(float x); +extern void (*pfFastSinCos)(float x, float* s, float* c); +extern float (*pfFastCos)(float x); + +#define FastSqrt(x) (*pfSqrt)(x) +#define FastRSqrt(x) (*pfRSqrt)(x) +#define FastRSqrtFast(x) (*pfRSqrtFast)(x) +#define FastSinCos(x,s,c) (*pfFastSinCos)(x,s,c) +#define FastCos(x) (*pfFastCos)(x) + +#if defined(__i386__) || defined(_M_IX86) +#undef FastSqrt +#define FastSqrt(x) ::sqrtf(x) +#endif + +#endif + +#if defined( _X360 ) + +FORCEINLINE float _VMX_Sqrt(float x) +{ + return __fsqrts(x); +} + +FORCEINLINE float _VMX_RSqrt(float x) +{ + float rroot = __frsqrte(x); + + return (0.5f * rroot) * (3.0f - (x * rroot) * rroot); +} + +FORCEINLINE float _VMX_RSqrtFast(float x) +{ + return __frsqrte(x); +} + +FORCEINLINE void _VMX_SinCos(float a, float* pS, float* pC) +{ + XMScalarSinCos(pS, pC, a); +} + +FORCEINLINE float _VMX_Cos(float a) +{ + return XMScalarCos(a); +} + +#define FastSqrt(x) _VMX_Sqrt(x) +#define FastRSqrt(x) _VMX_RSqrt(x) +#define FastRSqrtFast(x) _VMX_RSqrtFast(x) +#define FastSinCos(x,s,c) _VMX_SinCos(x,s,c) +#define FastCos(x) _VMX_Cos(x) + +#endif + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/mathlib.h b/SpyCustom/sdk/mathlib.h new file mode 100644 index 0000000..9f32d71 --- /dev/null +++ b/SpyCustom/sdk/mathlib.h @@ -0,0 +1,1785 @@ +#ifndef MATH_LIB_H +#define MATH_LIB_H + +#include +#include "basetypes.h" +#include "commonmacros.h" +#include "vector.h" +#include "vector2d.h" +#include "dbg.h" + +#include "math_pfns.h" + +#if defined(__i386__) || defined(_M_IX86) +#include +#endif + +#undef clamp + + +#ifdef FP_EXCEPTIONS_ENABLED +#include +#endif + +class FPExceptionDisabler +{ +public: +#ifdef FP_EXCEPTIONS_ENABLED + FPExceptionDisabler(); + ~FPExceptionDisabler(); + +private: + unsigned int mOldValues; +#else + FPExceptionDisabler() {} + ~FPExceptionDisabler() {} +#endif + +private: + FPExceptionDisabler(const FPExceptionDisabler&); + FPExceptionDisabler& operator=(const FPExceptionDisabler&); +}; + +class FPExceptionEnabler +{ +public: +#ifdef FP_EXCEPTIONS_ENABLED + FPExceptionEnabler(unsigned int enableBits = _EM_OVERFLOW | _EM_ZERODIVIDE | _EM_INVALID); + ~FPExceptionEnabler(); + +private: + unsigned int mOldValues; +#else + FPExceptionEnabler(unsigned int enableBits = 0) + { + } + ~FPExceptionEnabler() + { + } +#endif + +private: + FPExceptionEnabler(const FPExceptionEnabler&); + FPExceptionEnabler& operator=(const FPExceptionEnabler&); +}; + + + +#ifdef DEBUG +FORCEINLINE float clamp(float val, float minVal, float maxVal) +{ + if (maxVal < minVal) + return maxVal; + else if (val < minVal) + return minVal; + else if (val > maxVal) + return maxVal; + else + return val; +} +#else +FORCEINLINE float clamp(float val, float minVal, float maxVal) +{ +#if defined(__i386__) || defined(_M_IX86) + _mm_store_ss(&val, + _mm_min_ss( + _mm_max_ss( + _mm_load_ss(&val), + _mm_load_ss(&minVal)), + _mm_load_ss(&maxVal))); +#else + val = fpmax(minVal, val); + val = fpmin(maxVal, val); +#endif + return val; +} +#endif + +template< class T > +inline T clamp(T const& val, T const& minVal, T const& maxVal) +{ + if (maxVal < minVal) + return maxVal; + else if (val < minVal) + return minVal; + else if (val > maxVal) + return maxVal; + else + return val; +} + + +struct cplane_t +{ + Vector normal; + float dist; + byte type; + byte signbits; + byte pad[2]; + +#ifdef VECTOR_NO_SLOW_OPERATIONS + cplane_t() {} + +private: + cplane_t(const cplane_t& vOther); +#endif +}; + +#define CPLANE_NORMAL_X 0 +#define CPLANE_NORMAL_Y 4 +#define CPLANE_NORMAL_Z 8 +#define CPLANE_DIST 12 +#define CPLANE_TYPE 16 +#define CPLANE_SIGNBITS 17 +#define CPLANE_PAD0 18 +#define CPLANE_PAD1 19 + +#define PLANE_X 0 +#define PLANE_Y 1 +#define PLANE_Z 2 + +#define PLANE_ANYX 3 +#define PLANE_ANYY 4 +#define PLANE_ANYZ 5 + + +enum +{ + FRUSTUM_RIGHT = 0, + FRUSTUM_LEFT = 1, + FRUSTUM_TOP = 2, + FRUSTUM_BOTTOM = 3, + FRUSTUM_NEARZ = 4, + FRUSTUM_FARZ = 5, + FRUSTUM_NUMPLANES = 6 +}; + +extern int SignbitsForPlane(cplane_t* out); + +class Frustum_t +{ +public: + void SetPlane(int i, int nType, const Vector& vecNormal, float dist) + { + m_Plane[i].normal = vecNormal; + m_Plane[i].dist = dist; + m_Plane[i].type = nType; + m_Plane[i].signbits = SignbitsForPlane(&m_Plane[i]); + m_AbsNormal[i].Init(fabs(vecNormal.x), fabs(vecNormal.y), fabs(vecNormal.z)); + } + + inline const cplane_t* GetPlane(int i) const { return &m_Plane[i]; } + inline const Vector& GetAbsNormal(int i) const { return m_AbsNormal[i]; } + +private: + cplane_t m_Plane[FRUSTUM_NUMPLANES]; + Vector m_AbsNormal[FRUSTUM_NUMPLANES]; +}; + +float CalcFovY(float flFovX, float flScreenAspect); +float CalcFovX(float flFovY, float flScreenAspect); + +void GeneratePerspectiveFrustum(const Vector& origin, const QAngle& angles, float flZNear, float flZFar, float flFovX, float flAspectRatio, Frustum_t& frustum); +void GeneratePerspectiveFrustum(const Vector& origin, const Vector& forward, const Vector& right, const Vector& up, float flZNear, float flZFar, float flFovX, float flFovY, Frustum_t& frustum); + +bool R_CullBox(const Vector& mins, const Vector& maxs, const Frustum_t& frustum); +bool R_CullBoxSkipNear(const Vector& mins, const Vector& maxs, const Frustum_t& frustum); + +struct matrix3x4_t +{ + matrix3x4_t() {} + matrix3x4_t( + float m00, float m01, float m02, float m03, + float m10, float m11, float m12, float m13, + float m20, float m21, float m22, float m23) + { + m_flMatVal[0][0] = m00; m_flMatVal[0][1] = m01; m_flMatVal[0][2] = m02; m_flMatVal[0][3] = m03; + m_flMatVal[1][0] = m10; m_flMatVal[1][1] = m11; m_flMatVal[1][2] = m12; m_flMatVal[1][3] = m13; + m_flMatVal[2][0] = m20; m_flMatVal[2][1] = m21; m_flMatVal[2][2] = m22; m_flMatVal[2][3] = m23; + } + + void Init(const Vector& xAxis, const Vector& yAxis, const Vector& zAxis, const Vector& vecOrigin) + { + m_flMatVal[0][0] = xAxis.x; m_flMatVal[0][1] = yAxis.x; m_flMatVal[0][2] = zAxis.x; m_flMatVal[0][3] = vecOrigin.x; + m_flMatVal[1][0] = xAxis.y; m_flMatVal[1][1] = yAxis.y; m_flMatVal[1][2] = zAxis.y; m_flMatVal[1][3] = vecOrigin.y; + m_flMatVal[2][0] = xAxis.z; m_flMatVal[2][1] = yAxis.z; m_flMatVal[2][2] = zAxis.z; m_flMatVal[2][3] = vecOrigin.z; + } + + matrix3x4_t(const Vector& xAxis, const Vector& yAxis, const Vector& zAxis, const Vector& vecOrigin) + { + Init(xAxis, yAxis, zAxis, vecOrigin); + } + + inline void Invalidate(void) + { + for (int i = 0; i < 3; i++) + { + for (int j = 0; j < 4; j++) + { + m_flMatVal[i][j] = VEC_T_NAN; + } + } + } + + float* operator[](int i) { Assert((i >= 0) && (i < 3)); return m_flMatVal[i]; } + const float* operator[](int i) const { Assert((i >= 0) && (i < 3)); return m_flMatVal[i]; } + float* Base() { return &m_flMatVal[0][0]; } + const float* Base() const { return &m_flMatVal[0][0]; } + + float m_flMatVal[3][4]; +}; + +#include "fltx4.h" + +class ALIGN16 matrix3x4a_t : public matrix3x4_t +{ +public: + matrix3x4a_t(const matrix3x4_t& src) { *this = src; }; + matrix3x4a_t& operator=(const matrix3x4_t& src) { memcpy(Base(), src.Base(), sizeof(float) * 3 * 4); return *this; }; + + matrix3x4a_t( + float m00, float m01, float m02, float m03, + float m10, float m11, float m12, float m13, + float m20, float m21, float m22, float m23) + { + AssertDbg(((size_t)Base() & 0xf) == 0); + m_flMatVal[0][0] = m00; m_flMatVal[0][1] = m01; m_flMatVal[0][2] = m02; m_flMatVal[0][3] = m03; + m_flMatVal[1][0] = m10; m_flMatVal[1][1] = m11; m_flMatVal[1][2] = m12; m_flMatVal[1][3] = m13; + m_flMatVal[2][0] = m20; m_flMatVal[2][1] = m21; m_flMatVal[2][2] = m22; m_flMatVal[2][3] = m23; + } + matrix3x4a_t() {} + + static FORCEINLINE bool TypeIsAlignedForSIMD(void) { return true; } + + + FORCEINLINE fltx4& SIMDRow(uint nIdx) { AssertDbg(nIdx < 3); return *((fltx4*)(&(m_flMatVal[nIdx]))); } + FORCEINLINE const fltx4& SIMDRow(uint nIdx) const { AssertDbg(nIdx < 3); return *((const fltx4*)(&(m_flMatVal[nIdx]))); } + +} ALIGN16_POST; + + + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#define M_PI_F ((float)(M_PI)) + +#ifndef RAD2DEG +#define RAD2DEG( x ) ( (float)(x) * (float)(180.f / M_PI_F) ) +#endif + +#ifndef DEG2RAD +#define DEG2RAD( x ) ( (float)(x) * (float)(M_PI_F / 180.f) ) +#endif + +#define SIDE_FRONT 0 +#define SIDE_BACK 1 +#define SIDE_ON 2 +#define SIDE_CROSS -2 + +#define ON_VIS_EPSILON 0.01 +#define EQUAL_EPSILON 0.001 + +extern bool s_bMathlibInitialized; + +extern const Vector vec3_origin; +extern const QAngle vec3_angle; +extern const Quaternion quat_identity; +extern const Vector vec3_invalid; +extern const int nanmask; + +#define IS_NAN(x) (((*(int *)&x)&nanmask)==nanmask) + +FORCEINLINE vec_t DotProduct(const vec_t* v1, const vec_t* v2) +{ + return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]; +} +FORCEINLINE void VectorSubtract(const vec_t* a, const vec_t* b, vec_t* c) +{ + c[0] = a[0] - b[0]; + c[1] = a[1] - b[1]; + c[2] = a[2] - b[2]; +} +FORCEINLINE void VectorAdd(const vec_t* a, const vec_t* b, vec_t* c) +{ + c[0] = a[0] + b[0]; + c[1] = a[1] + b[1]; + c[2] = a[2] + b[2]; +} +FORCEINLINE void VectorCopy(const vec_t* a, vec_t* b) +{ + b[0] = a[0]; + b[1] = a[1]; + b[2] = a[2]; +} +FORCEINLINE void VectorClear(vec_t* a) +{ + a[0] = a[1] = a[2] = 0; +} + +FORCEINLINE float VectorMaximum(const vec_t* v) +{ + return max(v[0], max(v[1], v[2])); +} + +FORCEINLINE float VectorMaximum(const Vector& v) +{ + return max(v.x, max(v.y, v.z)); +} + +FORCEINLINE void VectorScale(const float* in, vec_t scale, float* out) +{ + out[0] = in[0] * scale; + out[1] = in[1] * scale; + out[2] = in[2] * scale; +} + + +inline void VectorFill(vec_t* a, float b) +{ + a[0] = a[1] = a[2] = b; +} + +inline void VectorNegate(vec_t* a) +{ + a[0] = -a[0]; + a[1] = -a[1]; + a[2] = -a[2]; +} + + +#define Vector2Clear(x) {(x)[0]=(x)[1]=0;} +#define Vector2Negate(x) {(x)[0]=-((x)[0]);(x)[1]=-((x)[1]);} +#define Vector2Copy(a,b) {(b)[0]=(a)[0];(b)[1]=(a)[1];} +#define Vector2Subtract(a,b,c) {(c)[0]=(a)[0]-(b)[0];(c)[1]=(a)[1]-(b)[1];} +#define Vector2Add(a,b,c) {(c)[0]=(a)[0]+(b)[0];(c)[1]=(a)[1]+(b)[1];} +#define Vector2Scale(a,b,c) {(c)[0]=(b)*(a)[0];(c)[1]=(b)*(a)[1];} + +#define VECTOR_COPY( A, B ) do { (B)[0] = (A)[0]; (B)[1] = (A)[1]; (B)[2]=(A)[2]; } while(0) +#define DOT_PRODUCT( A, B ) ( (A)[0]*(B)[0] + (A)[1]*(B)[1] + (A)[2]*(B)[2] ) + +FORCEINLINE void VectorMAInline(const float* start, float scale, const float* direction, float* dest) +{ + dest[0] = start[0] + direction[0] * scale; + dest[1] = start[1] + direction[1] * scale; + dest[2] = start[2] + direction[2] * scale; +} + +FORCEINLINE void VectorMAInline(const Vector& start, float scale, const Vector& direction, Vector& dest) +{ + dest.x = start.x + direction.x * scale; + dest.y = start.y + direction.y * scale; + dest.z = start.z + direction.z * scale; +} + +FORCEINLINE void VectorMA(const Vector& start, float scale, const Vector& direction, Vector& dest) +{ + VectorMAInline(start, scale, direction, dest); +} + +FORCEINLINE void VectorMA(const float* start, float scale, const float* direction, float* dest) +{ + VectorMAInline(start, scale, direction, dest); +} + + +int VectorCompare(const float* v1, const float* v2); + +inline float VectorLength(const float* v) +{ + return FastSqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + FLT_EPSILON); +} + +void CrossProduct(const float* v1, const float* v2, float* cross); + +qboolean VectorsEqual(const float* v1, const float* v2); + +inline vec_t RoundInt(vec_t in) +{ + return floor(in + 0.5f); +} + +int Q_log2(int val); + +void inline SinCos(float radians, float* sine, float* cosine) +{ +#if defined( _X360 ) + XMScalarSinCos(sine, cosine, radians); +#elif defined( PLATFORM_WINDOWS_PC32 ) + _asm + { + fld DWORD PTR[radians] + fsincos + + mov edx, DWORD PTR[cosine] + mov eax, DWORD PTR[sine] + + fstp DWORD PTR[edx] + fstp DWORD PTR[eax] + } +#elif defined( PLATFORM_WINDOWS_PC64 ) + *sine = sin(radians); + *cosine = cos(radians); +#elif defined( POSIX ) + register double __cosr, __sinr; + __asm ("fsincos" : "=t" (__cosr), "=u" (__sinr) : "0" (radians)); + + *sine = __sinr; + *cosine = __cosr; +#endif +} + +#define SIN_TABLE_SIZE 256 +#define FTOIBIAS 12582912.f +extern float SinCosTable[SIN_TABLE_SIZE]; + +inline float TableCos(float theta) +{ + union + { + int i; + float f; + } ftmp; + + ftmp.f = theta * (float)(SIN_TABLE_SIZE / (2.0f * M_PI)) + (FTOIBIAS + (SIN_TABLE_SIZE / 4)); + return SinCosTable[ftmp.i & (SIN_TABLE_SIZE - 1)]; +} + +inline float TableSin(float theta) +{ + union + { + int i; + float f; + } ftmp; + + ftmp.f = theta * (float)(SIN_TABLE_SIZE / (2.0f * M_PI)) + FTOIBIAS; + return SinCosTable[ftmp.i & (SIN_TABLE_SIZE - 1)]; +} + +template +FORCEINLINE T Square(T const& a) +{ + return a * a; +} + + +FORCEINLINE uint SmallestPowerOfTwoGreaterOrEqual(uint x) +{ + x -= 1; + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + return x + 1; +} + +FORCEINLINE uint LargestPowerOfTwoLessThanOrEqual(uint x) +{ + if (x >= 0x80000000) + return 0x80000000; + + return SmallestPowerOfTwoGreaterOrEqual(x + 1) >> 1; +} + + +void FloorDivMod(double numer, double denom, int* quotient, int* rem); +int GreatestCommonDivisor(int i1, int i2); + +bool IsDenormal(const float& val); + +enum +{ + PITCH = 0, + YAW, + ROLL +}; + +void MatrixAngles(const matrix3x4_t& matrix, float* angles); +void MatrixVectors(const matrix3x4_t& matrix, Vector* pForward, Vector* pRight, Vector* pUp); +void VectorTransform(const float* in1, const matrix3x4_t& in2, float* out); +void VectorITransform(const float* in1, const matrix3x4_t& in2, float* out); +void VectorRotate(const float* in1, const matrix3x4_t& in2, float* out); +void VectorRotate(const Vector& in1, const QAngle& in2, Vector& out); +void VectorRotate(const Vector& in1, const Quaternion& in2, Vector& out); +void VectorIRotate(const float* in1, const matrix3x4_t& in2, float* out); + +#ifndef VECTOR_NO_SLOW_OPERATIONS + +QAngle TransformAnglesToLocalSpace(const QAngle& angles, const matrix3x4_t& parentMatrix); +QAngle TransformAnglesToWorldSpace(const QAngle& angles, const matrix3x4_t& parentMatrix); + +#endif + +void MatrixInitialize(matrix3x4_t& mat, const Vector& vecOrigin, const Vector& vecXAxis, const Vector& vecYAxis, const Vector& vecZAxis); +void MatrixCopy(const matrix3x4_t& in, matrix3x4_t& out); +void MatrixInvert(const matrix3x4_t& in, matrix3x4_t& out); + +bool MatricesAreEqual(const matrix3x4_t& src1, const matrix3x4_t& src2, float flTolerance = 1e-5); + +void MatrixGetColumn(const matrix3x4_t& in, int column, Vector& out); +void MatrixSetColumn(const Vector& in, int column, matrix3x4_t& out); + +inline void MatrixGetTranslation(const matrix3x4_t& in, Vector& out) +{ + MatrixGetColumn(in, 3, out); +} + +inline void MatrixSetTranslation(const Vector& in, matrix3x4_t& out) +{ + MatrixSetColumn(in, 3, out); +} + +void MatrixScaleBy(const float flScale, matrix3x4_t& out); +void MatrixScaleByZero(matrix3x4_t& out); + +void ConcatRotations(const matrix3x4_t& in1, const matrix3x4_t& in2, matrix3x4_t& out); +void ConcatTransforms(const matrix3x4_t& in1, const matrix3x4_t& in2, matrix3x4_t& out); + +inline void MatrixMultiply(const matrix3x4_t& in1, const matrix3x4_t& in2, matrix3x4_t& out) +{ + ConcatTransforms(in1, in2, out); +} + +void QuaternionSlerp(const Quaternion& p, const Quaternion& q, float t, Quaternion& qt); +void QuaternionSlerpNoAlign(const Quaternion& p, const Quaternion& q, float t, Quaternion& qt); +void QuaternionBlend(const Quaternion& p, const Quaternion& q, float t, Quaternion& qt); +void QuaternionBlendNoAlign(const Quaternion& p, const Quaternion& q, float t, Quaternion& qt); +void QuaternionIdentityBlend(const Quaternion& p, float t, Quaternion& qt); +float QuaternionAngleDiff(const Quaternion& p, const Quaternion& q); +void QuaternionScale(const Quaternion& p, float t, Quaternion& q); +void QuaternionAlign(const Quaternion& p, const Quaternion& q, Quaternion& qt); +float QuaternionDotProduct(const Quaternion& p, const Quaternion& q); +void QuaternionConjugate(const Quaternion& p, Quaternion& q); +void QuaternionInvert(const Quaternion& p, Quaternion& q); +float QuaternionNormalize(Quaternion& q); +void QuaternionAdd(const Quaternion& p, const Quaternion& q, Quaternion& qt); +void QuaternionMult(const Quaternion& p, const Quaternion& q, Quaternion& qt); +void QuaternionMatrix(const Quaternion& q, matrix3x4_t& matrix); +void QuaternionMatrix(const Quaternion& q, const Vector& pos, matrix3x4_t& matrix); +void QuaternionAngles(const Quaternion& q, QAngle& angles); +void AngleQuaternion(const QAngle& angles, Quaternion& qt); +void QuaternionAngles(const Quaternion& q, RadianEuler& angles); +void AngleQuaternion(RadianEuler const& angles, Quaternion& qt); +void QuaternionAxisAngle(const Quaternion& q, Vector& axis, float& angle); +void AxisAngleQuaternion(const Vector& axis, float angle, Quaternion& q); +void BasisToQuaternion(const Vector& vecForward, const Vector& vecRight, const Vector& vecUp, Quaternion& q); +void MatrixQuaternion(const matrix3x4_t& mat, Quaternion& q); + +inline float MatrixRowDotProduct(const matrix3x4_t& in1, int row, const Vector& in2) +{ + Assert((row >= 0) && (row < 3)); + return DotProduct(in1[row], in2.Base()); +} + +inline float MatrixColumnDotProduct(const matrix3x4_t& in1, int col, const Vector& in2) +{ + Assert((col >= 0) && (col < 4)); + return in1[0][col] * in2[0] + in1[1][col] * in2[1] + in1[2][col] * in2[2]; +} + +int __cdecl BoxOnPlaneSide(const float* emins, const float* emaxs, const cplane_t* plane); + +inline float anglemod(float a) +{ + a = (360.f / 65536) * ((int)(a * (65536.f / 360.0f)) & 65535); + return a; +} + +inline float RemapVal(float val, float A, float B, float C, float D) +{ + if (A == B) + return val >= B ? D : C; + return C + (D - C) * (val - A) / (B - A); +} + +inline float RemapValClamped(float val, float A, float B, float C, float D) +{ + if (A == B) + return val >= B ? D : C; + float cVal = (val - A) / (B - A); + cVal = clamp(cVal, 0.0f, 1.0f); + + return C + (D - C) * cVal; +} + +template +FORCEINLINE T Lerp(float flPercent, T const& A, T const& B) +{ + return A + (B - A) * flPercent; +} + +FORCEINLINE float Sqr(float f) +{ + return f * f; +} + +static inline float FLerp(float f1, float f2, float i1, float i2, float x) +{ + return f1 + (f2 - f1) * (x - i1) / (i2 - i1); +} + + +#ifndef VECTOR_NO_SLOW_OPERATIONS + +template<> FORCEINLINE QAngle Lerp(float flPercent, const QAngle& q1, const QAngle& q2) +{ + if (q1 == q2) + return q1; + + Quaternion src, dest; + + AngleQuaternion(q1, src); + AngleQuaternion(q2, dest); + + Quaternion result; + + QuaternionSlerp(src, dest, flPercent, result); + + QAngle output; + QuaternionAngles(result, output); + return output; +} + +#else + +#pragma error + +template<> FORCEINLINE QAngleByValue Lerp(float flPercent, const QAngleByValue& q1, const QAngleByValue& q2) +{ + if (q1 == q2) + return q1; + + Quaternion src, dest; + + AngleQuaternion(q1, src); + AngleQuaternion(q2, dest); + + Quaternion result; + + QuaternionSlerp(src, dest, flPercent, result); + + QAngleByValue output; + QuaternionAngles(result, output); + return output; +} + +#endif + + +template +FORCEINLINE void V_swap(T& x, T& y) +{ + T temp = x; + x = y; + y = temp; +} + +template FORCEINLINE T AVG(T a, T b) +{ + return (a + b) / 2; +} + +#define NELEMS(x) ARRAYSIZE(x) + +#define XYZ(v) (v).x,(v).y,(v).z + + +inline float Sign(float x) +{ + return (x < 0.0f) ? -1.0f : 1.0f; +} + +inline int ClampArrayBounds(int n, unsigned maxindex) +{ + unsigned int inrangemask = 0xFFFFFFFF + (((unsigned)n) > maxindex); + unsigned int lessthan0mask = 0xFFFFFFFF + (n >= 0); + + int result = (inrangemask & n); + + result |= ((~inrangemask) & (~lessthan0mask)) & maxindex; + + return result; +} + + +#define BOX_ON_PLANE_SIDE(emins, emaxs, p) \ + (((p)->type < 3)? \ + ( \ + ((p)->dist <= (emins)[(p)->type])? \ + 1 \ + : \ + ( \ + ((p)->dist >= (emaxs)[(p)->type])?\ + 2 \ + : \ + 3 \ + ) \ + ) \ + : \ + BoxOnPlaneSide( (emins), (emaxs), (p))) + +void AngleVectors(const QAngle& angles, Vector* forward); +void AngleVectors(const QAngle& angles, Vector* forward, Vector* right, Vector* up); +void AngleVectorsTranspose(const QAngle& angles, Vector* forward, Vector* right, Vector* up); +void AngleMatrix(const QAngle& angles, matrix3x4_t& mat); +void AngleMatrix(const QAngle& angles, const Vector& position, matrix3x4_t& mat); +void AngleMatrix(const RadianEuler& angles, matrix3x4_t& mat); +void AngleMatrix(RadianEuler const& angles, const Vector& position, matrix3x4_t& mat); +void AngleIMatrix(const QAngle& angles, matrix3x4_t& mat); +void AngleIMatrix(const QAngle& angles, const Vector& position, matrix3x4_t& mat); +void AngleIMatrix(const RadianEuler& angles, matrix3x4_t& mat); +void VectorAngles(const Vector& forward, QAngle& angles); +void VectorAngles(const Vector& forward, const Vector& pseudoup, QAngle& angles); +void VectorMatrix(const Vector& forward, matrix3x4_t& mat); +void VectorVectors(const Vector& forward, Vector& right, Vector& up); +void SetIdentityMatrix(matrix3x4_t& mat); +void SetScaleMatrix(float x, float y, float z, matrix3x4_t& dst); +void MatrixBuildRotationAboutAxis(const Vector& vAxisOfRot, float angleDegrees, matrix3x4_t& dst); + +inline void SetScaleMatrix(float flScale, matrix3x4_t& dst) +{ + SetScaleMatrix(flScale, flScale, flScale, dst); +} + +inline void SetScaleMatrix(const Vector& scale, matrix3x4_t& dst) +{ + SetScaleMatrix(scale.x, scale.y, scale.z, dst); +} + +void MatrixTranspose(matrix3x4_t& mat); +void MatrixTranspose(const matrix3x4_t& src, matrix3x4_t& dst); +void MatrixInverseTranspose(const matrix3x4_t& src, matrix3x4_t& dst); + +inline void PositionMatrix(const Vector& position, matrix3x4_t& mat) +{ + MatrixSetColumn(position, 3, mat); +} + +inline void MatrixPosition(const matrix3x4_t& matrix, Vector& position) +{ + MatrixGetColumn(matrix, 3, position); +} + +inline void VectorRotate(const Vector& in1, const matrix3x4_t& in2, Vector& out) +{ + VectorRotate(&in1.x, in2, &out.x); +} + +inline void VectorIRotate(const Vector& in1, const matrix3x4_t& in2, Vector& out) +{ + VectorIRotate(&in1.x, in2, &out.x); +} + +inline void MatrixAngles(const matrix3x4_t& matrix, QAngle& angles) +{ + MatrixAngles(matrix, &angles.x); +} + +inline void MatrixAngles(const matrix3x4_t& matrix, QAngle& angles, Vector& position) +{ + MatrixAngles(matrix, angles); + MatrixPosition(matrix, position); +} + +inline void MatrixAngles(const matrix3x4_t& matrix, RadianEuler& angles) +{ + MatrixAngles(matrix, &angles.x); + + angles.Init(DEG2RAD(angles.z), DEG2RAD(angles.x), DEG2RAD(angles.y)); +} + +void MatrixAngles(const matrix3x4_t& mat, RadianEuler& angles, Vector& position); + +void MatrixAngles(const matrix3x4_t& mat, Quaternion& q, Vector& position); + +inline int VectorCompare(const Vector& v1, const Vector& v2) +{ + return v1 == v2; +} + +inline void VectorTransform(const Vector& in1, const matrix3x4_t& in2, Vector& out) +{ + VectorTransform(&in1.x, in2, &out.x); +} + +inline void VectorITransform(const Vector& in1, const matrix3x4_t& in2, Vector& out) +{ + VectorITransform(&in1.x, in2, &out.x); +} + +inline int BoxOnPlaneSide(const Vector& emins, const Vector& emaxs, const cplane_t* plane) +{ + return BoxOnPlaneSide(&emins.x, &emaxs.x, plane); +} + +inline void VectorFill(Vector& a, float b) +{ + a[0] = a[1] = a[2] = b; +} + +inline void VectorNegate(Vector& a) +{ + a[0] = -a[0]; + a[1] = -a[1]; + a[2] = -a[2]; +} + +inline vec_t VectorAvg(Vector& a) +{ + return (a[0] + a[1] + a[2]) / 3; +} + +inline int FASTCALL BoxOnPlaneSide2(const Vector& emins, const Vector& emaxs, const cplane_t* p, float tolerance = 0.f) +{ + Vector corners[2]; + + if (p->normal[0] < 0) + { + corners[0][0] = emins[0]; + corners[1][0] = emaxs[0]; + } + else + { + corners[1][0] = emins[0]; + corners[0][0] = emaxs[0]; + } + + if (p->normal[1] < 0) + { + corners[0][1] = emins[1]; + corners[1][1] = emaxs[1]; + } + else + { + corners[1][1] = emins[1]; + corners[0][1] = emaxs[1]; + } + + if (p->normal[2] < 0) + { + corners[0][2] = emins[2]; + corners[1][2] = emaxs[2]; + } + else + { + corners[1][2] = emins[2]; + corners[0][2] = emaxs[2]; + } + + int sides = 0; + + float dist1 = DotProduct(p->normal, corners[0]) - p->dist; + if (dist1 >= tolerance) + sides = 1; + + float dist2 = DotProduct(p->normal, corners[1]) - p->dist; + if (dist2 < -tolerance) + sides |= 2; + + return sides; +} + +void ClearBounds(Vector& mins, Vector& maxs); +void AddPointToBounds(const Vector& v, Vector& mins, Vector& maxs); + +void BuildGammaTable(float gamma, float texGamma, float brightness, int overbright); + +inline float TexLightToLinear(int c, int exponent) +{ + extern float power2_n[256]; + Assert(exponent >= -128 && exponent <= 127); + return (float)c * power2_n[exponent + 128]; +} + + +int LinearToTexture(float f); +int LinearToScreenGamma(float f); +float TextureToLinear(int c); + +struct ColorRGBExp32 +{ + byte r, g, b; + signed char exponent; +}; + +void ColorRGBExp32ToVector(const ColorRGBExp32& in, Vector& out); +void VectorToColorRGBExp32(const Vector& v, ColorRGBExp32& c); + +bool SolveQuadratic(float a, float b, float c, float& root1, float& root2); + +bool SolveInverseQuadratic(float x1, float y1, float x2, float y2, float x3, float y3, float& a, float& b, float& c); + +bool SolveInverseQuadraticMonotonic(float x1, float y1, float x2, float y2, + float x3, float y3, float& a, float& b, float& c); + + + + +bool SolveInverseReciprocalQuadratic(float x1, float y1, float x2, float y2, float x3, float y3, float& a, float& b, float& c); + +void VectorYawRotate(const Vector& in, float flYaw, Vector& out); + + +float Bias(float x, float biasAmt); + + +float Gain(float x, float biasAmt); + + +float SmoothCurve(float x); + + +float SmoothCurve_Tweak(float x, float flPeakPos = 0.5, float flPeakSharpness = 0.5); + + +inline float ExponentialDecay(float halflife, float dt) +{ + return expf(-0.69314718f / halflife * dt); +} + +inline float ExponentialDecay(float decayTo, float decayTime, float dt) +{ + return expf(logf(decayTo) / decayTime * dt); +} + +inline float ExponentialDecayIntegral(float decayTo, float decayTime, float dt) +{ + return (powf(decayTo, dt / decayTime) * decayTime - decayTime) / logf(decayTo); +} + +inline float SimpleSpline(float value) +{ + float valueSquared = value * value; + + return (3 * valueSquared - 2 * valueSquared * value); +} + +inline float SimpleSplineRemapVal(float val, float A, float B, float C, float D) +{ + if (A == B) + return val >= B ? D : C; + float cVal = (val - A) / (B - A); + return C + (D - C) * SimpleSpline(cVal); +} + +inline float SimpleSplineRemapValClamped(float val, float A, float B, float C, float D) +{ + if (A == B) + return val >= B ? D : C; + float cVal = (val - A) / (B - A); + cVal = clamp(cVal, 0.0f, 1.0f); + return C + (D - C) * SimpleSpline(cVal); +} + +FORCEINLINE int RoundFloatToInt(float f) +{ +#if defined(__i386__) || defined(_M_IX86) || defined( PLATFORM_WINDOWS_PC64 ) + return _mm_cvtss_si32(_mm_load_ss(&f)); +#elif defined( _X360 ) +#ifdef Assert + Assert(IsFPUControlWordSet()); +#endif + union + { + double flResult; + int pResult[2]; + }; + flResult = __fctiw(f); + return pResult[1]; +#else +#error Unknown architecture +#endif +} + +FORCEINLINE unsigned char RoundFloatToByte(float f) +{ + int nResult = RoundFloatToInt(f); +#ifdef Assert + Assert((nResult & ~0xFF) == 0); +#endif + return (unsigned char)nResult; +} + +FORCEINLINE unsigned long RoundFloatToUnsignedLong(float f) +{ +#if defined( _X360 ) +#ifdef Assert + Assert(IsFPUControlWordSet()); +#endif + union + { + double flResult; + int pIntResult[2]; + unsigned long pResult[2]; + }; + flResult = __fctiw(f); + Assert(pIntResult[1] >= 0); + return pResult[1]; +#else + +#if defined( PLATFORM_WINDOWS_PC64 ) + uint nRet = (uint)f; + if (nRet & 1) + { + if ((f - floor(f) >= 0.5)) + { + nRet++; + } + } + else + { + if ((f - floor(f) > 0.5)) + { + nRet++; + } + } + return nRet; +#else + unsigned char nResult[8]; + +#if defined( _WIN32 ) + __asm + { + fld f + fistp qword ptr nResult + } +#elif POSIX + __asm __volatile__( + "fistpl %0;": "=m" (nResult) : "t" (f) : "st" + ); +#endif + + return *((unsigned long*)nResult); +#endif +#endif +} + +FORCEINLINE bool IsIntegralValue(float flValue, float flTolerance = 0.001f) +{ + return fabs(RoundFloatToInt(flValue) - flValue) < flTolerance; +} + +FORCEINLINE int Float2Int(float a) +{ +#if defined( _X360 ) + union + { + double flResult; + int pResult[2]; + }; + flResult = __fctiwz(a); + return pResult[1]; +#else + return (int)a; +#endif +} + +inline int Floor2Int(float a) +{ + int RetVal; +#if defined( __i386__ ) + __m128 a128 = _mm_set_ss(a); + RetVal = _mm_cvtss_si32(a128); + __m128 rounded128 = _mm_cvt_si2ss(_mm_setzero_ps(), RetVal); + RetVal -= _mm_comigt_ss(rounded128, a128); +#else + RetVal = static_cast(floor(a)); +#endif + return RetVal; +} + +FORCEINLINE unsigned int FastFToC(float c) +{ +#if defined( __i386__ ) + union { float f; int i; } convert = { c * 255.0f + (float)(1 << 23) }; + return convert.i & 255; +#else + return Float2Int(c * 255.0f); +#endif +} + +FORCEINLINE int FastFloatToSmallInt(float c) +{ +#if defined( __i386__ ) + union { float f; int i; } convert = { c + (float)(3 << 22) }; + return (convert.i & ((1 << 23) - 1)) - (1 << 22); +#else + return Float2Int(c); +#endif +} + +inline float ClampToMsec(float in) +{ + int msec = Floor2Int(in * 1000.0f + 0.5f); + return 0.001f * msec; +} + +inline int Ceil2Int(float a) +{ + int RetVal; +#if defined( __i386__ ) + __m128 a128 = _mm_load_ss(&a); + RetVal = _mm_cvtss_si32(a128); + __m128 rounded128 = _mm_cvt_si2ss(_mm_setzero_ps(), RetVal); + RetVal += _mm_comilt_ss(rounded128, a128); +#else + RetVal = static_cast(ceil(a)); +#endif + return RetVal; +} + + +#define TriArea2D( A, B, C ) \ + ( 0.5f * ( ( B.x - A.x ) * ( C.y - A.y ) - ( B.y - A.y ) * ( C.x - A.x ) ) ) + +#define TriArea2DTimesTwo( A, B, C ) \ + ( ( ( B.x - A.x ) * ( C.y - A.y ) - ( B.y - A.y ) * ( C.x - A.x ) ) ) + + +inline void GetBarycentricCoords2D( + Vector2D const& A, + Vector2D const& B, + Vector2D const& C, + Vector2D const& pt, + float bcCoords[3]) +{ + float invTriArea = 1.0f / TriArea2DTimesTwo(A, B, C); + + bcCoords[0] = TriArea2DTimesTwo(B, C, pt) * invTriArea; + bcCoords[1] = TriArea2DTimesTwo(C, A, pt) * invTriArea; + bcCoords[2] = TriArea2DTimesTwo(A, B, pt) * invTriArea; +} + + +inline bool QuickBoxSphereTest( + const Vector& vOrigin, + float flRadius, + const Vector& bbMin, + const Vector& bbMax) +{ + return vOrigin.x - flRadius < bbMax.x&& vOrigin.x + flRadius > bbMin.x && + vOrigin.y - flRadius < bbMax.y&& vOrigin.y + flRadius > bbMin.y && + vOrigin.z - flRadius < bbMax.z&& vOrigin.z + flRadius > bbMin.z; +} + + +inline bool QuickBoxIntersectTest( + const Vector& vBox1Min, + const Vector& vBox1Max, + const Vector& vBox2Min, + const Vector& vBox2Max) +{ + return + vBox1Min.x < vBox2Max.x&& vBox1Max.x > vBox2Min.x && + vBox1Min.y < vBox2Max.y&& vBox1Max.y > vBox2Min.y && + vBox1Min.z < vBox2Max.z&& vBox1Max.z > vBox2Min.z; +} + + +extern float GammaToLinearFullRange(float gamma); +extern float LinearToGammaFullRange(float linear); +extern float GammaToLinear(float gamma); +extern float LinearToGamma(float linear); + +extern float SrgbGammaToLinear(float flSrgbGammaValue); +extern float SrgbLinearToGamma(float flLinearValue); +extern float X360GammaToLinear(float fl360GammaValue); +extern float X360LinearToGamma(float flLinearValue); +extern float SrgbGammaTo360Gamma(float flSrgbGammaValue); + +FORCEINLINE float LinearToVertexLight(float f) +{ + extern float lineartovertex[4096]; + + int i = RoundFloatToInt(f * 1024.f); + + if ((unsigned)i > 4095) + { + if (i < 0) + i = 0; + else + i = 4095; + } + + return lineartovertex[i]; +} + + +FORCEINLINE unsigned char LinearToLightmap(float f) +{ + extern unsigned char lineartolightmap[4096]; + + int i = RoundFloatToInt(f * 1024.f); + + if ((unsigned)i > 4095) + { + if (i < 0) + i = 0; + else + i = 4095; + } + + return lineartolightmap[i]; +} + +FORCEINLINE void ColorClamp(Vector& color) +{ + float maxc = max(color.x, max(color.y, color.z)); + if (maxc > 1.0f) + { + float ooMax = 1.0f / maxc; + color.x *= ooMax; + color.y *= ooMax; + color.z *= ooMax; + } + + if (color[0] < 0.f) color[0] = 0.f; + if (color[1] < 0.f) color[1] = 0.f; + if (color[2] < 0.f) color[2] = 0.f; +} + +inline void ColorClampTruncate(Vector& color) +{ + if (color[0] > 1.0f) color[0] = 1.0f; else if (color[0] < 0.0f) color[0] = 0.0f; + if (color[1] > 1.0f) color[1] = 1.0f; else if (color[1] < 0.0f) color[1] = 0.0f; + if (color[2] > 1.0f) color[2] = 1.0f; else if (color[2] < 0.0f) color[2] = 0.0f; +} + +void Catmull_Rom_Spline( + const Vector& p1, + const Vector& p2, + const Vector& p3, + const Vector& p4, + float t, + Vector& output); + +void Catmull_Rom_Spline_Tangent( + const Vector& p1, + const Vector& p2, + const Vector& p3, + const Vector& p4, + float t, + Vector& output); + +void Catmull_Rom_Spline_Integral( + const Vector& p1, + const Vector& p2, + const Vector& p3, + const Vector& p4, + float t, + Vector& output); + +void Catmull_Rom_Spline_Integral( + const Vector& p1, + const Vector& p2, + const Vector& p3, + const Vector& p4, + Vector& output); + +void Catmull_Rom_Spline_Normalize( + const Vector& p1, + const Vector& p2, + const Vector& p3, + const Vector& p4, + float t, + Vector& output); + +void Catmull_Rom_Spline_Integral_Normalize( + const Vector& p1, + const Vector& p2, + const Vector& p3, + const Vector& p4, + float t, + Vector& output); + +void Catmull_Rom_Spline_NormalizeX( + const Vector& p1, + const Vector& p2, + const Vector& p3, + const Vector& p4, + float t, + Vector& output); + +void Catmull_Rom_Spline_NormalizeX( + const Vector& p1, + const Vector& p2, + const Vector& p3, + const Vector& p4, + float t, + Vector& output); + +void Hermite_Spline( + const Vector& p1, + const Vector& p2, + const Vector& d1, + const Vector& d2, + float t, + Vector& output); + +float Hermite_Spline( + float p1, + float p2, + float d1, + float d2, + float t); + +void Hermite_Spline( + const Vector& p0, + const Vector& p1, + const Vector& p2, + float t, + Vector& output); + +float Hermite_Spline( + float p0, + float p1, + float p2, + float t); + + +void Hermite_SplineBasis(float t, float basis[]); + +void Hermite_Spline( + const Quaternion& q0, + const Quaternion& q1, + const Quaternion& q2, + float t, + Quaternion& output); + + +void Kochanek_Bartels_Spline( + float tension, + float bias, + float continuity, + const Vector& p1, + const Vector& p2, + const Vector& p3, + const Vector& p4, + float t, + Vector& output); + +void Kochanek_Bartels_Spline_NormalizeX( + float tension, + float bias, + float continuity, + const Vector& p1, + const Vector& p2, + const Vector& p3, + const Vector& p4, + float t, + Vector& output); + +void Cubic_Spline( + const Vector& p1, + const Vector& p2, + const Vector& p3, + const Vector& p4, + float t, + Vector& output); + +void Cubic_Spline_NormalizeX( + const Vector& p1, + const Vector& p2, + const Vector& p3, + const Vector& p4, + float t, + Vector& output); + +void BSpline( + const Vector& p1, + const Vector& p2, + const Vector& p3, + const Vector& p4, + float t, + Vector& output); + +void BSpline_NormalizeX( + const Vector& p1, + const Vector& p2, + const Vector& p3, + const Vector& p4, + float t, + Vector& output); + +void Parabolic_Spline( + const Vector& p1, + const Vector& p2, + const Vector& p3, + const Vector& p4, + float t, + Vector& output); + +void Parabolic_Spline_NormalizeX( + const Vector& p1, + const Vector& p2, + const Vector& p3, + const Vector& p4, + float t, + Vector& output); + +FORCEINLINE float QuinticInterpolatingPolynomial(float t) +{ + return t * t * t * (t * (t * 6.0 - 15.0) + 10.0); +} + +void GetInterpolationData(float const* pKnotPositions, + float const* pKnotValues, + int nNumValuesinList, + int nInterpolationRange, + float flPositionToInterpolateAt, + bool bWrap, + float* pValueA, + float* pValueB, + float* pInterpolationValue); + +float RangeCompressor(float flValue, float flMin, float flMax, float flBase); + +float CalcSqrDistanceToAABB(const Vector& mins, const Vector& maxs, const Vector& point); +void CalcClosestPointOnAABB(const Vector& mins, const Vector& maxs, const Vector& point, Vector& closestOut); +void CalcSqrDistAndClosestPointOnAABB(const Vector& mins, const Vector& maxs, const Vector& point, Vector& closestOut, float& distSqrOut); + +inline float CalcDistanceToAABB(const Vector& mins, const Vector& maxs, const Vector& point) +{ + float flDistSqr = CalcSqrDistanceToAABB(mins, maxs, point); + return sqrt(flDistSqr); +} + +void CalcClosestPointOnLine(const Vector& P, const Vector& vLineA, const Vector& vLineB, Vector& vClosest, float* t = 0); +float CalcDistanceToLine(const Vector& P, const Vector& vLineA, const Vector& vLineB, float* t = 0); +float CalcDistanceSqrToLine(const Vector& P, const Vector& vLineA, const Vector& vLineB, float* t = 0); + +void CalcClosestPointOnLineSegment(const Vector& P, const Vector& vLineA, const Vector& vLineB, Vector& vClosest, float* t = 0); +float CalcDistanceToLineSegment(const Vector& P, const Vector& vLineA, const Vector& vLineB, float* t = 0); +float CalcDistanceSqrToLineSegment(const Vector& P, const Vector& vLineA, const Vector& vLineB, float* t = 0); + +bool CalcLineToLineIntersectionSegment( + const Vector& p1, const Vector& p2, const Vector& p3, const Vector& p4, Vector* s1, Vector* s2, + float* t1, float* t2); + +void CalcClosestPointOnLine2D(Vector2D const& P, Vector2D const& vLineA, Vector2D const& vLineB, Vector2D& vClosest, float* t = 0); +float CalcDistanceToLine2D(Vector2D const& P, Vector2D const& vLineA, Vector2D const& vLineB, float* t = 0); +float CalcDistanceSqrToLine2D(Vector2D const& P, Vector2D const& vLineA, Vector2D const& vLineB, float* t = 0); +void CalcClosestPointOnLineSegment2D(Vector2D const& P, Vector2D const& vLineA, Vector2D const& vLineB, Vector2D& vClosest, float* t = 0); +float CalcDistanceToLineSegment2D(Vector2D const& P, Vector2D const& vLineA, Vector2D const& vLineB, float* t = 0); +float CalcDistanceSqrToLineSegment2D(Vector2D const& P, Vector2D const& vLineA, Vector2D const& vLineB, float* t = 0); + +void MathLib_Init(float gamma = 2.2f, float texGamma = 2.2f, float brightness = 0.0f, int overbright = 2.0f, bool bAllow3DNow = true, bool bAllowSSE = true, bool bAllowSSE2 = true, bool bAllowMMX = true); +bool MathLib_3DNowEnabled(void); +bool MathLib_MMXEnabled(void); +bool MathLib_SSEEnabled(void); +bool MathLib_SSE2Enabled(void); + +float Approach(float target, float value, float speed); +float ApproachAngle(float target, float value, float speed); +float AngleDiff(float destAngle, float srcAngle); +float AngleDistance(float next, float cur); +float AngleNormalize(float angle); + +float AngleNormalizePositive(float angle); + +bool AnglesAreEqual(float a, float b, float tolerance = 0.0f); + + +void RotationDeltaAxisAngle(const QAngle& srcAngles, const QAngle& destAngles, Vector& deltaAxis, float& deltaAngle); +void RotationDelta(const QAngle& srcAngles, const QAngle& destAngles, QAngle* out); + +void ComputeTrianglePlane(const Vector& v1, const Vector& v2, const Vector& v3, Vector& normal, float& intercept); +int PolyFromPlane(Vector* outVerts, const Vector& normal, float dist, float fHalfScale = 9000.0f); +int ClipPolyToPlane(Vector* inVerts, int vertCount, Vector* outVerts, const Vector& normal, float dist, float fOnPlaneEpsilon = 0.1f); +int ClipPolyToPlane_Precise(double* inVerts, int vertCount, double* outVerts, const double* normal, double dist, double fOnPlaneEpsilon = 0.1); + +void CalcTriangleTangentSpace(const Vector& p0, const Vector& p1, const Vector& p2, + const Vector2D& t0, const Vector2D& t1, const Vector2D& t2, + Vector& sVect, Vector& tVect); + +void TransformAABB(const matrix3x4_t& in1, const Vector& vecMinsIn, const Vector& vecMaxsIn, Vector& vecMinsOut, Vector& vecMaxsOut); + +void ITransformAABB(const matrix3x4_t& in1, const Vector& vecMinsIn, const Vector& vecMaxsIn, Vector& vecMinsOut, Vector& vecMaxsOut); + +void RotateAABB(const matrix3x4_t& in1, const Vector& vecMinsIn, const Vector& vecMaxsIn, Vector& vecMinsOut, Vector& vecMaxsOut); + +void IRotateAABB(const matrix3x4_t& in1, const Vector& vecMinsIn, const Vector& vecMaxsIn, Vector& vecMinsOut, Vector& vecMaxsOut); + +inline void MatrixTransformPlane(const matrix3x4_t& src, const cplane_t& inPlane, cplane_t& outPlane) +{ + VectorRotate(inPlane.normal, src, outPlane.normal); + outPlane.dist = inPlane.dist * DotProduct(outPlane.normal, outPlane.normal); + outPlane.dist += outPlane.normal.x * src[0][3] + outPlane.normal.y * src[1][3] + outPlane.normal.z * src[2][3]; +} + +inline void MatrixITransformPlane(const matrix3x4_t& src, const cplane_t& inPlane, cplane_t& outPlane) +{ + Vector vecTranslation; + MatrixGetColumn(src, 3, vecTranslation); + + Vector vecInvTranslation; + VectorIRotate(vecTranslation, src, vecInvTranslation); + + VectorIRotate(inPlane.normal, src, outPlane.normal); + outPlane.dist = inPlane.dist * DotProduct(outPlane.normal, outPlane.normal); + outPlane.dist -= outPlane.normal.x * vecInvTranslation[0] + outPlane.normal.y * vecInvTranslation[1] + outPlane.normal.z * vecInvTranslation[2]; +} + +int CeilPow2(int in); +int FloorPow2(int in); + +FORCEINLINE float* UnpackNormal_HEND3N(const unsigned int* pPackedNormal, float* pNormal) +{ + int temp[3]; + temp[0] = ((*pPackedNormal >> 0L) & 0x7ff); + if (temp[0] & 0x400) + { + temp[0] = 2048 - temp[0]; + } + temp[1] = ((*pPackedNormal >> 11L) & 0x7ff); + if (temp[1] & 0x400) + { + temp[1] = 2048 - temp[1]; + } + temp[2] = ((*pPackedNormal >> 22L) & 0x3ff); + if (temp[2] & 0x200) + { + temp[2] = 1024 - temp[2]; + } + pNormal[0] = (float)temp[0] * 1.0f / 1023.0f; + pNormal[1] = (float)temp[1] * 1.0f / 1023.0f; + pNormal[2] = (float)temp[2] * 1.0f / 511.0f; + return pNormal; +} + +FORCEINLINE unsigned int* PackNormal_HEND3N(const float* pNormal, unsigned int* pPackedNormal) +{ + int temp[3]; + + temp[0] = Float2Int(pNormal[0] * 1023.0f); + temp[1] = Float2Int(pNormal[1] * 1023.0f); + temp[2] = Float2Int(pNormal[2] * 511.0f); + + Assert(temp[0] >= -1023 && temp[0] <= 1023); + Assert(temp[1] >= -1023 && temp[1] <= 1023); + Assert(temp[2] >= -511 && temp[2] <= 511); + + *pPackedNormal = ((temp[2] & 0x3ff) << 22L) | + ((temp[1] & 0x7ff) << 11L) | + ((temp[0] & 0x7ff) << 0L); + return pPackedNormal; +} + +FORCEINLINE unsigned int* PackNormal_HEND3N(float nx, float ny, float nz, unsigned int* pPackedNormal) +{ + int temp[3]; + + temp[0] = Float2Int(nx * 1023.0f); + temp[1] = Float2Int(ny * 1023.0f); + temp[2] = Float2Int(nz * 511.0f); + + Assert(temp[0] >= -1023 && temp[0] <= 1023); + Assert(temp[1] >= -1023 && temp[1] <= 1023); + Assert(temp[2] >= -511 && temp[2] <= 511); + + *pPackedNormal = ((temp[2] & 0x3ff) << 22L) | + ((temp[1] & 0x7ff) << 11L) | + ((temp[0] & 0x7ff) << 0L); + return pPackedNormal; +} + +FORCEINLINE float* UnpackNormal_SHORT2(const unsigned int* pPackedNormal, float* pNormal, bool bIsTangent = FALSE) +{ + short iX = (*pPackedNormal & 0x0000FFFF); + short iY = (*pPackedNormal & 0xFFFF0000) >> 16; + + float zSign = +1; + if (iX < 0) + { + zSign = -1; + iX = -iX; + } + float tSign = +1; + if (iY < 0) + { + tSign = -1; + iY = -iY; + } + + pNormal[0] = (iX - 16384.0f) / 16384.0f; + pNormal[1] = (iY - 16384.0f) / 16384.0f; + pNormal[2] = zSign * sqrtf(1.0f - (pNormal[0] * pNormal[0] + pNormal[1] * pNormal[1])); + if (bIsTangent) + { + pNormal[3] = tSign; + } + + return pNormal; +} + +FORCEINLINE unsigned int* PackNormal_SHORT2(float nx, float ny, float nz, unsigned int* pPackedNormal, float binormalSign = +1.0f) +{ + nx += 1; + ny += 1; + nx *= 16384.0f; + ny *= 16384.0f; + + nx = max(nx, 1.0f); + ny = max(ny, 1.0f); + nx = min(nx, 32767.0f); + ny = min(ny, 32767.0f); + + if (nz < 0.0f) + nx = -nx; + + ny *= binormalSign; + + short sX = (short)nx; + short sY = (short)ny; + + *pPackedNormal = (sX & 0x0000FFFF) | (sY << 16); + + return pPackedNormal; +} + +FORCEINLINE unsigned int* PackNormal_SHORT2(const float* pNormal, unsigned int* pPackedNormal, float binormalSign = +1.0f) +{ + return PackNormal_SHORT2(pNormal[0], pNormal[1], pNormal[2], pPackedNormal, binormalSign); +} + +FORCEINLINE float* UnpackNormal_UBYTE4(const unsigned int* pPackedNormal, float* pNormal, bool bIsTangent = FALSE) +{ + unsigned char cX, cY; + if (bIsTangent) + { + cX = *pPackedNormal >> 16; + cY = *pPackedNormal >> 24; + } + else + { + cX = *pPackedNormal >> 0; + cY = *pPackedNormal >> 8; + } + + float x = cX - 128.0f; + float y = cY - 128.0f; + float z; + + float zSignBit = x < 0 ? 1.0f : 0.0f; + float tSignBit = y < 0 ? 1.0f : 0.0f; + float zSign = -(2 * zSignBit - 1); + float tSign = -(2 * tSignBit - 1); + + x = x * zSign - zSignBit; + y = y * tSign - tSignBit; + x = x - 64; + y = y - 64; + + float xSignBit = x < 0 ? 1.0f : 0.0f; + float ySignBit = y < 0 ? 1.0f : 0.0f; + float xSign = -(2 * xSignBit - 1); + float ySign = -(2 * ySignBit - 1); + + x = (x * xSign - xSignBit) / 63.0f; + y = (y * ySign - ySignBit) / 63.0f; + z = 1.0f - x - y; + + float oolen = 1.0f / sqrt(x * x + y * y + z * z); + x *= oolen * xSign; + y *= oolen * ySign; + z *= oolen * zSign; + + pNormal[0] = x; + pNormal[1] = y; + pNormal[2] = z; + if (bIsTangent) + { + pNormal[3] = tSign; + } + + return pNormal; +} + +FORCEINLINE unsigned int* PackNormal_UBYTE4(float nx, float ny, float nz, unsigned int* pPackedNormal, bool bIsTangent = false, float binormalSign = +1.0f) +{ + float xSign = nx < 0.0f ? -1.0f : 1.0f; + float ySign = ny < 0.0f ? -1.0f : 1.0f; + float zSign = nz < 0.0f ? -1.0f : 1.0f; + float tSign = binormalSign; + Assert((binormalSign == +1.0f) || (binormalSign == -1.0f)); + + float xSignBit = 0.5f * (1 - xSign); + float ySignBit = 0.5f * (1 - ySign); + float zSignBit = 0.5f * (1 - zSign); + float tSignBit = 0.5f * (1 - binormalSign); + + float absX = xSign * nx; + float absY = ySign * ny; + float absZ = zSign * nz; + + float xbits = absX / (absX + absY + absZ); + float ybits = absY / (absX + absY + absZ); + + xbits *= 63; + ybits *= 63; + + xbits = xbits * xSign - xSignBit; + ybits = ybits * ySign - ySignBit; + xbits += 64.0f; + ybits += 64.0f; + + xbits = xbits * zSign - zSignBit; + ybits = ybits * tSign - tSignBit; + + xbits += 128.0f; + ybits += 128.0f; + + unsigned char cX = (unsigned char)xbits; + unsigned char cY = (unsigned char)ybits; + + if (!bIsTangent) + *pPackedNormal = (cX << 0) | (cY << 8); + else + *pPackedNormal = (cX << 16) | (cY << 24); + + return pPackedNormal; +} + +FORCEINLINE unsigned int* PackNormal_UBYTE4(const float* pNormal, unsigned int* pPackedNormal, bool bIsTangent = false, float binormalSign = +1.0f) +{ + return PackNormal_UBYTE4(pNormal[0], pNormal[1], pNormal[2], pPackedNormal, bIsTangent, binormalSign); +} + + +void RGBtoHSV(const Vector& rgb, Vector& hsv); + + +void HSVtoRGB(const Vector& hsv, Vector& rgb); + + +float FastLog2(float i); +float FastPow2(float i); +float FastPow(float a, float b); +float FastPow10(float i); + +inline bool CloseEnough(float a, float b, float epsilon = EQUAL_EPSILON) +{ + return fabs(a - b) <= epsilon; +} + +inline bool CloseEnough(const Vector& a, const Vector& b, float epsilon = EQUAL_EPSILON) +{ + return fabs(a.x - b.x) <= epsilon && + fabs(a.y - b.y) <= epsilon && + fabs(a.z - b.z) <= epsilon; +} + +bool AlmostEqual(float a, float b, int maxUlps = 10); + +inline bool AlmostEqual(const Vector& a, const Vector& b, int maxUlps = 10) +{ + return AlmostEqual(a.x, b.x, maxUlps) && + AlmostEqual(a.y, b.y, maxUlps) && + AlmostEqual(a.z, b.z, maxUlps); +} + + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/mem.h b/SpyCustom/sdk/mem.h new file mode 100644 index 0000000..fc1ae45 --- /dev/null +++ b/SpyCustom/sdk/mem.h @@ -0,0 +1,40 @@ +#ifndef TIER0_MEM_H +#define TIER0_MEM_H + +#ifdef _WIN32 +#pragma once +#endif + +#include +#ifdef LINUX +#undef offsetof +#define offsetof(s,m) (size_t)&(((s *)0)->m) +#endif + +#include "platform.h" + +#if !defined(STATIC_TIER0) && !defined(_STATIC_LINKED) + +#ifdef TIER0_DLL_EXPORT +# define MEM_INTERFACE DLL_EXPORT +#else +# define MEM_INTERFACE DLL_IMPORT +#endif + +#else + +#define MEM_INTERFACE extern + +#endif + + + +MEM_INTERFACE void* MemAllocScratch(int nMemSize); +MEM_INTERFACE void MemFreeScratch(); + +#ifdef _LINUX +MEM_INTERFACE void ZeroMemory(void* mem, size_t length); +#endif + + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/memalloc.h b/SpyCustom/sdk/memalloc.h new file mode 100644 index 0000000..a3463cc --- /dev/null +++ b/SpyCustom/sdk/memalloc.h @@ -0,0 +1,567 @@ +#ifndef TIER0_MEMALLOC_H +#define TIER0_MEMALLOC_H + +#ifdef _WIN32 +#pragma once +#endif + +#ifndef POSIX +#endif + +#if defined( _MEMTEST ) +#ifdef _WIN32 +#define USE_MEM_DEBUG 1 +#endif +#endif + +#define MEM_DEBUG_CLASSNAME 1 + +#include +#if defined( OSX ) +#include +#endif + +#include "mem.h" + +#if !defined(STEAM) && !defined(NO_MALLOC_OVERRIDE) + +struct _CrtMemState; + +#define MEMALLOC_VERSION 1 + +typedef size_t(*MemAllocFailHandler_t)(size_t); + +class IMemAlloc +{ +public: + virtual void* Alloc(size_t nSize) = 0; + virtual void* Realloc(void* pMem, size_t nSize) = 0; + virtual void Free(void* pMem) = 0; + virtual void* Expand_NoLongerSupported(void* pMem, size_t nSize) = 0; + + virtual void* Alloc(size_t nSize, const char* pFileName, int nLine) = 0; + virtual void* Realloc(void* pMem, size_t nSize, const char* pFileName, int nLine) = 0; + virtual void Free(void* pMem, const char* pFileName, int nLine) = 0; + virtual void* Expand_NoLongerSupported(void* pMem, size_t nSize, const char* pFileName, int nLine) = 0; + + virtual size_t GetSize(void* pMem) = 0; + + virtual void PushAllocDbgInfo(const char* pFileName, int nLine) = 0; + virtual void PopAllocDbgInfo() = 0; + + virtual long CrtSetBreakAlloc(long lNewBreakAlloc) = 0; + virtual int CrtSetReportMode(int nReportType, int nReportMode) = 0; + virtual int CrtIsValidHeapPointer(const void* pMem) = 0; + virtual int CrtIsValidPointer(const void* pMem, unsigned int size, int access) = 0; + virtual int CrtCheckMemory(void) = 0; + virtual int CrtSetDbgFlag(int nNewFlag) = 0; + virtual void CrtMemCheckpoint(_CrtMemState* pState) = 0; + + virtual void DumpStats() = 0; + virtual void DumpStatsFileBase(char const* pchFileBase) = 0; + + virtual void* CrtSetReportFile(int nRptType, void* hFile) = 0; + virtual void* CrtSetReportHook(void* pfnNewHook) = 0; + virtual int CrtDbgReport(int nRptType, const char* szFile, + int nLine, const char* szModule, const char* pMsg) = 0; + + virtual int heapchk() = 0; + + virtual bool IsDebugHeap() = 0; + + virtual void GetActualDbgInfo(const char*& pFileName, int& nLine) = 0; + virtual void RegisterAllocation(const char* pFileName, int nLine, int nLogicalSize, int nActualSize, unsigned nTime) = 0; + virtual void RegisterDeallocation(const char* pFileName, int nLine, int nLogicalSize, int nActualSize, unsigned nTime) = 0; + + virtual int GetVersion() = 0; + + virtual void CompactHeap() = 0; + + virtual MemAllocFailHandler_t SetAllocFailHandler(MemAllocFailHandler_t pfnMemAllocFailHandler) = 0; + + virtual void DumpBlockStats(void*) = 0; + +#if defined( _MEMTEST ) + virtual void SetStatsExtraInfo(const char* pMapName, const char* pComment) = 0; +#endif + + virtual size_t MemoryAllocFailed() = 0; + + virtual uint32 GetDebugInfoSize() = 0; + virtual void SaveDebugInfo(void* pvDebugInfo) = 0; + virtual void RestoreDebugInfo(const void* pvDebugInfo) = 0; + virtual void InitDebugInfo(void* pvDebugInfo, const char* pchRootFileName, int nLine) = 0; + + virtual void GlobalMemoryStatus(size_t* pUsedMemory, size_t* pFreeMemory) = 0; +}; + +MEM_INTERFACE IMemAlloc* g_pMemAlloc; + +#ifdef MEMALLOC_REGIONS +#ifndef MEMALLOC_REGION +#define MEMALLOC_REGION 0 +#endif +inline void* MemAlloc_Alloc(size_t nSize) +{ + return g_pMemAlloc->RegionAlloc(MEMALLOC_REGION, nSize); +} + +inline void* MemAlloc_Alloc(size_t nSize, const char* pFileName, int nLine) +{ + return g_pMemAlloc->RegionAlloc(MEMALLOC_REGION, nSize, pFileName, nLine); +} +#else +#undef MEMALLOC_REGION +inline void* MemAlloc_Alloc(size_t nSize) +{ + return g_pMemAlloc->Alloc(nSize); +} + +inline void* MemAlloc_Alloc(size_t nSize, const char* pFileName, int nLine) +{ + return g_pMemAlloc->Alloc(nSize, pFileName, nLine); +} +#endif +inline void MemAlloc_Free(void* ptr) +{ + g_pMemAlloc->Free(ptr); +} +inline void MemAlloc_Free(void* ptr, const char* pFileName, int nLine) +{ + g_pMemAlloc->Free(ptr, pFileName, nLine); +} + +inline bool ValueIsPowerOfTwo(size_t value) +{ + return (value & (value - 1)) == 0; +} + +inline void* MemAlloc_AllocAligned(size_t size, size_t align) +{ + unsigned char* pAlloc, * pResult; + + if (!IsPowerOfTwo(align)) + return NULL; + + align = (align > sizeof(void*) ? align : sizeof(void*)) - 1; + + if ((pAlloc = (unsigned char*)g_pMemAlloc->Alloc(sizeof(void*) + align + size)) == (unsigned char*)NULL) + return NULL; + + pResult = (unsigned char*)((size_t)(pAlloc + sizeof(void*) + align) & ~align); + ((unsigned char**)(pResult))[-1] = pAlloc; + + return (void*)pResult; +} + +inline void* MemAlloc_AllocAligned(size_t size, size_t align, const char* pszFile, int nLine) +{ + unsigned char* pAlloc, * pResult; + + if (!IsPowerOfTwo(align)) + return NULL; + + align = (align > sizeof(void*) ? align : sizeof(void*)) - 1; + + if ((pAlloc = (unsigned char*)g_pMemAlloc->Alloc(sizeof(void*) + align + size, pszFile, nLine)) == (unsigned char*)NULL) + return NULL; + + pResult = (unsigned char*)((size_t)(pAlloc + sizeof(void*) + align) & ~align); + ((unsigned char**)(pResult))[-1] = pAlloc; + + return (void*)pResult; +} + +inline void* MemAlloc_AllocAlignedUnattributed(size_t size, size_t align) +{ + unsigned char* pAlloc, * pResult; + + if (!ValueIsPowerOfTwo(align)) + return NULL; + + align = (align > sizeof(void*) ? align : sizeof(void*)) - 1; + + if ((pAlloc = (unsigned char*)MemAlloc_Alloc(sizeof(void*) + align + size)) == (unsigned char*)NULL) + return NULL; + + pResult = (unsigned char*)((size_t)(pAlloc + sizeof(void*) + align) & ~align); + ((unsigned char**)(pResult))[-1] = pAlloc; + + return (void*)pResult; +} + +inline void* MemAlloc_AllocAlignedFileLine(size_t size, size_t align, const char* pszFile, int nLine) +{ + unsigned char* pAlloc, * pResult; + + if (!ValueIsPowerOfTwo(align)) + return NULL; + + align = (align > sizeof(void*) ? align : sizeof(void*)) - 1; + + if ((pAlloc = (unsigned char*)MemAlloc_Alloc(sizeof(void*) + align + size, pszFile, nLine)) == (unsigned char*)NULL) + return NULL; + + pResult = (unsigned char*)((size_t)(pAlloc + sizeof(void*) + align) & ~align); + ((unsigned char**)(pResult))[-1] = pAlloc; + + return (void*)pResult; +} + +inline void* MemAlloc_ReallocAligned(void* ptr, size_t size, size_t align) +{ + if (!IsPowerOfTwo(align)) + return NULL; + + if (((size_t)ptr & (align - 1)) != 0) + return NULL; + + if (!ptr) + return MemAlloc_AllocAligned(size, align); + + void* pAlloc, * pResult; + + pAlloc = ptr; + pAlloc = (void*)(((size_t)pAlloc & ~(sizeof(void*) - 1)) - sizeof(void*)); + pAlloc = *((void**)pAlloc); + + size_t nOffset = (size_t)ptr - (size_t)pAlloc; + size_t nOldSize = g_pMemAlloc->GetSize(pAlloc); + if (nOldSize >= size + nOffset) + return ptr; + + pResult = MemAlloc_AllocAligned(size, align); + memcpy(pResult, ptr, nOldSize - nOffset); + g_pMemAlloc->Free(pAlloc); + return pResult; +} + +inline void MemAlloc_FreeAligned(void* pMemBlock) +{ + void* pAlloc; + + if (pMemBlock == NULL) + return; + + pAlloc = pMemBlock; + + pAlloc = (void*)(((size_t)pAlloc & ~(sizeof(void*) - 1)) - sizeof(void*)); + + pAlloc = *((void**)pAlloc); + g_pMemAlloc->Free(pAlloc); +} + +inline void MemAlloc_FreeAligned(void* pMemBlock, const char* pFileName, int nLine) +{ + void* pAlloc; + + if (pMemBlock == NULL) + return; + + pAlloc = pMemBlock; + + pAlloc = (void*)(((size_t)pAlloc & ~(sizeof(void*) - 1)) - sizeof(void*)); + + pAlloc = *((void**)pAlloc); + g_pMemAlloc->Free(pAlloc, pFileName, nLine); +} + +inline size_t MemAlloc_GetSizeAligned(void* pMemBlock) +{ + void* pAlloc; + + if (pMemBlock == NULL) + return 0; + + pAlloc = pMemBlock; + + pAlloc = (void*)(((size_t)pAlloc & ~(sizeof(void*) - 1)) - sizeof(void*)); + + pAlloc = *((void**)pAlloc); + return g_pMemAlloc->GetSize(pAlloc) - ((byte*)pMemBlock - (byte*)pAlloc); +} + +#if (defined(_DEBUG) || defined(USE_MEM_DEBUG)) +#define MEM_ALLOC_CREDIT_(tag) CMemAllocAttributeAlloction memAllocAttributeAlloction( tag, __LINE__ ) +#define MemAlloc_PushAllocDbgInfo( pszFile, line ) g_pMemAlloc->PushAllocDbgInfo( pszFile, line ) +#define MemAlloc_PopAllocDbgInfo() g_pMemAlloc->PopAllocDbgInfo() +#define MemAlloc_RegisterAllocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) g_pMemAlloc->RegisterAllocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) +#define MemAlloc_RegisterDeallocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) g_pMemAlloc->RegisterDeallocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) +#else +#define MEM_ALLOC_CREDIT_(tag) ((void)0) +#define MemAlloc_PushAllocDbgInfo( pszFile, line ) ((void)0) +#define MemAlloc_PopAllocDbgInfo() ((void)0) +#define MemAlloc_RegisterAllocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) ((void)0) +#define MemAlloc_RegisterDeallocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) ((void)0) +#endif + +#define MemAlloc_DumpStats() g_pMemAlloc->DumpStats() +#define MemAlloc_CompactHeap() g_pMemAlloc->CompactHeap() +#define MemAlloc_OutOfMemory() g_pMemAlloc->OutOfMemory() +#define MemAlloc_CompactIncremental() g_pMemAlloc->CompactIncremental() +#define MemAlloc_DumpStatsFileBase( _filename ) g_pMemAlloc->DumpStatsFileBase( _filename ) +#define MemAlloc_CrtCheckMemory() g_pMemAlloc->CrtCheckMemory() +#define MemAlloc_GlobalMemoryStatus( _usedMemory, _freeMemory ) g_pMemAlloc->GlobalMemoryStatus( _usedMemory, _freeMemory ) +#define MemAlloc_MemoryAllocFailed() g_pMemAlloc->MemoryAllocFailed() + +#define MemAlloc_GetDebugInfoSize() g_pMemAlloc->GetDebugInfoSize() +#define MemAlloc_SaveDebugInfo( pvDebugInfo ) g_pMemAlloc->SaveDebugInfo( pvDebugInfo ) +#define MemAlloc_RestoreDebugInfo( pvDebugInfo ) g_pMemAlloc->RestoreDebugInfo( pvDebugInfo ) +#define MemAlloc_InitDebugInfo( pvDebugInfo, pchRootFileName, nLine ) g_pMemAlloc->InitDebugInfo( pvDebugInfo, pchRootFileName, nLine ) +#define MemAlloc_GetSize( x ) g_pMemAlloc->GetSize( x ); +class CMemAllocAttributeAlloction +{ +public: + CMemAllocAttributeAlloction(const char* pszFile, int line) + { + MemAlloc_PushAllocDbgInfo(pszFile, line); + } + + ~CMemAllocAttributeAlloction() + { + MemAlloc_PopAllocDbgInfo(); + } +}; + +#define MEM_ALLOC_CREDIT() MEM_ALLOC_CREDIT_(__FILE__) + +#if defined(_WIN32) && ( defined(_DEBUG) || defined(USE_MEM_DEBUG) ) + +#pragma warning(disable:4290) +#pragma warning(push) +#include + +#if defined(_CPPRTTI) && defined(MEM_DEBUG_CLASSNAME) +#define MEM_ALLOC_CREDIT_CLASS() MEM_ALLOC_CREDIT_( typeid(*this).name() ) +#define MEM_ALLOC_CLASSNAME(type) (typeid((type*)(0)).name()) +#else +#define MEM_ALLOC_CREDIT_CLASS() MEM_ALLOC_CREDIT_( __FILE__ ) +#define MEM_ALLOC_CLASSNAME(type) (__FILE__) +#endif + +#ifdef _MSC_VER +#define MEM_ALLOC_CREDIT_FUNCTION() MEM_ALLOC_CREDIT_( __FUNCTION__ ) +#else +#define MEM_ALLOC_CREDIT_FUNCTION() (__FILE__) +#endif + +#pragma warning(pop) +#else +#define MEM_ALLOC_CREDIT_CLASS() +#define MEM_ALLOC_CLASSNAME(type) NULL +#define MEM_ALLOC_CREDIT_FUNCTION() +#endif + +#if (defined(_DEBUG) || defined(USE_MEM_DEBUG)) +struct MemAllocFileLine_t +{ + const char* pszFile; + int line; +}; + +#define MEMALLOC_DEFINE_EXTERNAL_TRACKING( tag ) \ + static CUtlMap g_##tag##Allocs( DefLessFunc( void *) ); \ + static const char *g_psz##tag##Alloc = strcpy( (char *)g_pMemAlloc->Alloc( strlen( #tag "Alloc" ) + 1, "intentional leak", 0 ), #tag "Alloc" ); + +#define MemAlloc_RegisterExternalAllocation( tag, p, size ) \ + if ( !p ) \ + ; \ + else \ + { \ + MemAllocFileLine_t fileLine = { g_psz##tag##Alloc, 0 }; \ + g_pMemAlloc->GetActualDbgInfo( fileLine.pszFile, fileLine.line ); \ + if ( fileLine.pszFile != g_psz##tag##Alloc ) \ + { \ + g_##tag##Allocs.Insert( p, fileLine ); \ + } \ + \ + MemAlloc_RegisterAllocation( fileLine.pszFile, fileLine.line, size, size, 0); \ + } + +#define MemAlloc_RegisterExternalDeallocation( tag, p, size ) \ + if ( !p ) \ + ; \ + else \ + { \ + MemAllocFileLine_t fileLine = { g_psz##tag##Alloc, 0 }; \ + CUtlMap::IndexType_t iRecordedFileLine = g_##tag##Allocs.Find( p ); \ + if ( iRecordedFileLine != g_##tag##Allocs.InvalidIndex() ) \ + { \ + fileLine = g_##tag##Allocs[iRecordedFileLine]; \ + g_##tag##Allocs.RemoveAt( iRecordedFileLine ); \ + } \ + \ + MemAlloc_RegisterDeallocation( fileLine.pszFile, fileLine.line, size, size, 0); \ + } + +#else + +#define MEMALLOC_DEFINE_EXTERNAL_TRACKING( tag ) +#define MemAlloc_RegisterExternalAllocation( tag, p, size ) ((void)0) +#define MemAlloc_RegisterExternalDeallocation( tag, p, size ) ((void)0) + +#endif + +#elif defined( POSIX ) + +#if defined( OSX ) +inline void* memalign(size_t alignment, size_t size) { void* pTmp = NULL; pTmp = malloc(size); return pTmp; } +#endif + +inline void* _aligned_malloc(size_t nSize, size_t align) { return memalign(align, nSize); } +inline void _aligned_free(void* ptr) { free(ptr); } + +inline void* MemAlloc_Alloc(size_t nSize, const char* pFileName = NULL, int nLine = 0) { return malloc(nSize); } +inline void MemAlloc_Free(void* ptr, const char* pFileName = NULL, int nLine = 0) { free(ptr); } + +inline void* MemAlloc_AllocAligned(size_t size, size_t align, const char* pszFile = NULL, int nLine = 0) { return memalign(align, size); } +inline void* MemAlloc_AllocAlignedFileLine(size_t size, size_t align, const char* pszFile = NULL, int nLine = 0) { return memalign(align, size); } +inline void MemAlloc_FreeAligned(void* pMemBlock, const char* pszFile = NULL, int nLine = 0) { free(pMemBlock); } + +#if defined( OSX ) +inline size_t _msize(void* ptr) { return malloc_size(ptr); } +#else +inline size_t _msize(void* ptr) { return malloc_usable_size(ptr); } +#endif + +inline void* MemAlloc_ReallocAligned(void* ptr, size_t size, size_t align) +{ + void* ptr_new_aligned = memalign(align, size); + + if (ptr_new_aligned) + { + size_t old_size = _msize(ptr); + size_t copy_size = (size < old_size) ? size : old_size; + + memcpy(ptr_new_aligned, ptr, copy_size); + free(ptr); + } + + return ptr_new_aligned; +} +#else +#define MemAlloc_GetDebugInfoSize() g_pMemAlloc->GetDebugInfoSize() +#define MemAlloc_SaveDebugInfo( pvDebugInfo ) g_pMemAlloc->SaveDebugInfo( pvDebugInfo ) +#define MemAlloc_RestoreDebugInfo( pvDebugInfo ) g_pMemAlloc->RestoreDebugInfo( pvDebugInfo ) +#define MemAlloc_InitDebugInfo( pvDebugInfo, pchRootFileName, nLine ) g_pMemAlloc->InitDebugInfo( pvDebugInfo, pchRootFileName, nLine ) + +#endif + +#if !defined(STEAM) && defined(NO_MALLOC_OVERRIDE) + +#define MEM_ALLOC_CREDIT_(tag) ((void)0) +#define MEM_ALLOC_CREDIT() MEM_ALLOC_CREDIT_(__FILE__) +#define MEM_ALLOC_CREDIT_FUNCTION() +#define MEM_ALLOC_CREDIT_CLASS() +#define MEM_ALLOC_CLASSNAME(type) NULL + +#define MemAlloc_PushAllocDbgInfo( pszFile, line ) +#define MemAlloc_PopAllocDbgInfo() +#define MemAlloc_RegisterAllocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) ((void)0) +#define MemAlloc_RegisterDeallocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) ((void)0) +#define MemAlloc_DumpStats() ((void)0) +#define MemAlloc_CompactHeap() ((void)0) +#define MemAlloc_OutOfMemory() ((void)0) +#define MemAlloc_CompactIncremental() ((void)0) +#define MemAlloc_DumpStatsFileBase( _filename ) ((void)0) +inline bool MemAlloc_CrtCheckMemory() { return true; } +inline void MemAlloc_GlobalMemoryStatus(size_t* pusedMemory, size_t* pfreeMemory) +{ + *pusedMemory = 0; + *pfreeMemory = 0; +} +#define MemAlloc_MemoryAllocFailed() 0 + +#define MemAlloc_GetDebugInfoSize() 0 +#define MemAlloc_SaveDebugInfo( pvDebugInfo ) ((void)0) +#define MemAlloc_RestoreDebugInfo( pvDebugInfo ) ((void)0) +#define MemAlloc_InitDebugInfo( pvDebugInfo, pchRootFileName, nLine ) ((void)0) + + +#define MEMALLOC_DEFINE_EXTERNAL_TRACKING( tag ) +#define MemAlloc_RegisterExternalAllocation( tag, p, size ) ((void)0) +#define MemAlloc_RegisterExternalDeallocation( tag, p, size ) ((void)0) + +#endif + + + +#if defined( POSIX ) && !defined( NO_HOOK_MALLOC ) +PLATFORM_INTERFACE void MemoryLogMessage(char const* s); +PLATFORM_INTERFACE void EnableMemoryLogging(bool bOnOff); +PLATFORM_INTERFACE void DumpMemoryLog(int nThresh); +PLATFORM_INTERFACE void DumpMemorySummary(void); +PLATFORM_INTERFACE void SetMemoryMark(void); +PLATFORM_INTERFACE void DumpChangedMemory(int nThresh); + +#else +FORCEINLINE void MemoryLogMessage(char const* s) +{ +} + +FORCEINLINE void EnableMemoryLogging(bool bOnOff) +{ +} +FORCEINLINE void DumpMemoryLog(int nThresh) +{ +} +FORCEINLINE void DumpMemorySummary(void) +{ +} +FORCEINLINE void SetMemoryMark(void) +{ +} +FORCEINLINE void DumpChangedMemory(int nThresh) +{ +} + +#endif + +#ifdef POSIX +PLATFORM_INTERFACE size_t ApproximateProcessMemoryUsage(void); +#else +FORCEINLINE size_t ApproximateProcessMemoryUsage(void) +{ + return 0; +} + +#endif + +struct aligned_tmp_t +{ +}; + +template< int bytesAlignment = 16, class T = aligned_tmp_t > +class CAlignedNewDelete : public T +{ + +public: + void* operator new(size_t nSize) + { + return MemAlloc_AllocAligned(nSize, bytesAlignment); + } + + void* operator new(size_t nSize, int nBlockUse, const char* pFileName, int nLine) + { + return MemAlloc_AllocAlignedFileLine(nSize, bytesAlignment, pFileName, nLine); + } + + void operator delete(void* pData) + { + if (pData) + { + MemAlloc_FreeAligned(pData); + } + } + + void operator delete(void* pData, int nBlockUse, const char* pFileName, int nLine) + { + if (pData) + { + MemAlloc_FreeAligned(pData, pFileName, nLine); + } + } +}; + + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/memdbgoff.h b/SpyCustom/sdk/memdbgoff.h new file mode 100644 index 0000000..4c63e25 --- /dev/null +++ b/SpyCustom/sdk/memdbgoff.h @@ -0,0 +1,16 @@ +#ifdef MEM_OVERRIDE_ON + +#undef malloc +#undef realloc +#undef calloc +#undef free +#undef _expand +#undef _msize +#undef new +#undef _aligned_malloc +#undef _aligned_free +#undef _malloc_dbg + +#undef MEM_OVERRIDE_ON + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/memdbgon.h b/SpyCustom/sdk/memdbgon.h new file mode 100644 index 0000000..2a72ed9 --- /dev/null +++ b/SpyCustom/sdk/memdbgon.h @@ -0,0 +1,219 @@ +#if !defined(STEAM) && !defined(NO_MALLOC_OVERRIDE) + +#if defined(_DEBUG) && !defined(USE_MEM_DEBUG) +#define USE_MEM_DEBUG 1 +#endif + +#if defined(NO_HOOK_MALLOC) +#undef USE_MEM_DEBUG +#endif + +#if (defined(_DEBUG) || !defined(_INC_CRTDBG)) || defined(MEMDBGON_H) + +#include "basetypes.h" +#ifdef _WIN32 +#include +#else +#include +#endif +#include +#include +#include "commonmacros.h" +#include "memalloc.h" + +#if defined(USE_MEM_DEBUG) +#if defined( POSIX ) + +#define _NORMAL_BLOCK 1 + +#include +#include +#include +#include +#if !defined( DID_THE_OPERATOR_NEW ) +#define DID_THE_OPERATOR_NEW +void* operator new(size_t nSize, int blah, const char* pFileName, int nLine); +void* operator new[](size_t nSize, int blah, const char* pFileName, int nLine); +#endif + +#else + +#if !defined(_DEBUG) +#define _DEBUG 1 +#include +#undef _DEBUG +#else +#include +#endif + +#endif +#endif + +#include "memdbgoff.h" + +#define MEM_OVERRIDE_ON 1 + +#undef malloc +#undef realloc +#undef calloc +#undef _expand +#undef free +#undef _msize +#undef _aligned_malloc +#undef _aligned_free + +#ifndef MEMDBGON_H +inline void* MemAlloc_InlineCallocMemset(void* pMem, size_t nCount, size_t nElementSize) +{ + memset(pMem, 0, nElementSize * nCount); + return pMem; +} +#endif + +#define calloc(c, s) MemAlloc_InlineCallocMemset(malloc(c*s), c, s) +#define free(p) g_pMemAlloc->Free( p ) +#define _msize(p) g_pMemAlloc->GetSize( p ) +#define _expand(p, s) _expand_NoLongerSupported(p, s) +#define _aligned_free( p ) MemAlloc_FreeAligned( p ) + +#if defined(USE_MEM_DEBUG) + +#define malloc(s) g_pMemAlloc->Alloc( s, __FILE__, __LINE__) +#define realloc(p, s) g_pMemAlloc->Realloc( p, s, __FILE__, __LINE__ ) +#define _aligned_malloc( s, a ) MemAlloc_AllocAligned( s, a, __FILE__, __LINE__ ) + +#define _malloc_dbg(s, t, f, l) WHYCALLINGTHISDIRECTLY(s) + +#if !defined( LINUX ) +#if defined(__AFX_H__) && defined(DEBUG_NEW) +#define new DEBUG_NEW +#else +#undef new +#define MEMALL_DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__) +#define new MEMALL_DEBUG_NEW +#endif +#endif + +#undef _strdup +#undef strdup +#undef _wcsdup +#undef wcsdup + +#define _strdup(s) MemAlloc_StrDup(s, __FILE__, __LINE__) +#define strdup(s) MemAlloc_StrDup(s, __FILE__, __LINE__) +#define _wcsdup(s) MemAlloc_WcStrDup(s, __FILE__, __LINE__) +#define wcsdup(s) MemAlloc_WcStrDup(s, __FILE__, __LINE__) + +#if !defined(MEMDBGON_H) + +inline char* MemAlloc_StrDup(const char* pString, const char* pFileName, unsigned nLine) +{ + char* pMemory; + + if (!pString) + return NULL; + + size_t len = strlen(pString) + 1; + if ((pMemory = (char*)g_pMemAlloc->Alloc(len, pFileName, nLine)) != NULL) + { + return strcpy(pMemory, pString); + } + + return NULL; +} + +inline wchar_t* MemAlloc_WcStrDup(const wchar_t* pString, const char* pFileName, unsigned nLine) +{ + wchar_t* pMemory; + + if (!pString) + return NULL; + + size_t len = (wcslen(pString) + 1); + if ((pMemory = (wchar_t*)g_pMemAlloc->Alloc(len * sizeof(wchar_t), pFileName, nLine)) != NULL) + { + return wcscpy(pMemory, pString); + } + + return NULL; +} + +#endif + +#else +#define malloc(s) g_pMemAlloc->Alloc( s ) +#define realloc(p, s) g_pMemAlloc->Realloc( p, s ) +#define _aligned_malloc( s, a ) MemAlloc_AllocAligned( s, a ) + +#ifndef _malloc_dbg +#define _malloc_dbg(s, t, f, l) WHYCALLINGTHISDIRECTLY(s) +#endif + +#undef new + +#undef _strdup +#undef strdup +#undef _wcsdup +#undef wcsdup + +#define _strdup(s) MemAlloc_StrDup(s) +#define strdup(s) MemAlloc_StrDup(s) +#define _wcsdup(s) MemAlloc_WcStrDup(s) +#define wcsdup(s) MemAlloc_WcStrDup(s) + +#if !defined(MEMDBGON_H) + +inline char* MemAlloc_StrDup(const char* pString) +{ + char* pMemory; + + if (!pString) + return NULL; + + size_t len = strlen(pString) + 1; + if ((pMemory = (char*)g_pMemAlloc->Alloc(len)) != NULL) + { + return strcpy(pMemory, pString); + } + + return NULL; +} + +inline wchar_t* MemAlloc_WcStrDup(const wchar_t* pString) +{ + wchar_t* pMemory; + + if (!pString) + return NULL; + + size_t len = (wcslen(pString) + 1); + if ((pMemory = (wchar_t*)g_pMemAlloc->Alloc(len * sizeof(wchar_t))) != NULL) + { + return wcscpy(pMemory, pString); + } + + return NULL; +} + +#endif + +#endif + +#define MEMDBGON_H + +#else + +#if defined(USE_MEM_DEBUG) +#ifndef _STATIC_LINKED +#pragma message ("Note: file includes crtdbg.h directly, therefore will cannot use memdbgon.h in non-debug build") +#else +#error "Error: file includes crtdbg.h directly, therefore will cannot use memdbgon.h in non-debug build. Not recoverable in static build" +#endif +#endif +#endif + +#else + +#include "memalloc.h" + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/mempool.h b/SpyCustom/sdk/mempool.h new file mode 100644 index 0000000..2de8dba --- /dev/null +++ b/SpyCustom/sdk/mempool.h @@ -0,0 +1,590 @@ +#ifndef MEMPOOL_H +#define MEMPOOL_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "memalloc.h" +#include "tslist.h" +#include "platform.h" +#include "utlvector.h" +#include "utlrbtree.h" + +typedef void (*MemoryPoolReportFunc_t)(PRINTF_FORMAT_STRING char const* pMsg, ...); + +class CUtlMemoryPool +{ +public: + enum MemoryPoolGrowType_t + { + GROW_NONE = 0, + GROW_FAST = 1, + GROW_SLOW = 2 + }; + + CUtlMemoryPool(int blockSize, int numElements, int growMode = GROW_FAST, const char* pszAllocOwner = NULL, int nAlignment = 0); + ~CUtlMemoryPool(); + + void* Alloc(); + void* Alloc(size_t amount); + void* AllocZero(); + void* AllocZero(size_t amount); + void Free(void* pMem); + + void Clear(); + + static void SetErrorReportFunc(MemoryPoolReportFunc_t func); + + int Count() const { return m_BlocksAllocated; } + int PeakCount() const { return m_PeakAlloc; } + int BlockSize() const { return m_BlockSize; } + int Size() const; + + bool IsAllocationWithinPool(void* pMem) const; + +protected: + class CBlob + { + public: + CBlob* m_pPrev, * m_pNext; + int m_NumBytes; + char m_Data[1]; + char m_Padding[3]; + }; + + void Init(); + void AddNewBlob(); + void ReportLeaks(); + + int m_BlockSize; + int m_BlocksPerBlob; + + int m_GrowMode; + + int m_BlocksAllocated; + int m_PeakAlloc; + unsigned short m_nAlignment; + unsigned short m_NumBlobs; + void* m_pHeadOfFreeList; + const char* m_pszAllocOwner; + CBlob m_BlobHead; + + static MemoryPoolReportFunc_t g_ReportFunc; +}; + + +class CMemoryPoolMT : public CUtlMemoryPool +{ +public: + CMemoryPoolMT(int blockSize, int numElements, int growMode = GROW_FAST, const char* pszAllocOwner = NULL, int nAlignment = 0) : CUtlMemoryPool(blockSize, numElements, growMode, pszAllocOwner, nAlignment) {} + + + void* Alloc() { AUTO_LOCK(m_mutex); return CUtlMemoryPool::Alloc(); } + void* Alloc(size_t amount) { AUTO_LOCK(m_mutex); return CUtlMemoryPool::Alloc(amount); } + void* AllocZero() { AUTO_LOCK(m_mutex); return CUtlMemoryPool::AllocZero(); } + void* AllocZero(size_t amount) { AUTO_LOCK(m_mutex); return CUtlMemoryPool::AllocZero(amount); } + void Free(void* pMem) { AUTO_LOCK(m_mutex); CUtlMemoryPool::Free(pMem); } + + void Clear() { AUTO_LOCK(m_mutex); return CUtlMemoryPool::Clear(); } +private: + CThreadFastMutex m_mutex; +}; + + +template< class T > +class CClassMemoryPool : public CUtlMemoryPool +{ +public: + CClassMemoryPool(int numElements, int growMode = GROW_FAST, int nAlignment = 0) : + CUtlMemoryPool(sizeof(T), numElements, growMode, MEM_ALLOC_CLASSNAME(T), nAlignment) {} + + T* Alloc(); + T* AllocZero(); + void Free(T* pMem); + + void Clear(); +}; + +template +class CAlignedMemPool +{ + enum + { + BLOCK_SIZE = COMPILETIME_MAX(ALIGN_VALUE(ITEM_SIZE, ALIGNMENT), 8), + }; + +public: + CAlignedMemPool(); + + void* Alloc(); + void Free(void* p); + + static int __cdecl CompareChunk(void* const* ppLeft, void* const* ppRight); + void Compact(); + + int NumTotal() { AUTO_LOCK(m_mutex); return m_Chunks.Count() * (CHUNK_SIZE / BLOCK_SIZE); } + int NumAllocated() { AUTO_LOCK(m_mutex); return NumTotal() - m_nFree; } + int NumFree() { AUTO_LOCK(m_mutex); return m_nFree; } + + int BytesTotal() { AUTO_LOCK(m_mutex); return NumTotal() * BLOCK_SIZE; } + int BytesAllocated() { AUTO_LOCK(m_mutex); return NumAllocated() * BLOCK_SIZE; } + int BytesFree() { AUTO_LOCK(m_mutex); return NumFree() * BLOCK_SIZE; } + + int ItemSize() { return ITEM_SIZE; } + int BlockSize() { return BLOCK_SIZE; } + int ChunkSize() { return CHUNK_SIZE; } + +private: + struct FreeBlock_t + { + FreeBlock_t* pNext; + byte reserved[BLOCK_SIZE - sizeof(FreeBlock_t*)]; + }; + + CUtlVector m_Chunks; + FreeBlock_t* m_pFirstFree; + int m_nFree; + CAllocator m_Allocator; + double m_TimeLastCompact; + + CThreadFastMutex m_mutex; +}; + +template +class CObjectPool +{ +public: + CObjectPool() + { + int i = nInitialCount; + while (i-- > 0) + { + m_AvailableObjects.PushItem(new T); + } + } + + ~CObjectPool() + { + Purge(); + } + + int NumAvailable() + { + return m_AvailableObjects.Count(); + } + + void Purge() + { + T* p = NULL; + while (m_AvailableObjects.PopItem(&p)) + { + delete p; + } + } + + T* GetObject(bool bCreateNewIfEmpty = bDefCreateNewIfEmpty) + { + T* p = NULL; + if (!m_AvailableObjects.PopItem(&p)) + { + p = (bCreateNewIfEmpty) ? new T : NULL; + } + return p; + } + + void PutObject(T* p) + { + m_AvailableObjects.PushItem(p); + } + +private: + CTSList m_AvailableObjects; +}; + +template +class CFixedBudgetMemoryPool +{ +public: + CFixedBudgetMemoryPool() + { + m_pBase = m_pLimit = 0; + COMPILE_TIME_ASSERT(ITEM_SIZE % 4 == 0); + } + + bool Owns(void* p) + { + return (p >= m_pBase && p < m_pLimit); + } + + void* Alloc() + { + MEM_ALLOC_CREDIT_CLASS(); +#ifndef USE_MEM_DEBUG + if (!m_pBase) + { + LOCAL_THREAD_LOCK(); + if (!m_pBase) + { + byte* pMemory = m_pBase = (byte*)malloc(ITEM_COUNT * ITEM_SIZE); + m_pLimit = m_pBase + (ITEM_COUNT * ITEM_SIZE); + + for (int i = 0; i < ITEM_COUNT; i++) + { + m_freeList.Push((TSLNodeBase_t*)pMemory); + pMemory += ITEM_SIZE; + } + } + } + + void* p = m_freeList.Pop(); + if (p) + return p; +#endif + return malloc(ITEM_SIZE); + } + + void Free(void* p) + { +#ifndef USE_MEM_DEBUG + if (Owns(p)) + m_freeList.Push((TSLNodeBase_t*)p); + else +#endif + free(p); + } + + void Clear() + { +#ifndef USE_MEM_DEBUG + if (m_pBase) + { + free(m_pBase); + } + m_pBase = m_pLimit = 0; + Construct(&m_freeList); +#endif + } + + bool IsEmpty() + { +#ifndef USE_MEM_DEBUG + if (m_pBase && m_freeList.Count() != ITEM_COUNT) + return false; +#endif + return true; + } + + enum + { + ITEM_SIZE = ALIGN_VALUE(PROVIDED_ITEM_SIZE, TSLIST_NODE_ALIGNMENT) + }; + + CTSListBase m_freeList; + byte* m_pBase; + byte* m_pLimit; +}; + +#define BIND_TO_FIXED_BUDGET_POOL( poolName ) \ + inline void* operator new( size_t size ) { return poolName.Alloc(); } \ + inline void* operator new( size_t size, int nBlockUse, const char *pFileName, int nLine ) { return poolName.Alloc(); } \ + inline void operator delete( void* p ) { poolName.Free(p); } \ + inline void operator delete( void* p, int nBlockUse, const char *pFileName, int nLine ) { poolName.Free(p); } + + +template< class T > +inline T* CClassMemoryPool::Alloc() +{ + T* pRet; + + { + MEM_ALLOC_CREDIT_CLASS(); + pRet = (T*)CUtlMemoryPool::Alloc(); + } + + if (pRet) + { + Construct(pRet); + } + return pRet; +} + +template< class T > +inline T* CClassMemoryPool::AllocZero() +{ + T* pRet; + + { + MEM_ALLOC_CREDIT_CLASS(); + pRet = (T*)CUtlMemoryPool::AllocZero(); + } + + if (pRet) + { + Construct(pRet); + } + return pRet; +} + +template< class T > +inline void CClassMemoryPool::Free(T* pMem) +{ + if (pMem) + { + Destruct(pMem); + } + + CUtlMemoryPool::Free(pMem); +} + +template< class T > +inline void CClassMemoryPool::Clear() +{ + CUtlRBTree freeBlocks; + SetDefLessFunc(freeBlocks); + + void* pCurFree = m_pHeadOfFreeList; + while (pCurFree != NULL) + { + freeBlocks.Insert(pCurFree); + pCurFree = *((void**)pCurFree); + } + + for (CBlob* pCur = m_BlobHead.m_pNext; pCur != &m_BlobHead; pCur = pCur->m_pNext) + { + int nElements = pCur->m_NumBytes / this->m_BlockSize; + T* p = (T*)AlignValue(pCur->m_Data, this->m_nAlignment); + T* pLimit = p + nElements; + while (p < pLimit) + { + if (freeBlocks.Find(p) == freeBlocks.InvalidIndex()) + { + Destruct(p); + } + p++; + } + } + + CUtlMemoryPool::Clear(); +} + + + + + +#define DECLARE_FIXEDSIZE_ALLOCATOR( _class ) \ + public: \ + inline void* operator new( size_t size ) { MEM_ALLOC_CREDIT_(#_class " pool"); return s_Allocator.Alloc(size); } \ + inline void* operator new( size_t size, int nBlockUse, const char *pFileName, int nLine ) { MEM_ALLOC_CREDIT_(#_class " pool"); return s_Allocator.Alloc(size); } \ + inline void operator delete( void* p ) { s_Allocator.Free(p); } \ + inline void operator delete( void* p, int nBlockUse, const char *pFileName, int nLine ) { s_Allocator.Free(p); } \ + private: \ + static CUtlMemoryPool s_Allocator + +#define DEFINE_FIXEDSIZE_ALLOCATOR( _class, _initsize, _grow ) \ + CUtlMemoryPool _class::s_Allocator(sizeof(_class), _initsize, _grow, #_class " pool") + +#define DEFINE_FIXEDSIZE_ALLOCATOR_ALIGNED( _class, _initsize, _grow, _alignment ) \ + CUtlMemoryPool _class::s_Allocator(sizeof(_class), _initsize, _grow, #_class " pool", _alignment ) + +#define DECLARE_FIXEDSIZE_ALLOCATOR_MT( _class ) \ + public: \ + inline void* operator new( size_t size ) { MEM_ALLOC_CREDIT_(#_class " pool"); return s_Allocator.Alloc(size); } \ + inline void* operator new( size_t size, int nBlockUse, const char *pFileName, int nLine ) { MEM_ALLOC_CREDIT_(#_class " pool"); return s_Allocator.Alloc(size); } \ + inline void operator delete( void* p ) { s_Allocator.Free(p); } \ + inline void operator delete( void* p, int nBlockUse, const char *pFileName, int nLine ) { s_Allocator.Free(p); } \ + private: \ + static CMemoryPoolMT s_Allocator + +#define DEFINE_FIXEDSIZE_ALLOCATOR_MT( _class, _initsize, _grow ) \ + CMemoryPoolMT _class::s_Allocator(sizeof(_class), _initsize, _grow, #_class " pool") + +#define DECLARE_FIXEDSIZE_ALLOCATOR_EXTERNAL( _class ) \ + public: \ + inline void* operator new( size_t size ) { MEM_ALLOC_CREDIT_(#_class " pool"); return s_pAllocator->Alloc(size); } \ + inline void* operator new( size_t size, int nBlockUse, const char *pFileName, int nLine ) { MEM_ALLOC_CREDIT_(#_class " pool"); return s_pAllocator->Alloc(size); } \ + inline void operator delete( void* p ) { s_pAllocator->Free(p); } \ + private: \ + static CUtlMemoryPool* s_pAllocator + +#define DEFINE_FIXEDSIZE_ALLOCATOR_EXTERNAL( _class, _allocator ) \ + CUtlMemoryPool* _class::s_pAllocator = _allocator + + +template +inline CAlignedMemPool::CAlignedMemPool() + : m_pFirstFree(0), + m_nFree(0), + m_TimeLastCompact(0) +{ + { COMPILE_TIME_ASSERT(sizeof(FreeBlock_t) >= BLOCK_SIZE); } + { COMPILE_TIME_ASSERT(ALIGN_VALUE(sizeof(FreeBlock_t), ALIGNMENT) == sizeof(FreeBlock_t)); } +} + +template +inline void* CAlignedMemPool::Alloc() +{ + AUTO_LOCK(m_mutex); + + if (!m_pFirstFree) + { + if (!GROWMODE && m_Chunks.Count()) + { + return NULL; + } + + FreeBlock_t* pNew = (FreeBlock_t*)m_Allocator.Alloc(CHUNK_SIZE); + Assert((unsigned)pNew % ALIGNMENT == 0); + m_Chunks.AddToTail(pNew); + m_nFree = CHUNK_SIZE / BLOCK_SIZE; + m_pFirstFree = pNew; + for (int i = 0; i < m_nFree - 1; i++) + { + pNew->pNext = pNew + 1; + pNew++; + } + pNew->pNext = NULL; + } + + void* p = m_pFirstFree; + m_pFirstFree = m_pFirstFree->pNext; + m_nFree--; + + return p; +} + +template +inline void CAlignedMemPool::Free(void* p) +{ + AUTO_LOCK(m_mutex); + + FreeBlock_t* pFree = ((FreeBlock_t*)p); + FreeBlock_t* pCur = m_pFirstFree; + FreeBlock_t* pPrev = NULL; + + while (pCur && pFree > pCur) + { + pPrev = pCur; + pCur = pCur->pNext; + } + + pFree->pNext = pCur; + + if (pPrev) + { + pPrev->pNext = pFree; + } + else + { + m_pFirstFree = pFree; + } + m_nFree++; + + if (m_nFree >= (CHUNK_SIZE / BLOCK_SIZE) * COMPACT_THRESHOLD) + { + double time = Plat_FloatTime(); + double compactTime = (m_nFree >= (CHUNK_SIZE / BLOCK_SIZE) * COMPACT_THRESHOLD * 4) ? 15.0 : 30.0; + if (m_TimeLastCompact > time || m_TimeLastCompact + compactTime < time) + { + Compact(); + m_TimeLastCompact = time; + } + } +} + +template +inline void CAlignedMemPool::Compact() +{ + FreeBlock_t* pCur = m_pFirstFree; + FreeBlock_t* pPrev = NULL; + + m_Chunks.Sort(CompareChunk); + +#ifdef VALIDATE_ALIGNED_MEM_POOL + { + FreeBlock_t* p = m_pFirstFree; + while (p) + { + if (p->pNext && p > p->pNext) + { + __asm { int 3 } + } + p = p->pNext; + } + + for (int i = 0; i < m_Chunks.Count(); i++) + { + if (i + 1 < m_Chunks.Count()) + { + if (m_Chunks[i] > m_Chunks[i + 1]) + { + __asm { int 3 } + } + } + } + } +#endif + + int i; + + for (i = 0; i < m_Chunks.Count(); i++) + { + int nBlocksPerChunk = CHUNK_SIZE / BLOCK_SIZE; + FreeBlock_t* pChunkLimit = ((FreeBlock_t*)m_Chunks[i]) + nBlocksPerChunk; + int nFromChunk = 0; + if (pCur == m_Chunks[i]) + { + FreeBlock_t* pFirst = pCur; + while (pCur && pCur >= m_Chunks[i] && pCur < pChunkLimit) + { + pCur = pCur->pNext; + nFromChunk++; + } + pCur = pFirst; + + } + + while (pCur && pCur >= m_Chunks[i] && pCur < pChunkLimit) + { + if (nFromChunk != nBlocksPerChunk) + { + if (pPrev) + { + pPrev->pNext = pCur; + } + else + { + m_pFirstFree = pCur; + } + pPrev = pCur; + } + else if (pPrev) + { + pPrev->pNext = NULL; + } + else + { + m_pFirstFree = NULL; + } + + pCur = pCur->pNext; + } + + if (nFromChunk == nBlocksPerChunk) + { + m_Allocator.Free(m_Chunks[i]); + m_nFree -= nBlocksPerChunk; + m_Chunks[i] = 0; + } + } + + for (i = m_Chunks.Count() - 1; i >= 0; i--) + { + if (!m_Chunks[i]) + { + m_Chunks.FastRemove(i); + } + } +} + +#endif diff --git a/SpyCustom/sdk/meshreader.h b/SpyCustom/sdk/meshreader.h new file mode 100644 index 0000000..6fa8d7a --- /dev/null +++ b/SpyCustom/sdk/meshreader.h @@ -0,0 +1,231 @@ +#ifndef MESHREADER_H +#define MESHREADER_H + +#ifdef _WIN32 +#pragma once +#endif + + +class CBaseMeshReader : protected MeshDesc_t +{ +public: + + CBaseMeshReader(); + ~CBaseMeshReader(); + + void BeginRead( + IMesh* pMesh, + int firstVertex = 0, + int numVertices = 0, + int firstIndex = 0, + int numIndices = 0); + + void EndRead(); + + void BeginRead_Direct(const MeshDesc_t& desc, int numVertices, int nIndices); + + void Reset(); + + +protected: + IMesh* m_pMesh; + int m_MaxVertices; + int m_MaxIndices; +}; + + +class CMeshReader : public CBaseMeshReader +{ +public: +public: + int NumIndices() const; + unsigned short Index(int index) const; + + const Vector& Position(int iVertex) const; + + unsigned int Color(int iVertex) const; + + const float* TexCoord(int iVertex, int stage) const; + void TexCoord2f(int iVertex, int stage, float& s, float& t) const; + const Vector2D& TexCoordVector2D(int iVertex, int stage) const; + + int NumBoneWeights() const; + float Wrinkle(int iVertex) const; + + const Vector& Normal(int iVertex) const; + void Normal(int iVertex, Vector& vNormal) const; + + const Vector& TangentS(int iVertex) const; + const Vector& TangentT(int iVertex) const; + float BoneWeight(int iVertex) const; + +#ifdef NEW_SKINNING + float* BoneMatrix(int iVertex) const; +#else + unsigned char* BoneMatrix(int iVertex) const; +#endif +}; + + +inline CBaseMeshReader::CBaseMeshReader() +{ + m_pMesh = NULL; +} + +inline CBaseMeshReader::~CBaseMeshReader() +{ + Assert(!m_pMesh); +} + +inline void CBaseMeshReader::BeginRead( + IMesh* pMesh, + int firstVertex, + int numVertices, + int firstIndex, + int numIndices) +{ + Assert(pMesh && (!m_pMesh)); + + if (numVertices < 0) + { + numVertices = pMesh->VertexCount(); + } + + if (numIndices < 0) + { + numIndices = pMesh->IndexCount(); + } + + m_pMesh = pMesh; + m_MaxVertices = numVertices; + m_MaxIndices = numIndices; + + VertexCompressionType_t compressionType = CompressionType(pMesh->GetVertexFormat()); + Assert(compressionType == VERTEX_COMPRESSION_NONE); + if (compressionType != VERTEX_COMPRESSION_NONE) + { + Warning("Cannot use CBaseMeshReader with compressed vertices! Will get junk data or a crash.\n"); + } + + pMesh->ModifyBeginEx(true, firstVertex, numVertices, firstIndex, numIndices, *this); + + Reset(); +} + +inline void CBaseMeshReader::EndRead() +{ + Assert(m_pMesh); + m_pMesh->ModifyEnd(*this); + m_pMesh = NULL; +} + +inline void CBaseMeshReader::BeginRead_Direct(const MeshDesc_t& desc, int nVertices, int nIndices) +{ + MeshDesc_t* pThis = this; + *pThis = desc; + m_MaxVertices = nVertices; + m_MaxIndices = nIndices; + + Assert(desc.m_CompressionType == VERTEX_COMPRESSION_NONE); + if (desc.m_CompressionType != VERTEX_COMPRESSION_NONE) + { + Warning("Cannot use CBaseMeshReader with compressed vertices!\n"); + } +} + +inline void CBaseMeshReader::Reset() +{ +} + + + + +inline int CMeshReader::NumIndices() const +{ + return m_MaxIndices; +} + +inline unsigned short CMeshReader::Index(int index) const +{ + Assert((index >= 0) && (index < m_MaxIndices)); + return m_pIndices[index * m_nIndexSize]; +} + +inline const Vector& CMeshReader::Position(int iVertex) const +{ + Assert(iVertex >= 0 && iVertex < m_MaxVertices); + return *(Vector*)((char*)m_pPosition + iVertex * m_VertexSize_Position); +} + +inline unsigned int CMeshReader::Color(int iVertex) const +{ + Assert(iVertex >= 0 && iVertex < m_MaxVertices); + unsigned char* pColor = m_pColor + iVertex * m_VertexSize_Color; + return (pColor[0] << 16) | (pColor[1] << 8) | (pColor[2]) | (pColor[3] << 24); +} + +inline const float* CMeshReader::TexCoord(int iVertex, int iStage) const +{ + Assert(iVertex >= 0 && iVertex < m_MaxVertices); + return (float*)((char*)m_pTexCoord[iStage] + iVertex * m_VertexSize_TexCoord[iStage]); +} + +inline void CMeshReader::TexCoord2f(int iVertex, int iStage, float& s, float& t) const +{ + Assert(iVertex >= 0 && iVertex < m_MaxVertices); + float* p = (float*)((char*)m_pTexCoord[iStage] + iVertex * m_VertexSize_TexCoord[iStage]); + s = p[0]; + t = p[1]; +} + +inline const Vector2D& CMeshReader::TexCoordVector2D(int iVertex, int iStage) const +{ + Assert(iVertex >= 0 && iVertex < m_MaxVertices); + Vector2D* p = (Vector2D*)((char*)m_pTexCoord[iStage] + iVertex * m_VertexSize_TexCoord[iStage]); + return *p; +} + +inline float CMeshReader::Wrinkle(int iVertex) const +{ + Assert(iVertex >= 0 && iVertex < m_MaxVertices); + return *(float*)((char*)m_pWrinkle + iVertex * m_VertexSize_Wrinkle); +} + +inline int CMeshReader::NumBoneWeights() const +{ + return m_NumBoneWeights; +} + +inline const Vector& CMeshReader::Normal(int iVertex) const +{ + Assert(iVertex >= 0 && iVertex < m_MaxVertices); + return *(const Vector*)(const float*)((char*)m_pNormal + iVertex * m_VertexSize_Normal); +} + +inline void CMeshReader::Normal(int iVertex, Vector& vNormal) const +{ + Assert(iVertex >= 0 && iVertex < m_MaxVertices); + const float* p = (const float*)((char*)m_pNormal + iVertex * m_VertexSize_Normal); + vNormal.Init(p[0], p[1], p[2]); +} + +inline const Vector& CMeshReader::TangentS(int iVertex) const +{ + Assert(iVertex >= 0 && iVertex < m_MaxVertices); + return *(const Vector*)((char*)m_pTangentS + iVertex * m_VertexSize_TangentS); +} + +inline const Vector& CMeshReader::TangentT(int iVertex) const +{ + Assert(iVertex >= 0 && iVertex < m_MaxVertices); + return *(const Vector*)((char*)m_pTangentT + iVertex * m_VertexSize_TangentT); +} + +inline float CMeshReader::BoneWeight(int iVertex) const +{ + Assert(iVertex >= 0 && iVertex < m_MaxVertices); + float* p = (float*)((char*)m_pBoneWeight + iVertex * m_VertexSize_BoneWeight); + return *p; +} + +#endif diff --git a/SpyCustom/sdk/meshutils.h b/SpyCustom/sdk/meshutils.h new file mode 100644 index 0000000..3c354eb --- /dev/null +++ b/SpyCustom/sdk/meshutils.h @@ -0,0 +1,16 @@ +#ifndef MESHUTILS_H +#define MESHUTILS_H + +#ifdef _WIN32 +#pragma once +#endif + + +void GenerateSequentialIndexBuffer(unsigned short* pIndexMemory, int nIndexCount, int nFirstVertex); +void GenerateQuadIndexBuffer(unsigned short* pIndexMemory, int nIndexCount, int nFirstVertex); +void GeneratePolygonIndexBuffer(unsigned short* pIndexMemory, int nIndexCount, int nFirstVertex); +void GenerateLineStripIndexBuffer(unsigned short* pIndexMemory, int nIndexCount, int nFirstVertex); +void GenerateLineLoopIndexBuffer(unsigned short* pIndexMemory, int nIndexCount, int nFirstVertex); + + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/messagebox.h b/SpyCustom/sdk/messagebox.h new file mode 100644 index 0000000..9fec7a7 --- /dev/null +++ b/SpyCustom/sdk/messagebox.h @@ -0,0 +1,74 @@ +#ifndef MESSAGEBOX_H +#define MESSAGEBOX_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "vgui.h" +#include "Frame.h" + +#ifdef MessageBox +#undef MessageBox +#endif + +namespace vgui +{ + + class MessageBox : public Frame + { + DECLARE_CLASS_SIMPLE(MessageBox, Frame); + + public: + MessageBox(const char* title, const char* text, Panel* parent = NULL); + MessageBox(const wchar_t* wszTitle, const wchar_t* wszText, Panel* parent = NULL); + ~MessageBox(); + + virtual void DoModal(Frame* pFrameOver = NULL); + + virtual void ShowWindow(Frame* pFrameOver = NULL); + + virtual void SetCommand(const char* command); + virtual void SetCommand(KeyValues* command); + + virtual void SetOKButtonVisible(bool state); + + virtual void SetOKButtonText(const char* buttonText); + virtual void SetOKButtonText(const wchar_t* wszButtonText); + + void SetCancelButtonVisible(bool state); + void SetCancelButtonText(const char* buttonText); + void SetCancelButtonText(const wchar_t* wszButtonText); + void SetCancelCommand(KeyValues* command); + + virtual void DisableCloseButton(bool state); + + virtual void OnCommand(const char* pCommand); + + void ShowMessageBoxOverCursor(bool bEnable); + + protected: + virtual void PerformLayout(); + virtual void ApplySchemeSettings(IScheme* pScheme); + + protected: + Button* m_pOkButton; + Button* m_pCancelButton; + Label* m_pMessageLabel; + + private: + MESSAGE_FUNC(OnShutdownRequest, "ShutdownRequest"); + + void Init(); + + KeyValues* m_OkCommand; + KeyValues* m_CancelCommand; + vgui::Frame* m_pFrameOver; + bool m_bNoAutoClose : 1; + bool m_bShowMessageBoxOverCursor : 1; + }; + +} + + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/minidump.h b/SpyCustom/sdk/minidump.h new file mode 100644 index 0000000..5338a83 --- /dev/null +++ b/SpyCustom/sdk/minidump.h @@ -0,0 +1,57 @@ +#ifndef MINIDUMP_H +#define MINIDUMP_H +#ifdef _WIN32 +#pragma once +#endif + +#include "platform.h" + +PLATFORM_INTERFACE void SetMinidumpFilenamePrefix(const char* pszPrefix); + +PLATFORM_INTERFACE void SetMinidumpComment(const char* pszComment); + +PLATFORM_INTERFACE void WriteMiniDump(const char* pszFilenameSuffix = NULL); + +typedef void (*FnWMain)(int, tchar* []); +typedef void (*FnVoidPtrFn)(void*); + +#if defined(_WIN32) && !defined(_X360) + +typedef void (*FnWMain)(int, tchar* []); +typedef int (*FnWMainIntRet)(int, tchar* []); +typedef void (*FnVoidPtrFn)(void*); + +enum ECatchAndWriteMinidumpAction +{ + k_ECatchAndWriteMiniDumpAbort = 0, + k_ECatchAndWriteMiniDumpReThrow = 1, + k_ECatchAndWriteMiniDumpIgnore = 2, +}; + +PLATFORM_INTERFACE void CatchAndWriteMiniDump(FnWMain pfn, int argc, tchar* argv[]); +PLATFORM_INTERFACE void CatchAndWriteMiniDumpForVoidPtrFn(FnVoidPtrFn pfn, void* pv, bool bExitQuietly); + +PLATFORM_INTERFACE void CatchAndWriteMiniDumpEx(FnWMain pfn, int argc, tchar* argv[], ECatchAndWriteMinidumpAction eAction); +PLATFORM_INTERFACE int CatchAndWriteMiniDumpExReturnsInt(FnWMainIntRet pfn, int argc, tchar* argv[], ECatchAndWriteMinidumpAction eAction); +PLATFORM_INTERFACE void CatchAndWriteMiniDumpExForVoidPtrFn(FnVoidPtrFn pfn, void* pv, ECatchAndWriteMinidumpAction eAction); + +struct _EXCEPTION_POINTERS; + +typedef void (*FnMiniDump)(unsigned int uStructuredExceptionCode, _EXCEPTION_POINTERS* pExceptionInfo, const char* pszFilenameSuffix); +PLATFORM_INTERFACE FnMiniDump SetMiniDumpFunction(FnMiniDump pfn); + +PLATFORM_INTERFACE bool WriteMiniDumpUsingExceptionInfo( + unsigned int uStructuredExceptionCode, + _EXCEPTION_POINTERS* pExceptionInfo, + int minidumpType, + const char* pszFilenameSuffix = NULL, + tchar* ptchMinidumpFileNameBuffer = NULL +); + +PLATFORM_INTERFACE void MinidumpSetUnhandledExceptionFunction(FnMiniDump pfn); + +PLATFORM_INTERFACE void EnableCrashingOnCrashes(); + +#endif + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/modelloader.h b/SpyCustom/sdk/modelloader.h new file mode 100644 index 0000000..42c1a22 --- /dev/null +++ b/SpyCustom/sdk/modelloader.h @@ -0,0 +1,148 @@ +#if !defined( MOD_LOADER_H ) +#define MOD_LOADER_H +#ifdef _WIN32 +#pragma once +#endif + +struct model_t; +class IMaterial; +class IFileList; + + +#include "utlmemory.h" + + +abstract_class IModelLoader +{ +public: + enum REFERENCETYPE + { + FMODELLOADER_NOTLOADEDORREFERENCED = 0, + FMODELLOADER_LOADED = (1 << 0), + + FMODELLOADER_SERVER = (1 << 1), + FMODELLOADER_CLIENT = (1 << 2), + FMODELLOADER_CLIENTDLL = (1 << 3), + FMODELLOADER_STATICPROP = (1 << 4), + FMODELLOADER_DETAILPROP = (1 << 5), + FMODELLOADER_REFERENCEMASK = (FMODELLOADER_SERVER | FMODELLOADER_CLIENT | FMODELLOADER_CLIENTDLL | FMODELLOADER_STATICPROP | FMODELLOADER_DETAILPROP), + + FMODELLOADER_TOUCHED_BY_PRELOAD = (1 << 15), + FMODELLOADER_LOADED_BY_PRELOAD = (1 << 16), + FMODELLOADER_TOUCHED_MATERIALS = (1 << 17), + }; + + enum ReloadType_t + { + RELOAD_LOD_CHANGED = 0, + RELOAD_EVERYTHING, + RELOAD_REFRESH_MODELS, + }; + + virtual void Init(void) = 0; + virtual void Shutdown(void) = 0; + + virtual int GetCount(void) = 0; + virtual model_t* GetModelForIndex(int i) = 0; + + virtual const char* GetName(const model_t* model) = 0; + + virtual void* GetExtraData(model_t* model) = 0; + + virtual int GetModelFileSize(const char* name) = 0; + + virtual model_t* GetModelForName(const char* name, REFERENCETYPE referencetype) = 0; + virtual model_t* ReferenceModel(const char* name, REFERENCETYPE referencetype) = 0; + virtual void UnreferenceModel(model_t* model, REFERENCETYPE referencetype) = 0; + virtual void UnreferenceAllModels(REFERENCETYPE referencetype) = 0; + + virtual void UnloadUnreferencedModels(void) = 0; + virtual void PurgeUnusedModels(void) = 0; + + virtual bool Map_GetRenderInfoAllocated(void) = 0; + virtual void Map_SetRenderInfoAllocated(bool allocated) = 0; + + virtual void Map_LoadDisplacements(model_t* model, bool bRestoring) = 0; + + virtual void Print(void) = 0; + + virtual bool Map_IsValid(char const* mapname) = 0; + + virtual void RecomputeSurfaceFlags(model_t* mod) = 0; + + virtual void Studio_ReloadModels(ReloadType_t reloadType) = 0; + + virtual bool IsLoaded(const model_t* mod) = 0; + + virtual bool LastLoadedMapHasHDRLighting(void) = 0; + + virtual void ReloadFilesInList(IFileList* pFilesToReload) = 0; + + virtual const char* GetActiveMapName(void) = 0; +}; + +extern IModelLoader* modelloader; + +class CMapLoadHelper +{ +public: + CMapLoadHelper(int lumpToLoad); + ~CMapLoadHelper(void); + + byte* LumpBase(void); + int LumpSize(void); + int LumpOffset(void); + int LumpVersion() const; + const char* GetMapName(void); + char* GetLoadName(void); + char* GetDiskName(void); + struct worldbrushdata_t* GetMap(void); + + static void Init(model_t* pMapModel, const char* pLoadname); + static void InitFromMemory(model_t* pMapModel, const void* pData, int nDataSize); + static void Shutdown(void); + static int GetRefCount(void); + + static void FreeLightingLump(); + + static int LumpSize(int lumpId); + static int LumpOffset(int lumpId); + + void LoadLumpElement(int nElemIndex, int nElemSize, void* pData); + void LoadLumpData(int offset, int size, void* pData); + +private: + int m_nLumpSize; + int m_nLumpOffset; + int m_nLumpVersion; + byte* m_pRawData; + byte* m_pData; + byte* m_pUncompressedData; + + int m_nLumpID; + char m_szLumpFilename[MAX_PATH]; +}; + +void Mod_RecomputeTranslucency(model_t* mod, int nSkin, int nBody, void * pClientRenderable); + +int Mod_GameLumpSize(int lumpId); +int Mod_GameLumpVersion(int lumpId); +bool Mod_LoadGameLump(int lumpId, void* pBuffer, int size); + +int Mod_GetMaterialCount(model_t* mod); + +int Mod_GetModelMaterials(model_t* mod, int count, IMaterial** ppMaterial); + +bool Mod_MarkWaterSurfaces(model_t* pModel); + +void ConnectMDLCacheNotify(); +void DisconnectMDLCacheNotify(); + +void InitStudioModelState(model_t* pModel); + +char* GetMapNameOnDisk(char* pDiskName, const char* pFullMapName, unsigned int nDiskNameSize); + +extern bool g_bLoadedMapHasBakedPropLighting; +extern bool g_bBakedPropLightingNoSeparateHDR; + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/modes.h b/SpyCustom/sdk/modes.h new file mode 100644 index 0000000..21b91f5 --- /dev/null +++ b/SpyCustom/sdk/modes.h @@ -0,0 +1,15 @@ +#if !defined( MODES_H ) +#define MODES_H +#ifdef _WIN32 +#pragma once +#endif + +typedef struct vmode_s +{ + int width; + int height; + int bpp; + int refreshRate; +} vmode_t; + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/mouthinfo.h b/SpyCustom/sdk/mouthinfo.h new file mode 100644 index 0000000..42ba87d --- /dev/null +++ b/SpyCustom/sdk/mouthinfo.h @@ -0,0 +1,178 @@ +#if !defined( MOUTHINFO_H ) +#define MOUTHINFO_H +#ifdef _WIN32 +#pragma once +#endif + +class CAudioSource; + +#pragma pack(push,4) +class CVoiceData +{ +public: + CVoiceData(void) + { + m_flElapsed = 0.0f; + m_pAudioSource = NULL; + m_bIgnorePhonemes = false; + } + + void SetElapsedTime(float t) + { + m_flElapsed = t; + } + + float GetElapsedTime() const + { + return m_flElapsed; + } + + void SetSource(CAudioSource* source, bool bIgnorePhonemes) + { + m_pAudioSource = source; + m_bIgnorePhonemes = bIgnorePhonemes; + } + + bool ShouldIgnorePhonemes() const + { + return m_bIgnorePhonemes; + } + + CAudioSource* GetSource() + { + return m_pAudioSource; + } + +private: + float m_flElapsed; + CAudioSource* m_pAudioSource; + bool m_bIgnorePhonemes; +}; + +#define UNKNOWN_VOICE_SOURCE -1 + +class CMouthInfo +{ +public: + byte mouthopen; + byte sndcount; + int sndavg; + +public: + CMouthInfo(void) { m_nVoiceSources = 0; m_needsEnvelope = false; } + virtual ~CMouthInfo(void) { ClearVoiceSources(); } + + int GetNumVoiceSources(void); + CVoiceData* GetVoiceSource(int number); + + void ClearVoiceSources(void); + int GetIndexForSource(CAudioSource* source); + bool IsSourceReferenced(CAudioSource* source); + + CVoiceData* AddSource(CAudioSource* source, bool bIgnorePhonemes); + + void RemoveSource(CAudioSource* source); + void RemoveSourceByIndex(int index); + + bool IsActive(void); + bool NeedsEnvelope() { return m_needsEnvelope != 0; } + void ActivateEnvelope() { m_needsEnvelope = true; } + +private: + enum + { + MAX_VOICE_DATA = 4 + }; + + short m_nVoiceSources; + short m_needsEnvelope; + CVoiceData m_VoiceSources[MAX_VOICE_DATA]; +}; +#pragma pack(pop) + + +inline bool CMouthInfo::IsActive(void) +{ + return (GetNumVoiceSources() > 0) ? true : false; +} + +inline int CMouthInfo::GetNumVoiceSources(void) +{ + return m_nVoiceSources; +} + +inline CVoiceData* CMouthInfo::GetVoiceSource(int number) +{ + if (number < 0 || number >= m_nVoiceSources) + return NULL; + + return &m_VoiceSources[number]; +} + +inline void CMouthInfo::ClearVoiceSources(void) +{ + m_nVoiceSources = 0; +} + +inline int CMouthInfo::GetIndexForSource(CAudioSource* source) +{ + for (int i = 0; i < m_nVoiceSources; i++) + { + CVoiceData* v = &m_VoiceSources[i]; + if (!v) + continue; + + if (v->GetSource() == source) + return i; + } + + return UNKNOWN_VOICE_SOURCE; +} + +inline bool CMouthInfo::IsSourceReferenced(CAudioSource* source) +{ + if (GetIndexForSource(source) != UNKNOWN_VOICE_SOURCE) + return true; + + return false; +} + +inline void CMouthInfo::RemoveSource(CAudioSource* source) +{ + int idx = GetIndexForSource(source); + if (idx == UNKNOWN_VOICE_SOURCE) + return; + + RemoveSourceByIndex(idx); +} + +inline void CMouthInfo::RemoveSourceByIndex(int index) +{ + if (index < 0 || index >= m_nVoiceSources) + return; + + m_VoiceSources[index] = m_VoiceSources[--m_nVoiceSources]; +} + +inline CVoiceData* CMouthInfo::AddSource(CAudioSource* source, bool bIgnorePhonemes) +{ + int idx = GetIndexForSource(source); + if (idx == UNKNOWN_VOICE_SOURCE) + { + if (m_nVoiceSources < MAX_VOICE_DATA) + { + idx = m_nVoiceSources++; + } + else + { + return NULL; + } + } + + CVoiceData* data = &m_VoiceSources[idx]; + data->SetSource(source, bIgnorePhonemes); + data->SetElapsedTime(0.0f); + return data; +} + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/networkstringtabledefs.h b/SpyCustom/sdk/networkstringtabledefs.h new file mode 100644 index 0000000..396849a --- /dev/null +++ b/SpyCustom/sdk/networkstringtabledefs.h @@ -0,0 +1,63 @@ +#ifndef NETWORKSTRINGTABLEDEFS_H +#define NETWORKSTRINGTABLEDEFS_H +#ifdef _WIN32 +#pragma once +#endif + +typedef int TABLEID; + +#define INVALID_STRING_TABLE -1 +const unsigned short INVALID_STRING_INDEX = (unsigned short)-1; + +#define MAX_TABLES 32 + +#define INTERFACENAME_NETWORKSTRINGTABLESERVER "VEngineServerStringTable001" +#define INTERFACENAME_NETWORKSTRINGTABLECLIENT "VEngineClientStringTable001" + +class INetworkStringTable; + +typedef void (*pfnStringChanged)(void* object, INetworkStringTable* stringTable, int stringNumber, char const* newString, void const* newData); + +class INetworkStringTable +{ +public: + + virtual ~INetworkStringTable(void) {}; + + virtual const char* GetTableName(void) const = 0; + virtual TABLEID GetTableId(void) const = 0; + virtual int GetNumStrings(void) const = 0; + virtual int GetMaxStrings(void) const = 0; + virtual int GetEntryBits(void) const = 0; + + virtual void SetTick(int tick) = 0; + virtual bool ChangedSinceTick(int tick) const = 0; + + virtual int AddString(bool bIsServer, const char* value, int length = -1, const void* userdata = 0) = 0; + + virtual const char* GetString(int stringNumber) = 0; + virtual void SetStringUserData(int stringNumber, int length, const void* userdata) = 0; + virtual const void* GetStringUserData(int stringNumber, int* length) = 0; + virtual int FindStringIndex(char const* string) = 0; + + virtual void SetStringChangedCallback(void* object, pfnStringChanged changeFunc) = 0; +}; + +class INetworkStringTableContainer +{ +public: + + virtual ~INetworkStringTableContainer(void) {}; + + virtual INetworkStringTable* CreateStringTable(const char* tableName, int maxentries, int userdatafixedsize = 0, int userdatanetworkbits = 0) = 0; + virtual void RemoveAllTables(void) = 0; + + virtual INetworkStringTable* FindTable(const char* tableName) const = 0; + virtual INetworkStringTable* GetTable(TABLEID stringTable) const = 0; + virtual int GetNumTables(void) const = 0; + + virtual INetworkStringTable* CreateStringTableEx(const char* tableName, int maxentries, int userdatafixedsize = 0, int userdatanetworkbits = 0, bool bIsFilenames = false) = 0; + virtual void SetAllowClientSideAddString(INetworkStringTable* table, bool bAllowClientSideAddString) = 0; +}; + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/networkvar.h b/SpyCustom/sdk/networkvar.h new file mode 100644 index 0000000..ff0b261 --- /dev/null +++ b/SpyCustom/sdk/networkvar.h @@ -0,0 +1,737 @@ +#ifndef NETWORKVAR_H +#define NETWORKVAR_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "dbg.h" +#include "convar.h" + +#if defined( CLIENT_DLL ) || defined( GAME_DLL ) +#include "basehandle.h" +#endif + + +#pragma warning( disable : 4284 ) + +#define MyOffsetOf( type, var ) ( (int)&((type*)0)->var ) + +#ifdef _DEBUG +extern bool g_bUseNetworkVars; +#define CHECK_USENETWORKVARS if(g_bUseNetworkVars) +#else +#define CHECK_USENETWORKVARS +#endif + + + +inline int InternalCheckDeclareClass(const char* pClassName, const char* pClassNameMatch, void* pTestPtr, void* pBasePtr) +{ + Assert(pTestPtr == pBasePtr); + + Assert((void*)pClassName == (void*)pClassNameMatch); + return 0; +} + + +template +inline int CheckDeclareClass_Access(T*, const char* pShouldBe) +{ + return T::CheckDeclareClass(pShouldBe); +} + +#ifndef _STATIC_LINKED +#ifdef _MSC_VER +#if defined(_DEBUG) && (_MSC_VER > 1200 ) +#define VALIDATE_DECLARE_CLASS 1 +#endif +#endif +#endif + +#ifdef VALIDATE_DECLARE_CLASS + +#define DECLARE_CLASS( className, baseClassName ) \ + typedef baseClassName BaseClass; \ + typedef className ThisClass; \ + template friend int CheckDeclareClass_Access(T *, const char *pShouldBe); \ + static int CheckDeclareClass( const char *pShouldBe ) \ + { \ + InternalCheckDeclareClass( pShouldBe, #className, (ThisClass*)0xFFFFF, (BaseClass*)(ThisClass*)0xFFFFF ); \ + return CheckDeclareClass_Access( (BaseClass *)NULL, #baseClassName ); \ + } + +#define DECLARE_CLASS_GAMEROOT( className, baseClassName ) \ + typedef baseClassName BaseClass; \ + typedef className ThisClass; \ + template friend int CheckDeclareClass_Access(T *, const char *pShouldBe); \ + static int CheckDeclareClass( const char *pShouldBe ) \ + { \ + return InternalCheckDeclareClass( pShouldBe, #className, (ThisClass*)0xFFFFF, (BaseClass*)(ThisClass*)0xFFFFF ); \ + } + +#define DECLARE_CLASS_NOFRIEND( className, baseClassName ) \ + DECLARE_CLASS( className, baseClassName ) + +#define DECLARE_CLASS_NOBASE( className ) \ + typedef className ThisClass; \ + template friend int CheckDeclareClass_Access(T *, const char *pShouldBe); \ + static int CheckDeclareClass( const char *pShouldBe ) \ + { \ + return InternalCheckDeclareClass( pShouldBe, #className, 0, 0 ); \ + } + +#else +#define DECLARE_CLASS( className, baseClassName ) \ + typedef baseClassName BaseClass; \ + typedef className ThisClass; + +#define DECLARE_CLASS_GAMEROOT( className, baseClassName ) DECLARE_CLASS( className, baseClassName ) +#define DECLARE_CLASS_NOFRIEND( className, baseClassName ) DECLARE_CLASS( className, baseClassName ) + +#define DECLARE_CLASS_NOBASE( className ) typedef className ThisClass; +#endif + + + + +class CBaseEntity; +class CAutoInitEntPtr +{ +public: + CAutoInitEntPtr() + { + m_pEnt = NULL; + } + CBaseEntity* m_pEnt; +}; + +#define DECLARE_NETWORKVAR_CHAIN() \ + CAutoInitEntPtr __m_pChainEntity; \ + void NetworkStateChanged() { CHECK_USENETWORKVARS __m_pChainEntity.m_pEnt->NetworkStateChanged(); } \ + void NetworkStateChanged( void *pVar ) { CHECK_USENETWORKVARS __m_pChainEntity.m_pEnt->NetworkStateChanged(); } + +#define IMPLEMENT_NETWORKVAR_CHAIN( varName ) \ + (varName)->__m_pChainEntity.m_pEnt = this; + + + +template< class T > +static inline void DispatchNetworkStateChanged(T* pObj) +{ + CHECK_USENETWORKVARS pObj->NetworkStateChanged(); +} +template< class T > +static inline void DispatchNetworkStateChanged(T* pObj, void* pVar) +{ + CHECK_USENETWORKVARS pObj->NetworkStateChanged(pVar); +} + + +#define DECLARE_EMBEDDED_NETWORKVAR() \ + template friend int ServerClassInit(T *); \ + template friend int ClientClassInit(T *); \ + virtual void NetworkStateChanged() {} virtual void NetworkStateChanged( void *pProp ) {} + +#define CNetworkVarEmbedded( type, name ) \ + class NetworkVar_##name; \ + friend class NetworkVar_##name; \ + static inline int GetOffset_##name() { return MyOffsetOf(ThisClass,name); } \ + typedef ThisClass ThisClass_##name; \ + class NetworkVar_##name : public type \ + { \ + template< class T > NetworkVar_##name& operator=( const T &val ) { *((type*)this) = val; return *this; } \ + public: \ + void CopyFrom( const type &src ) { *((type *)this) = src; NetworkStateChanged(); } \ + virtual void NetworkStateChanged() \ + { \ + DispatchNetworkStateChanged( (ThisClass_##name*)( ((char*)this) - GetOffset_##name() ) ); \ + } \ + virtual void NetworkStateChanged( void *pVar ) \ + { \ + DispatchNetworkStateChanged( (ThisClass_##name*)( ((char*)this) - GetOffset_##name() ), pVar ); \ + } \ + }; \ + NetworkVar_##name name; + +template +FORCEINLINE void NetworkVarConstruct(T& x) { x = T(0); } +FORCEINLINE void NetworkVarConstruct(color32_s& x) { x.r = x.g = x.b = x.a = 0; } + +template< class Type, class Changer > +class CNetworkVarBase +{ +public: + inline CNetworkVarBase() + { + NetworkVarConstruct(m_Value); + } + + template< class C > + const Type& operator=(const C& val) + { + return Set((const Type)val); + } + + template< class C > + const Type& operator=(const CNetworkVarBase< C, Changer >& val) + { + return Set((const Type)val.m_Value); + } + + const Type& Set(const Type& val) + { + if (memcmp(&m_Value, &val, sizeof(Type))) + { + NetworkStateChanged(); + m_Value = val; + } + return m_Value; + } + + Type& GetForModify() + { + NetworkStateChanged(); + return m_Value; + } + + template< class C > + const Type& operator+=(const C& val) + { + return Set(m_Value + (const Type)val); + } + + template< class C > + const Type& operator-=(const C& val) + { + return Set(m_Value - (const Type)val); + } + + template< class C > + const Type& operator/=(const C& val) + { + return Set(m_Value / (const Type)val); + } + + template< class C > + const Type& operator*=(const C& val) + { + return Set(m_Value * (const Type)val); + } + + template< class C > + const Type& operator^=(const C& val) + { + return Set(m_Value ^ (const Type)val); + } + + template< class C > + const Type& operator|=(const C& val) + { + return Set(m_Value | (const Type)val); + } + + const Type& operator++() + { + return (*this += 1); + } + + Type operator--() + { + return (*this -= 1); + } + + Type operator++(int) + { + Type val = m_Value; + (*this += 1); + return val; + } + + Type operator--(int) + { + Type val = m_Value; + (*this -= 1); + return val; + } + + template< class C > + const Type& operator&=(const C& val) + { + return Set(m_Value & (const Type)val); + } + + operator const Type& () const + { + return m_Value; + } + + const Type& Get() const + { + return m_Value; + } + + const Type* operator->() const + { + return &m_Value; + } + + Type m_Value; + +protected: + inline void NetworkStateChanged() + { + Changer::NetworkStateChanged(this); + } +}; + + +template< class Type, class Changer > +class CNetworkColor32Base : public CNetworkVarBase< Type, Changer > +{ +public: + inline void Init(byte rVal, byte gVal, byte bVal) + { + SetR(rVal); + SetG(gVal); + SetB(bVal); + } + inline void Init(byte rVal, byte gVal, byte bVal, byte aVal) + { + SetR(rVal); + SetG(gVal); + SetB(bVal); + SetA(aVal); + } + + const Type& operator=(const Type& val) + { + return this->Set(val); + } + + const Type& operator=(const CNetworkColor32Base& val) + { + return CNetworkVarBase::Set(val.m_Value); + } + + inline byte GetR() const { return CNetworkColor32Base::m_Value.r; } + inline byte GetG() const { return CNetworkColor32Base::m_Value.g; } + inline byte GetB() const { return CNetworkColor32Base::m_Value.b; } + inline byte GetA() const { return CNetworkColor32Base::m_Value.a; } + inline void SetR(byte val) { SetVal(CNetworkColor32Base::m_Value.r, val); } + inline void SetG(byte val) { SetVal(CNetworkColor32Base::m_Value.g, val); } + inline void SetB(byte val) { SetVal(CNetworkColor32Base::m_Value.b, val); } + inline void SetA(byte val) { SetVal(CNetworkColor32Base::m_Value.a, val); } + +protected: + inline void SetVal(byte& out, const byte& in) + { + if (out != in) + { + CNetworkVarBase< Type, Changer >::NetworkStateChanged(); + out = in; + } + } +}; + + +template< class Type, class Changer > +class CNetworkVectorBase : public CNetworkVarBase< Type, Changer > +{ +public: + inline void Init(float ix = 0, float iy = 0, float iz = 0) + { + SetX(ix); + SetY(iy); + SetZ(iz); + } + + const Type& operator=(const Type& val) + { + return CNetworkVarBase< Type, Changer >::Set(val); + } + + const Type& operator=(const CNetworkVectorBase& val) + { + return CNetworkVarBase::Set(val.m_Value); + } + + inline float GetX() const { return CNetworkVectorBase::m_Value.x; } + inline float GetY() const { return CNetworkVectorBase::m_Value.y; } + inline float GetZ() const { return CNetworkVectorBase::m_Value.z; } + inline float operator[](int i) const { return CNetworkVectorBase::m_Value[i]; } + + inline void SetX(float val) { DetectChange(CNetworkVectorBase::m_Value.x, val); } + inline void SetY(float val) { DetectChange(CNetworkVectorBase::m_Value.y, val); } + inline void SetZ(float val) { DetectChange(CNetworkVectorBase::m_Value.z, val); } + inline void Set(int i, float val) { DetectChange(CNetworkVectorBase::m_Value[i], val); } + + bool operator==(const Type& val) const + { + return CNetworkVectorBase::m_Value == (Type)val; + } + + bool operator!=(const Type& val) const + { + return CNetworkVectorBase::m_Value != (Type)val; + } + + const Type operator+(const Type& val) const + { + return CNetworkVectorBase::m_Value + val; + } + + const Type operator-(const Type& val) const + { + return CNetworkVectorBase::m_Value - val; + } + + const Type operator*(const Type& val) const + { + return CNetworkVectorBase::m_Value * val; + } + + const Type& operator*=(float val) + { + return CNetworkVarBase< Type, Changer >::Set(CNetworkVectorBase::m_Value * val); + } + + const Type operator*(float val) const + { + return CNetworkVectorBase::m_Value * val; + } + + const Type operator/(const Type& val) const + { + return CNetworkVectorBase::m_Value / val; + } + +private: + inline void DetectChange(float& out, float in) + { + if (out != in) + { + CNetworkVectorBase::NetworkStateChanged(); + out = in; + } + } +}; + + +template< class Type, class Changer > +class CNetworkQuaternionBase : public CNetworkVarBase< Type, Changer > +{ +public: + inline void Init(float ix = 0, float iy = 0, float iz = 0, float iw = 0) + { + SetX(ix); + SetY(iy); + SetZ(iz); + SetW(iw); + } + + const Type& operator=(const Type& val) + { + return CNetworkVarBase< Type, Changer >::Set(val); + } + + const Type& operator=(const CNetworkQuaternionBase& val) + { + return CNetworkVarBase::Set(val.m_Value); + } + + inline float GetX() const { return CNetworkQuaternionBase::m_Value.x; } + inline float GetY() const { return CNetworkQuaternionBase::m_Value.y; } + inline float GetZ() const { return CNetworkQuaternionBase::m_Value.z; } + inline float GetW() const { return CNetworkQuaternionBase::m_Value.w; } + inline float operator[](int i) const { return CNetworkQuaternionBase::m_Value[i]; } + + inline void SetX(float val) { DetectChange(CNetworkQuaternionBase::m_Value.x, val); } + inline void SetY(float val) { DetectChange(CNetworkQuaternionBase::m_Value.y, val); } + inline void SetZ(float val) { DetectChange(CNetworkQuaternionBase::m_Value.z, val); } + inline void SetW(float val) { DetectChange(CNetworkQuaternionBase::m_Value.w, val); } + inline void Set(int i, float val) { DetectChange(CNetworkQuaternionBase::m_Value[i], val); } + + bool operator==(const Type& val) const + { + return CNetworkQuaternionBase::m_Value == (Type)val; + } + + bool operator!=(const Type& val) const + { + return CNetworkQuaternionBase::m_Value != (Type)val; + } + + const Type operator+(const Type& val) const + { + return CNetworkQuaternionBase::m_Value + val; + } + + const Type operator-(const Type& val) const + { + return CNetworkQuaternionBase::m_Value - val; + } + + const Type operator*(const Type& val) const + { + return CNetworkQuaternionBase::m_Value * val; + } + + const Type& operator*=(float val) + { + return CNetworkQuaternionBase< Type, Changer >::Set(CNetworkQuaternionBase::m_Value * val); + } + + const Type operator*(float val) const + { + return CNetworkQuaternionBase::m_Value * val; + } + + const Type operator/(const Type& val) const + { + return CNetworkQuaternionBase::m_Value / val; + } + +private: + inline void DetectChange(float& out, float in) + { + if (out != in) + { + CNetworkQuaternionBase::NetworkStateChanged(); + out = in; + } + } +}; + + +#if defined( CLIENT_DLL ) || defined( GAME_DLL ) +inline void NetworkVarConstruct(CBaseHandle& x) {} + +template< class Type, class Changer > +class CNetworkHandleBase : public CNetworkVarBase< CBaseHandle, Changer > +{ +public: + const Type* operator=(const Type* val) + { + return Set(val); + } + + const Type& operator=(const CNetworkHandleBase& val) + { + const CBaseHandle& handle = CNetworkVarBase::Set(val.m_Value); + return *(const Type*)handle.Get(); + } + + bool operator !() const + { + return !CNetworkHandleBase::m_Value.Get(); + } + + operator Type* () const + { + return static_cast(CNetworkHandleBase::m_Value.Get()); + } + + const Type* Set(const Type* val) + { + if (CNetworkHandleBase::m_Value != val) + { + this->NetworkStateChanged(); + CNetworkHandleBase::m_Value = val; + } + return val; + } + + Type* Get() const + { + return static_cast(CNetworkHandleBase::m_Value.Get()); + } + + Type* operator->() const + { + return static_cast(CNetworkHandleBase::m_Value.Get()); + } + + bool operator==(const Type* val) const + { + return CNetworkHandleBase::m_Value == val; + } + + bool operator!=(const Type* val) const + { + return CNetworkHandleBase::m_Value != val; + } +}; + +#define CNetworkHandle( type, name ) CNetworkHandleInternal( type, name, NetworkStateChanged ) + +#define CNetworkHandleInternal( type, name, stateChangedFn ) \ + NETWORK_VAR_START( type, name ) \ + NETWORK_VAR_END( type, name, CNetworkHandleBase, stateChangedFn ) +#endif + + +#define CNetworkVar( type, name ) \ + NETWORK_VAR_START( type, name ) \ + NETWORK_VAR_END( type, name, CNetworkVarBase, NetworkStateChanged ) + + +#define CNetworkVarForDerived( type, name ) \ + virtual void NetworkStateChanged_##name() {} \ + virtual void NetworkStateChanged_##name( void *pVar ) {} \ + NETWORK_VAR_START( type, name ) \ + NETWORK_VAR_END( type, name, CNetworkVarBase, NetworkStateChanged_##name ) + +#define CNetworkVectorForDerived( name ) \ + virtual void NetworkStateChanged_##name() {} \ + virtual void NetworkStateChanged_##name( void *pVar ) {} \ + CNetworkVectorInternal( Vector, name, NetworkStateChanged_##name ) + +#define CNetworkHandleForDerived( type, name ) \ + virtual void NetworkStateChanged_##name() {} \ + virtual void NetworkStateChanged_##name( void *pVar ) {} \ + CNetworkHandleInternal( type, name, NetworkStateChanged_##name ) + +#define CNetworkArrayForDerived( type, name, count ) \ + virtual void NetworkStateChanged_##name() {} \ + virtual void NetworkStateChanged_##name( void *pVar ) {} \ + CNetworkArrayInternal( type, name, count, NetworkStateChanged_##name ) + +#define IMPLEMENT_NETWORK_VAR_FOR_DERIVED( name ) \ + virtual void NetworkStateChanged_##name() { CHECK_USENETWORKVARS NetworkStateChanged(); } \ + virtual void NetworkStateChanged_##name( void *pVar ) { CHECK_USENETWORKVARS NetworkStateChanged( pVar ); } + + +#define CNetworkVarForDerived_OnByDefault( type, name ) \ + virtual void NetworkStateChanged_##name() { CHECK_USENETWORKVARS NetworkStateChanged(); } \ + virtual void NetworkStateChanged_##name( void *pVar ) { CHECK_USENETWORKVARS NetworkStateChanged( pVar ); } \ + NETWORK_VAR_START( type, name ) \ + NETWORK_VAR_END( type, name, CNetworkVarBase, NetworkStateChanged_##name ) + +#define DISABLE_NETWORK_VAR_FOR_DERIVED( name ) \ + virtual void NetworkStateChanged_##name() {} \ + virtual void NetworkStateChanged_##name( void *pVar ) {} + + + +#define CNetworkVector( name ) CNetworkVectorInternal( Vector, name, NetworkStateChanged ) +#define CNetworkQAngle( name ) CNetworkVectorInternal( QAngle, name, NetworkStateChanged ) + +#define CNetworkVectorInternal( type, name, stateChangedFn ) \ + NETWORK_VAR_START( type, name ) \ + NETWORK_VAR_END( type, name, CNetworkVectorBase, stateChangedFn ) + +#define CNetworkQuaternion( name ) \ + NETWORK_VAR_START( Quaternion, name ) \ + NETWORK_VAR_END( Quaternion, name, CNetworkQuaternionBase, NetworkStateChanged ) + +#define CNetworkColor32( name ) \ + NETWORK_VAR_START( color32, name ) \ + NETWORK_VAR_END( color32, name, CNetworkColor32Base, NetworkStateChanged ) + + +#define CNetworkString( name, length ) \ + class NetworkVar_##name; \ + friend class NetworkVar_##name; \ + typedef ThisClass MakeANetworkVar_##name; \ + class NetworkVar_##name \ + { \ + public: \ + NetworkVar_##name() { m_Value[0] = '\0'; } \ + operator const char*() const { return m_Value; } \ + const char* Get() const { return m_Value; } \ + char* GetForModify() \ + { \ + NetworkStateChanged(); \ + return m_Value; \ + } \ + protected: \ + inline void NetworkStateChanged() \ + { \ + CHECK_USENETWORKVARS ((ThisClass*)(((char*)this) - MyOffsetOf(ThisClass,name)))->NetworkStateChanged(); \ + } \ + private: \ + char m_Value[length]; \ + }; \ + NetworkVar_##name name; + + + + +#define CNetworkArrayInternal( type, name, count, stateChangedFn ) \ + class NetworkVar_##name; \ + friend class NetworkVar_##name; \ + typedef ThisClass MakeANetworkVar_##name; \ + class NetworkVar_##name \ + { \ + public: \ + inline NetworkVar_##name() \ + { \ + for ( int i = 0 ; i < count ; ++i ) \ + NetworkVarConstruct( m_Value[i] ); \ + } \ + template friend int ServerClassInit(T *); \ + const type& operator[]( int i ) const \ + { \ + return Get( i ); \ + } \ + \ + const type& Get( int i ) const \ + { \ + Assert( i >= 0 && i < count ); \ + return m_Value[i]; \ + } \ + \ + type& GetForModify( int i ) \ + { \ + Assert( i >= 0 && i < count ); \ + NetworkStateChanged( i ); \ + return m_Value[i]; \ + } \ + \ + void Set( int i, const type &val ) \ + { \ + Assert( i >= 0 && i < count ); \ + if( memcmp( &m_Value[i], &val, sizeof(type) ) ) \ + { \ + NetworkStateChanged( i ); \ + m_Value[i] = val; \ + } \ + } \ + const type* Base() const { return m_Value; } \ + int Count() const { return count; } \ + protected: \ + inline void NetworkStateChanged( int index ) \ + { \ + CHECK_USENETWORKVARS ((ThisClass*)(((char*)this) - MyOffsetOf(ThisClass,name)))->stateChangedFn( &m_Value[index] ); \ + } \ + type m_Value[count]; \ + }; \ + NetworkVar_##name name; + + +#define CNetworkArray( type, name, count ) CNetworkArrayInternal( type, name, count, NetworkStateChanged ) + + +#define NETWORK_VAR_START( type, name ) \ + class NetworkVar_##name; \ + friend class NetworkVar_##name; \ + typedef ThisClass MakeANetworkVar_##name; \ + class NetworkVar_##name \ + { \ + public: \ + template friend int ServerClassInit(T *); + + +#define NETWORK_VAR_END( type, name, base, stateChangedFn ) \ + public: \ + static inline void NetworkStateChanged( void *ptr ) \ + { \ + CHECK_USENETWORKVARS ((ThisClass*)(((char*)ptr) - MyOffsetOf(ThisClass,name)))->stateChangedFn( ptr ); \ + } \ + }; \ + base< type, NetworkVar_##name > name; + + + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/particle_iterators.h b/SpyCustom/sdk/particle_iterators.h new file mode 100644 index 0000000..46e42fb --- /dev/null +++ b/SpyCustom/sdk/particle_iterators.h @@ -0,0 +1,222 @@ +#ifndef PARTICLE_ITERATORS_H +#define PARTICLE_ITERATORS_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "imesh.h" +#include "particledraw.h" + + +#define NUM_PARTICLES_PER_BATCH 200 +#ifndef _XBOX +#define MAX_TOTAL_PARTICLES 2048 +#else +#define MAX_TOTAL_PARTICLES 1024 +#endif + + +class CParticleRenderIterator +{ + friend class CParticleMgr; + friend class CParticleEffectBinding; +public: + CParticleRenderIterator(); + + const Particle* GetFirst(); + const Particle* GetNext(float sortKey); + + ParticleDraw* GetParticleDraw() const; + + +private: + + void TestFlushBatch(); + + +private: + CParticleEffectBinding* m_pEffectBinding; + CEffectMaterial* m_pMaterial; + ParticleDraw* m_pParticleDraw; + CMeshBuilder* m_pMeshBuilder; + IMesh* m_pMesh; + bool m_bBucketSort; + + float m_MinZ; + float m_MaxZ; + float m_zCoords[MAX_TOTAL_PARTICLES]; + int m_nZCoords; + + Particle* m_pCur; + bool m_bGotFirst; + float m_flPrevZ; + int m_nParticlesInCurrentBatch; +}; + + +class CParticleSimulateIterator +{ + friend class CParticleMgr; + friend class CParticleEffectBinding; +public: + CParticleSimulateIterator(); + + Particle* GetFirst(); + Particle* GetNext(); + float GetTimeDelta() const; + + void RemoveParticle(Particle* pParticle); + void RemoveAllParticles(); + +private: + CParticleEffectBinding* m_pEffectBinding; + CEffectMaterial* m_pMaterial; + float m_flTimeDelta; + + bool m_bGotFirst; + Particle* m_pNextParticle; +}; + + +inline CParticleRenderIterator::CParticleRenderIterator() +{ + m_pCur = NULL; + m_bGotFirst = false; + m_flPrevZ = 0; + m_nParticlesInCurrentBatch = 0; + m_MinZ = 1e24; + m_MaxZ = -1e24; + m_nZCoords = 0; +} + +inline const Particle* CParticleRenderIterator::GetFirst() +{ + Assert(!m_bGotFirst); + m_bGotFirst = true; + + m_pCur = m_pMaterial->m_Particles.m_pNext; + if (m_pCur == &m_pMaterial->m_Particles) + return NULL; + + m_pParticleDraw->m_pSubTexture = m_pCur->m_pSubTexture; + return m_pCur; +} + +inline void CParticleRenderIterator::TestFlushBatch() +{ + ++m_nParticlesInCurrentBatch; + if (m_nParticlesInCurrentBatch >= NUM_PARTICLES_PER_BATCH) + { + m_pMeshBuilder->End(false, true); + m_pMeshBuilder->Begin(m_pMesh, MATERIAL_QUADS, NUM_PARTICLES_PER_BATCH * 4); + + m_nParticlesInCurrentBatch = 0; + } +} + +inline const Particle* CParticleRenderIterator::GetNext(float sortKey) +{ + Assert(m_bGotFirst); + Assert(m_pCur); + + TestFlushBatch(); + + Particle* pNext = m_pCur->m_pNext; + + if (m_bBucketSort) + { + m_MinZ = MIN(sortKey, m_MinZ); + m_MaxZ = MAX(sortKey, m_MaxZ); + + m_zCoords[m_nZCoords] = sortKey; + ++m_nZCoords; + } + else + { + if (m_pCur != m_pMaterial->m_Particles.m_pNext && m_flPrevZ > sortKey) + { + SwapParticles(m_pCur->m_pPrev, m_pCur); + } + else + { + m_flPrevZ = sortKey; + } + } + + m_pCur = pNext; + if (m_pCur == &m_pMaterial->m_Particles) + return NULL; + + m_pParticleDraw->m_pSubTexture = m_pCur->m_pSubTexture; + return m_pCur; +} + +inline ParticleDraw* CParticleRenderIterator::GetParticleDraw() const +{ + return m_pParticleDraw; +} + + +inline CParticleSimulateIterator::CParticleSimulateIterator() +{ + m_pNextParticle = NULL; +#ifdef _DEBUG + m_bGotFirst = false; +#endif +} + +inline Particle* CParticleSimulateIterator::GetFirst() +{ +#ifdef _DEBUG + if (m_bGotFirst) + { + Assert(m_pNextParticle == &m_pMaterial->m_Particles); + } +#endif + + Particle* pRet = m_pMaterial->m_Particles.m_pNext; + if (pRet == &m_pMaterial->m_Particles) + return NULL; + +#ifdef _DEBUG + m_bGotFirst = true; +#endif + + m_pNextParticle = pRet->m_pNext; + return pRet; +} + +inline Particle* CParticleSimulateIterator::GetNext() +{ + Particle* pRet = m_pNextParticle; + + if (pRet == &m_pMaterial->m_Particles) + return NULL; + + m_pNextParticle = pRet->m_pNext; + return pRet; +} + +inline void CParticleSimulateIterator::RemoveParticle(Particle* pParticle) +{ + m_pEffectBinding->RemoveParticle(pParticle); +} + +inline void CParticleSimulateIterator::RemoveAllParticles() +{ + Particle* pParticle = GetFirst(); + while (pParticle) + { + RemoveParticle(pParticle); + pParticle = GetNext(); + } +} + +inline float CParticleSimulateIterator::GetTimeDelta() const +{ + return m_flTimeDelta; +} + + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/particle_parse.h b/SpyCustom/sdk/particle_parse.h new file mode 100644 index 0000000..4a4c415 --- /dev/null +++ b/SpyCustom/sdk/particle_parse.h @@ -0,0 +1,66 @@ +#ifndef PARTICLE_PARSE_H +#define PARTICLE_PARSE_H +#ifdef _WIN32 +#pragma once +#endif + +#include "utlvector.h" +#include "utlstring.h" +#include "ifilelist.h" + +enum ParticleAttachment_t +{ + PATTACH_ABSORIGIN = 0, + PATTACH_ABSORIGIN_FOLLOW, + PATTACH_CUSTOMORIGIN, + PATTACH_POINT, + PATTACH_POINT_FOLLOW, + + PATTACH_WORLDORIGIN, + + PATTACH_ROOTBONE_FOLLOW, + + MAX_PATTACH_TYPES, +}; + +extern int GetAttachTypeFromString(const char* pszString); + +#define PARTICLE_DISPATCH_FROM_ENTITY (1<<0) +#define PARTICLE_DISPATCH_RESET_PARTICLES (1<<1) + +struct te_tf_particle_effects_colors_t +{ + Vector m_vecColor1; + Vector m_vecColor2; +}; + +struct te_tf_particle_effects_control_point_t +{ + ParticleAttachment_t m_eParticleAttachment; + Vector m_vecOffset; +}; + +void ParseParticleEffects(bool bLoadSheets, bool bPrecache); +void ParseParticleEffectsMap(const char* pMapName, bool bLoadSheets, IFileList* pFilesToReload = NULL); + +void GetParticleManifest(CUtlVector& list); + +void PrecacheStandardParticleSystems(); + +class IFileList; +void ReloadParticleEffectsInList(IFileList* pFilesToReload); + +void DispatchParticleEffect(const char* pszParticleName, ParticleAttachment_t iAttachType, CBaseEntity* pEntity, const char* pszAttachmentName, bool bResetAllParticlesOnEntity = false); +void DispatchParticleEffect(const char* pszParticleName, ParticleAttachment_t iAttachType, CBaseEntity* pEntity = NULL, int iAttachmentPoint = -1, bool bResetAllParticlesOnEntity = false); +void DispatchParticleEffect(const char* pszParticleName, Vector vecOrigin, QAngle vecAngles, CBaseEntity* pEntity = NULL); +void DispatchParticleEffect(const char* pszParticleName, Vector vecOrigin, Vector vecStart, QAngle vecAngles, CBaseEntity* pEntity = NULL); +void DispatchParticleEffect(int iEffectIndex, Vector vecOrigin, Vector vecStart, QAngle vecAngles, CBaseEntity* pEntity = NULL); + +void DispatchParticleEffect(const char* pszParticleName, ParticleAttachment_t iAttachType, CBaseEntity* pEntity, const char* pszAttachmentName, Vector vecColor1, Vector vecColor2, bool bUseColors = true, bool bResetAllParticlesOnEntity = false); +void DispatchParticleEffect(const char* pszParticleName, Vector vecOrigin, QAngle vecAngles, Vector vecColor1, Vector vecColor2, bool bUseColors = true, CBaseEntity* pEntity = NULL, int iAttachType = PATTACH_CUSTOMORIGIN); + + +void StopParticleEffects(CBaseEntity* pEntity); + + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/particle_property.h b/SpyCustom/sdk/particle_property.h new file mode 100644 index 0000000..43012c0 --- /dev/null +++ b/SpyCustom/sdk/particle_property.h @@ -0,0 +1,110 @@ +#ifndef PARTICLEPROPERTY_H +#define PARTICLEPROPERTY_H +#ifdef _WIN32 +#pragma once +#endif + +#include "smartptr.h" +#include "globalvars_base.h" +#include "particles_new.h" +#include "particle_parse.h" + +class CBaseEntity; +class CNewParticleEffect; + +#ifdef CLIENT_DLL +#define INVALID_PARTICLE_ATTACHMENT 0 +#else +#define INVALID_PARTICLE_ATTACHMENT -1 +#endif + +struct ParticleControlPoint_t +{ + ParticleControlPoint_t() + { + iControlPoint = 0; + iAttachType = PATTACH_ABSORIGIN_FOLLOW; + iAttachmentPoint = 0; + vecOriginOffset = vec3_origin; + } + + int iControlPoint; + ParticleAttachment_t iAttachType; + int iAttachmentPoint; + Vector vecOriginOffset; + EHANDLE hEntity; +}; + +struct ParticleEffectList_t +{ + ParticleEffectList_t() + { + pParticleEffect = NULL; + } + + CUtlVector pControlPoints; + CSmartPtr pParticleEffect; +}; + +extern int GetAttachTypeFromString(const char* pszString); + +class CParticleProperty +{ + DECLARE_CLASS_NOBASE(CParticleProperty); + DECLARE_EMBEDDED_NETWORKVAR(); + DECLARE_PREDICTABLE(); + DECLARE_DATADESC(); + +public: + CParticleProperty(); + ~CParticleProperty(); + + void Init(CBaseEntity* pEntity); + CBaseEntity* GetOuter(void) { return m_pOuter; } + + CNewParticleEffect* Create(const char* pszParticleName, ParticleAttachment_t iAttachType, const char* pszAttachmentName); + CNewParticleEffect* Create(const char* pszParticleName, ParticleAttachment_t iAttachType, int iAttachmentPoint = INVALID_PARTICLE_ATTACHMENT, Vector vecOriginOffset = vec3_origin); + void AddControlPoint(CNewParticleEffect* pEffect, int iPoint, C_BaseEntity* pEntity, ParticleAttachment_t iAttachType, const char* pszAttachmentName = NULL, Vector vecOriginOffset = vec3_origin); + void AddControlPoint(int iEffectIndex, int iPoint, C_BaseEntity* pEntity, ParticleAttachment_t iAttachType, int iAttachmentPoint = INVALID_PARTICLE_ATTACHMENT, Vector vecOriginOffset = vec3_origin); + + inline void SetControlPointParent(CNewParticleEffect* pEffect, int whichControlPoint, int parentIdx); + void SetControlPointParent(int iEffectIndex, int whichControlPoint, int parentIdx); + + void StopEmission(CNewParticleEffect* pEffect = NULL, bool bWakeOnStop = false, bool bDestroyAsleepSystems = false); + void StopEmissionAndDestroyImmediately(CNewParticleEffect* pEffect = NULL); + + void StopParticlesInvolving(CBaseEntity* pEntity); + void StopParticlesNamed(const char* pszEffectName, bool bForceRemoveInstantly = false); + void StopParticlesWithNameAndAttachment(const char* pszEffectName, int iAttachmentPoint, bool bForceRemoveInstantly = false); + + void OnParticleSystemUpdated(CNewParticleEffect* pEffect, float flTimeDelta); + void OnParticleSystemDeleted(CNewParticleEffect* pEffect); + +#ifdef CLIENT_DLL + void OwnerSetDormantTo(bool bDormant); +#endif + + void ReplaceParticleEffect(CNewParticleEffect* pOldEffect, CNewParticleEffect* pNewEffect); + + void DebugPrintEffects(void); + + int FindEffect(const char* pEffectName, int nStart = 0); + inline CNewParticleEffect* GetParticleEffectFromIdx(int idx); + +private: + int GetParticleAttachment(C_BaseEntity* pEntity, const char* pszAttachmentName, const char* pszParticleName); + int FindEffect(CNewParticleEffect* pEffect); + void UpdateParticleEffect(ParticleEffectList_t* pEffect, bool bInitializing = false, int iOnlyThisControlPoint = -1); + void UpdateControlPoint(ParticleEffectList_t* pEffect, int iPoint, bool bInitializing); + +private: + CBaseEntity* m_pOuter; + CUtlVector m_ParticleEffects; + int m_iDormancyChangedAtFrame; + + friend class CBaseEntity; +}; + +#include "particle_property_inlines.h" + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/particle_property_inlines.h b/SpyCustom/sdk/particle_property_inlines.h new file mode 100644 index 0000000..95ba40d --- /dev/null +++ b/SpyCustom/sdk/particle_property_inlines.h @@ -0,0 +1,25 @@ +#ifndef PARTICLEPROPERTY_H +#pragma message("Do not include particle_property_inlines.h from anywhere other than particle_property.h!") +#pragma error +#endif + +#ifndef PARTICLEPROPERTY_INLINES_H +#define PARTICLEPROPERTY_INLINES_H +#ifdef _WIN32 +#pragma once +#endif + + +void CParticleProperty::SetControlPointParent(CNewParticleEffect* pEffect, int whichControlPoint, int parentIdx) +{ + pEffect->SetControlPointParent(whichControlPoint, parentIdx); +} + +CNewParticleEffect* CParticleProperty::GetParticleEffectFromIdx(int idx) +{ + return m_ParticleEffects[idx].pParticleEffect.GetObject(); +} + + + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/particle_util.h b/SpyCustom/sdk/particle_util.h new file mode 100644 index 0000000..003c514 --- /dev/null +++ b/SpyCustom/sdk/particle_util.h @@ -0,0 +1,289 @@ +#ifndef PARTICLE_UTIL_H +#define PARTICLE_UTIL_H + +#include "IMesh.h" +#include "particledraw.h" +#include "particlemgr.h" +#include "cdll_client_int.h" +#include "timedevent.h" + + + +inline float FLerp(float minVal, float maxVal, float t) +{ + return minVal + (maxVal - minVal) * t; +} + +inline Vector VecLerp(const Vector& minVal, const Vector& maxVal, float t) +{ + return minVal + (maxVal - minVal) * t; +} + +inline float FRand(float minVal, float maxVal) +{ + return minVal + ((float)rand() / RAND_MAX) * (maxVal - minVal); +} + +inline void PhysicallySimulate(Vector& pos, Vector& velocity, const Vector& acceleration, const float fTimeDelta) +{ + pos = pos + (velocity + (acceleration * fTimeDelta * 0.5f)) * fTimeDelta; + velocity = velocity + acceleration * fTimeDelta; +} + + +inline Vector GetGravityVector() +{ + return Vector(0, 0, -150); +} + + +inline void RenderParticle_Color255SizeSpecularTCoord3( + ParticleDraw* pDraw, + const Vector& pos, + const Vector& color, + const float alpha, + const float size, + const unsigned char* specular, + const float tCoord +) +{ + if (alpha < 0.5f) + return; + + CMeshBuilder* pBuilder = pDraw->GetMeshBuilder(); + if (!pBuilder) + return; + + unsigned char ubColor[4]; + ubColor[0] = (unsigned char)RoundFloatToInt(color.x); + ubColor[1] = (unsigned char)RoundFloatToInt(color.y); + ubColor[2] = (unsigned char)RoundFloatToInt(color.z); + ubColor[3] = (unsigned char)RoundFloatToInt(alpha); + + pBuilder->Position3f(pos.x - size, pos.y - size, pos.z); + pBuilder->Color4ubv(ubColor); + pBuilder->TexCoord3f(0, pDraw->m_pSubTexture->m_tCoordMins[0], pDraw->m_pSubTexture->m_tCoordMaxs[1], tCoord); + pBuilder->Specular3ubv(specular); + pBuilder->AdvanceVertex(); + + pBuilder->Position3f(pos.x - size, pos.y + size, pos.z); + pBuilder->Color4ubv(ubColor); + pBuilder->TexCoord3f(0, pDraw->m_pSubTexture->m_tCoordMins[0], pDraw->m_pSubTexture->m_tCoordMins[1], tCoord); + pBuilder->Specular3ubv(specular); + pBuilder->AdvanceVertex(); + + pBuilder->Position3f(pos.x + size, pos.y + size, pos.z); + pBuilder->Color4ubv(ubColor); + pBuilder->TexCoord3f(0, pDraw->m_pSubTexture->m_tCoordMaxs[0], pDraw->m_pSubTexture->m_tCoordMins[1], tCoord); + pBuilder->Specular3ubv(specular); + pBuilder->AdvanceVertex(); + + pBuilder->Position3f(pos.x + size, pos.y - size, pos.z); + pBuilder->Color4ubv(ubColor); + pBuilder->TexCoord3f(0, pDraw->m_pSubTexture->m_tCoordMaxs[0], pDraw->m_pSubTexture->m_tCoordMaxs[1], tCoord); + pBuilder->Specular3ubv(specular); + pBuilder->AdvanceVertex(); +} + + +inline void RenderParticle_Color255Size( + ParticleDraw* pDraw, + const Vector& pos, + const Vector& color, + const float alpha, + const float size) +{ + if (alpha < 0.5f) + return; + + CMeshBuilder* pBuilder = pDraw->GetMeshBuilder(); + if (!pBuilder) + return; + + unsigned char ubColor[4]; + ubColor[0] = (unsigned char)RoundFloatToInt(color.x); + ubColor[1] = (unsigned char)RoundFloatToInt(color.y); + ubColor[2] = (unsigned char)RoundFloatToInt(color.z); + ubColor[3] = (unsigned char)RoundFloatToInt(alpha); + + pBuilder->Position3f(pos.x - size, pos.y - size, pos.z); + pBuilder->Color4ubv(ubColor); + pBuilder->TexCoord2f(0, pDraw->m_pSubTexture->m_tCoordMins[0], pDraw->m_pSubTexture->m_tCoordMaxs[1]); + pBuilder->AdvanceVertex(); + + pBuilder->Position3f(pos.x - size, pos.y + size, pos.z); + pBuilder->Color4ubv(ubColor); + pBuilder->TexCoord2f(0, pDraw->m_pSubTexture->m_tCoordMins[0], pDraw->m_pSubTexture->m_tCoordMins[1]); + pBuilder->AdvanceVertex(); + + pBuilder->Position3f(pos.x + size, pos.y + size, pos.z); + pBuilder->Color4ubv(ubColor); + pBuilder->TexCoord2f(0, pDraw->m_pSubTexture->m_tCoordMaxs[0], pDraw->m_pSubTexture->m_tCoordMins[1]); + pBuilder->AdvanceVertex(); + + pBuilder->Position3f(pos.x + size, pos.y - size, pos.z); + pBuilder->Color4ubv(ubColor); + pBuilder->TexCoord2f(0, pDraw->m_pSubTexture->m_tCoordMaxs[0], pDraw->m_pSubTexture->m_tCoordMaxs[1]); + pBuilder->AdvanceVertex(); +} + + +inline void RenderParticle_Color255SizeNormal( + ParticleDraw* pDraw, + const Vector& pos, + const Vector& color, + const float alpha, + const float size, + const Vector& vNormal) +{ + if (alpha < 0.5f) + return; + + CMeshBuilder* pBuilder = pDraw->GetMeshBuilder(); + if (!pBuilder) + return; + + unsigned char ubColor[4]; + ubColor[0] = (unsigned char)RoundFloatToInt(color.x); + ubColor[1] = (unsigned char)RoundFloatToInt(color.y); + ubColor[2] = (unsigned char)RoundFloatToInt(color.z); + ubColor[3] = (unsigned char)RoundFloatToInt(alpha); + +} + + +inline void RenderParticle_Color255SizeNormalAngle( + ParticleDraw* pDraw, + const Vector& pos, + const Vector& color, + const float alpha, + const float size, + const Vector& vNormal, + const float angle) +{ + if (alpha < 0.5f) + return; + + CMeshBuilder* pBuilder = pDraw->GetMeshBuilder(); + if (!pBuilder) + return; + + unsigned char ubColor[4]; + ubColor[0] = (unsigned char)RoundFloatToInt(color.x); + ubColor[1] = (unsigned char)RoundFloatToInt(color.y); + ubColor[2] = (unsigned char)RoundFloatToInt(color.z); + ubColor[3] = (unsigned char)RoundFloatToInt(alpha); + + float ca = (float)cos(angle); + float sa = (float)sin(angle); + +} + + +inline void RenderParticle_ColorSize( + ParticleDraw* pDraw, + const Vector& pos, + const Vector& color, + const float alpha, + const float size +) +{ + if (alpha < 0.001f) + return; + + CMeshBuilder* pBuilder = pDraw->GetMeshBuilder(); + if (!pBuilder) + return; + + unsigned char ubColor[4]; + ubColor[0] = (unsigned char)RoundFloatToInt(color.x * 254.9f); + ubColor[1] = (unsigned char)RoundFloatToInt(color.y * 254.9f); + ubColor[2] = (unsigned char)RoundFloatToInt(color.z * 254.9f); + ubColor[3] = (unsigned char)RoundFloatToInt(alpha * 254.9f); + +} + + +inline void RenderParticle_ColorSizeAngle( + ParticleDraw* pDraw, + const Vector& pos, + const Vector& color, + const float alpha, + const float size, + const float angle) +{ + if (alpha < 0.001f) + return; + + CMeshBuilder* pBuilder = pDraw->GetMeshBuilder(); + if (!pBuilder) + return; + + unsigned char ubColor[4]; + ubColor[0] = (unsigned char)RoundFloatToInt(color.x * 254.9f); + ubColor[1] = (unsigned char)RoundFloatToInt(color.y * 254.9f); + ubColor[2] = (unsigned char)RoundFloatToInt(color.z * 254.9f); + ubColor[3] = (unsigned char)RoundFloatToInt(alpha * 254.9f); + + float sa, ca; + SinCos(angle, &sa, &ca); + +} + +inline void RenderParticle_ColorSizeAngles( + ParticleDraw* pDraw, + const Vector& pos, + const Vector& color, + const float alpha, + const float size, + const QAngle& angles) +{ + if (alpha < 0.001f) + return; + + CMeshBuilder* pBuilder = pDraw->GetMeshBuilder(); + if (!pBuilder) + return; + + unsigned char ubColor[4]; + ubColor[0] = (unsigned char)RoundFloatToInt(color.x * 254.9f); + ubColor[1] = (unsigned char)RoundFloatToInt(color.y * 254.9f); + ubColor[2] = (unsigned char)RoundFloatToInt(color.z * 254.9f); + ubColor[3] = (unsigned char)RoundFloatToInt(alpha * 254.9f); + + Vector vNorm, vWidth, vHeight; + AngleVectors(angles, &vNorm, &vWidth, &vHeight); + + Vector vVertex = pos; +} + +inline float GetAlphaDistanceFade( + const Vector& pos, + const float fadeNearDist, + const float fadeFarDist) +{ + if (-pos.z > fadeFarDist) + { + return 1; + } + else if (-pos.z > fadeNearDist) + { + return (-pos.z - fadeNearDist) / (fadeFarDist - fadeNearDist); + } + else + { + return 0; + } +} + + +inline Vector WorldGetLightForPoint(const Vector& vPos, bool bClamp) +{ +#if defined(PARTICLEPROTOTYPE_APP) + return Vector(1, 1, 1); +#else + return engine->GetLightForPoint(vPos, bClamp); +#endif +} + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/particledraw.h b/SpyCustom/sdk/particledraw.h new file mode 100644 index 0000000..f72b908 --- /dev/null +++ b/SpyCustom/sdk/particledraw.h @@ -0,0 +1,56 @@ +#ifndef PARTICLEDRAW_H +#define PARTICLEDRAW_H + + +class IMaterial; +class CMeshBuilder; +class CParticleSubTexture; + + +class ParticleDraw +{ + friend class CParticleEffectBinding; + +public: + + ParticleDraw(); + + void Init(CMeshBuilder* pMeshBuilder, IMaterial* pMaterial, float fTimeDelta); + + float GetTimeDelta() const; + + CMeshBuilder* GetMeshBuilder(); + + CParticleSubTexture* m_pSubTexture; + +private: + CMeshBuilder* m_pMeshBuilder; + IMaterial* m_pMaterial; + float m_fTimeDelta; +}; + + + +inline ParticleDraw::ParticleDraw() +{ + m_pMaterial = 0; +} + +inline void ParticleDraw::Init(CMeshBuilder* pMeshBuilder, IMaterial* pMaterial, float fTimeDelta) +{ + m_pMeshBuilder = pMeshBuilder; + m_pMaterial = pMaterial; + m_fTimeDelta = fTimeDelta; +} + +inline float ParticleDraw::GetTimeDelta() const +{ + return m_fTimeDelta; +} + +inline CMeshBuilder* ParticleDraw::GetMeshBuilder() +{ + return m_pMeshBuilder; +} + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/particlemgr.h b/SpyCustom/sdk/particlemgr.h new file mode 100644 index 0000000..0b12d4b --- /dev/null +++ b/SpyCustom/sdk/particlemgr.h @@ -0,0 +1,617 @@ + +#ifndef PARTICLEMGR_H +#define PARTICLEMGR_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "imaterial.h" +#include "imaterialsystem.h" +#include "vector.h" +#include "vmatrix.h" +#include "Mathlib.h" +#include "iclientrenderable.h" +#include "clientleafsystem.h" +#include "fasttimer.h" +#include "utllinkedlist.h" +#include "UtlDict.h" +#ifdef WIN32 +#include +#else +#include +#endif +#include "utlintrusivelist.h" +#include "utlobjectreference.h" +#include "utlstring.h" + + +class IParticleEffect; +class IClientParticleListener; +struct Particle; +class ParticleDraw; +class CMeshBuilder; +class CUtlMemoryPool; +class CEffectMaterial; +class CParticleSimulateIterator; +class CParticleRenderIterator; +class IThreadPool; +class CParticleSystemDefinition; +class CParticleMgr; +class CNewParticleEffect; +class CParticleCollection; + +#define INVALID_MATERIAL_HANDLE NULL + + + +class CParticleSubTexture; +class CParticleSubTextureGroup; + + +struct Particle +{ + Particle* m_pPrev, * m_pNext; + + CParticleSubTexture* m_pSubTexture; + + Vector m_Pos; +}; + + +typedef CParticleSubTexture* PMaterialHandle; + +class CEffectMaterial +{ +public: + CEffectMaterial(); + +public: + CParticleSubTextureGroup* m_pGroup; + + Particle m_Particles; + CEffectMaterial* m_pHashedNext; +}; + + +class CParticleSubTextureGroup +{ +public: + CParticleSubTextureGroup(); + ~CParticleSubTextureGroup(); + + IMaterial* m_pPageMaterial; +}; + +class CParticleSubTexture +{ +public: + CParticleSubTexture(); + + float m_tCoordMins[2]; + float m_tCoordMaxs[2]; + + CParticleSubTextureGroup* m_pGroup; + CParticleSubTextureGroup m_DefaultGroup; +#ifdef _DEBUG + char* m_szDebugName; +#endif + + IMaterial* m_pMaterial; +}; + + +abstract_class IParticleEffect +{ + public: + + virtual ~IParticleEffect() {} + + virtual void Update(float fTimeDelta) {} + + virtual void StartRender(VMatrix & effectMatrix) {} + + virtual bool ShouldSimulate() const = 0; + virtual void SetShouldSimulate(bool bSim) = 0; + virtual void SimulateParticles(CParticleSimulateIterator* pIterator) = 0; + + virtual void RenderParticles(CParticleRenderIterator* pIterator) = 0; + + virtual void NotifyRemove() {} + + virtual void NotifyDestroyParticle(Particle* pParticle) {} + + virtual const Vector& GetSortOrigin() = 0; + + virtual const Vector* GetParticlePosition(Particle* pParticle) { return &pParticle->m_Pos; } + + virtual const char* GetEffectName() { return "???"; } +}; + +#define REGISTER_EFFECT( effect ) \ + IParticleEffect* effect##_Factory() \ + { \ + return new effect; \ + } \ + struct effect##_RegistrationHelper \ + { \ + effect##_RegistrationHelper() \ + { \ + ParticleMgr()->RegisterEffect( typeid( effect ).name(), effect##_Factory ); \ + } \ + }; \ + static effect##_RegistrationHelper g_##effect##_RegistrationHelper + +#define REGISTER_EFFECT_USING_CREATE( effect ) \ + IParticleEffect* effect##_Factory() \ + { \ + return effect::Create( #effect ).GetObject(); \ + } \ + struct effect##_RegistrationHelper \ + { \ + effect##_RegistrationHelper() \ + { \ + ParticleMgr()->RegisterEffect( typeid( effect ).name(), effect##_Factory ); \ + } \ + }; \ + static effect##_RegistrationHelper g_##effect##_RegistrationHelper + + +class CParticleEffectBinding : public CDefaultClientRenderable +{ + friend class CParticleMgr; + friend class CParticleSimulateIterator; + friend class CNewParticleEffect; + +public: + CParticleEffectBinding(); + ~CParticleEffectBinding(); + + +public: + + void SimulateParticles(float flTimeDelta); + + PMaterialHandle FindOrAddMaterial(const char* pMaterialName); + + Particle* AddParticle(int sizeInBytes, PMaterialHandle pMaterial); + + void SetBBox(const Vector& bbMin, const Vector& bbMax, bool bDisableAutoUpdate = true); + void GetWorldspaceBounds(Vector* pMins, Vector* pMaxs); + + const matrix3x4_t& GetLocalSpaceTransform() const; + void SetLocalSpaceTransform(const matrix3x4_t& transform); + + bool EnlargeBBoxToContain(const Vector& pt); + + void SetDrawThruLeafSystem(int bDraw); + + void SetDrawBeforeViewModel(int bDraw); + + int GetRemoveFlag() { return GetFlag(FLAGS_REMOVE); } + void SetRemoveFlag() { SetFlag(FLAGS_REMOVE, 1); } + + int GetAlwaysSimulate() { return GetFlag(FLAGS_ALWAYSSIMULATE); } + void SetAlwaysSimulate(int bAlwaysSimulate) { SetFlag(FLAGS_ALWAYSSIMULATE, bAlwaysSimulate); } + + void SetIsNewParticleSystem(void) { SetFlag(FLAGS_NEW_PARTICLE_SYSTEM, 1); } + int WasDrawnPrevFrame() { return GetFlag(FLAGS_DRAWN_PREVFRAME); } + void SetWasDrawnPrevFrame(int bWasDrawnPrevFrame) { SetFlag(FLAGS_DRAWN_PREVFRAME, bWasDrawnPrevFrame); } + + int IsEffectCameraSpace() { return GetFlag(FLAGS_CAMERASPACE); } + void SetEffectCameraSpace(int bCameraSpace) { SetFlag(FLAGS_CAMERASPACE, bCameraSpace); } + + int GetAutoApplyLocalTransform() const { return GetFlag(FLAGS_AUTOAPPLYLOCALTRANSFORM); } + void SetAutoApplyLocalTransform(int b) { SetFlag(FLAGS_AUTOAPPLYLOCALTRANSFORM, b); } + + int GetAutoUpdateBBox() { return GetFlag(FLAGS_AUTOUPDATEBBOX); } + void SetAutoUpdateBBox(int bAutoUpdate) { SetFlag(FLAGS_AUTOUPDATEBBOX, bAutoUpdate); } + + int GetNumActiveParticles(); + + void SetParticleCullRadius(float flMaxParticleRadius); + + int GetActiveParticleList(int nCount, Particle** ppParticleList); + + void DetectChanges(); + +private: + void SetFlag(int flag, int bOn) { if (bOn) m_Flags |= flag; else m_Flags &= ~flag; } + int GetFlag(int flag) const { return m_Flags & flag; } + + void Init(CParticleMgr* pMgr, IParticleEffect* pSim); + void Term(); + + void RemoveParticle(Particle* pParticle); + + void StartDrawMaterialParticles( + CEffectMaterial* pMaterial, + float flTimeDelta, + IMesh*& pMesh, + CMeshBuilder& builder, + ParticleDraw& particleDraw, + bool bWireframe); + + int DrawMaterialParticles( + bool bBucketSort, + CEffectMaterial* pMaterial, + float flTimeDelta, + bool bWireframe + ); + + void GrowBBoxFromParticlePositions(CEffectMaterial* pMaterial, bool& bboxSet, Vector& bbMin, Vector& bbMax); + + void RenderStart(VMatrix& mTempModel, VMatrix& mTempView); + void RenderEnd(VMatrix& mModel, VMatrix& mView); + + void BBoxCalcStart(Vector& bbMin, Vector& bbMax); + void BBoxCalcEnd(bool bboxSet, Vector& bbMin, Vector& bbMax); + + void DoBucketSort( + CEffectMaterial* pMaterial, + float* zCoords, + int nZCoords, + float minZ, + float maxZ); + + int GetRemovalInProgressFlag() { return GetFlag(FLAGS_REMOVALINPROGRESS); } + void SetRemovalInProgressFlag() { SetFlag(FLAGS_REMOVALINPROGRESS, 1); } + + int GetNeedsBBoxUpdate() { return GetFlag(FLAGS_NEEDS_BBOX_UPDATE); } + void SetNeedsBBoxUpdate(int bFirstUpdate) { SetFlag(FLAGS_NEEDS_BBOX_UPDATE, bFirstUpdate); } + + int GetFirstFrameFlag() { return GetFlag(FLAGS_FIRST_FRAME); } + void SetFirstFrameFlag(int bFirstUpdate) { SetFlag(FLAGS_FIRST_FRAME, bFirstUpdate); } + + int WasDrawn() { return GetFlag(FLAGS_DRAWN); } + void SetDrawn(int bDrawn) { SetFlag(FLAGS_DRAWN, bDrawn); } + + bool RecalculateBoundingBox(); + + CEffectMaterial* GetEffectMaterial(CParticleSubTexture* pSubTexture); + +public: + + virtual const Vector& GetRenderOrigin(void); + virtual const QAngle& GetRenderAngles(void); + virtual const matrix3x4_t& RenderableToWorldTransform(); + virtual void GetRenderBounds(Vector& mins, Vector& maxs); + virtual bool ShouldDraw(void); + virtual int DrawModel(int flags, const RenderableInstance_t& instance); + +private: + enum + { + FLAGS_REMOVE = (1 << 0), + FLAGS_REMOVALINPROGRESS = (1 << 1), + FLAGS_NEEDS_BBOX_UPDATE = (1 << 2), + FLAGS_AUTOUPDATEBBOX = (1 << 3), + FLAGS_ALWAYSSIMULATE = (1 << 4), + FLAGS_DRAWN = (1 << 5), + FLAGS_DRAWN_PREVFRAME = (1 << 6), + FLAGS_CAMERASPACE = (1 << 7), + FLAGS_DRAW_THRU_LEAF_SYSTEM = (1 << 8), + FLAGS_DRAW_BEFORE_VIEW_MODEL = (1 << 9), + FLAGS_AUTOAPPLYLOCALTRANSFORM = (1 << 10), + FLAGS_FIRST_FRAME = (1 << 11), + FLAGS_NEW_PARTICLE_SYSTEM = (1 << 12) + }; + + + VMatrix m_LocalSpaceTransform; + bool m_bLocalSpaceTransformIdentity; + + Vector m_Min; + Vector m_Max; + + Vector m_LastMin; + Vector m_LastMax; + + float m_flParticleCullRadius; + + unsigned short m_nActiveParticles; + + unsigned short m_FrameCode; + + unsigned short m_ListIndex; + + IParticleEffect* m_pSim; + CParticleMgr* m_pParticleMgr; + + int m_Flags; + + enum { EFFECT_MATERIAL_HASH_SIZE = 8 }; + CEffectMaterial* m_EffectMaterialHash[EFFECT_MATERIAL_HASH_SIZE]; + +#ifdef INFESTED_PARTICLES +public: +#endif + CUtlLinkedList m_Materials; + + unsigned short m_UpdateBBoxCounter; +}; + + +class CParticleLightInfo +{ +public: + Vector m_vPos; + Vector m_vColor; + float m_flIntensity; +}; + +typedef IParticleEffect* (*CreateParticleEffectFN)(); + +enum +{ + TOOLPARTICLESYSTEMID_INVALID = -1, +}; + + +class CParticleCollection; + +class CNonDrawingParticleSystem +{ +public: + CNonDrawingParticleSystem* m_pNext; + CNonDrawingParticleSystem* m_pPrev; + CParticleCollection* m_pSystem; + + FORCEINLINE CParticleCollection* operator()(void) const + { + return m_pSystem; + } + + FORCEINLINE CParticleCollection* Get(void) const + { + return m_pSystem; + } + + ~CNonDrawingParticleSystem(void); +}; + + + + +class CClientTools; + +class CParticleMgr +{ + friend class CParticleEffectBinding; + friend class CParticleCollection; + friend class CNonDrawingParticleSystem; + friend class CClientTools; + +public: + + CParticleMgr(); + virtual ~CParticleMgr(); + + bool Init(unsigned long nPreallocatedParticles, IMaterialSystem* pMaterial); + + void Term(); + + void LevelInit(); + + void RegisterEffect(const char* pEffectType, CreateParticleEffectFN func); + IParticleEffect* CreateEffect(const char* pEffectType); + + bool AddEffect(CParticleEffectBinding* pEffect, IParticleEffect* pSim); + void RemoveEffect(CParticleEffectBinding* pEffect); + + void AddEffect(CNewParticleEffect* pEffect); + void RemoveEffect(CNewParticleEffect* pEffect); + + void RemoveAllEffects(); + + void IncrementFrameCode(); + + void Simulate(float fTimeDelta); + + void PostRender(); + + void DrawBeforeViewModelEffects(); + + VMatrix& GetModelView(); + + Particle* AllocParticle(int size); + void FreeParticle(Particle*); + + PMaterialHandle GetPMaterial(const char* pMaterialName); + IMaterial* PMaterialToIMaterial(PMaterialHandle hMaterial); + + void RepairPMaterial(PMaterialHandle hMaterial); + + void GetDirectionalLightInfo(CParticleLightInfo& info) const; + void SetDirectionalLightInfo(const CParticleLightInfo& info); + + void SpewInfo(bool bDetail); + + void AddEffectListener(IClientParticleListener* pListener); + void RemoveEffectListener(IClientParticleListener* pListener); + + int AllocateToolParticleEffectId(); + + void RemoveAllNewEffects(); + + CNewParticleEffect* FirstNewEffect(); + CNewParticleEffect* NextNewEffect(CNewParticleEffect* pEffect); + + void RenderParticleSystems(bool bEnable); + bool ShouldRenderParticleSystems() const; + + void RemoveOldParticleEffects(float flTime); + int GetNumParticles() const { return m_nCurrentParticlesAllocated; } + + + CNonDrawingParticleSystem* CreateNonDrawingEffect(const char* pEffectName); + +private: + struct RetireInfo_t + { + CParticleCollection* m_pCollection; + float m_flScreenArea; + bool m_bFirstFrame; + }; + + void UpdateAllEffects(float flTimeDelta); + + void UpdateNewEffects(float flTimeDelta); + + void SpewActiveParticleSystems(); + + CParticleSubTextureGroup* FindOrAddSubTextureGroup(IMaterial* pPageMaterial); + + int ComputeParticleDefScreenArea(int nInfoCount, RetireInfo_t* pInfo, float* pTotalArea, CParticleSystemDefinition* pDef, + const CViewSetup& view, const VMatrix& worldToPixels, float flFocalDist); + + bool RetireParticleCollections(CParticleSystemDefinition* pDef, int nCount, RetireInfo_t* pInfo, float flScreenArea, float flMaxTotalArea); + void BuildParticleSimList(CUtlVector< CNewParticleEffect* >& list); + bool EarlyRetireParticleSystems(int nCount, CNewParticleEffect** ppEffects); + static int RetireSort(const void* p1, const void* p2); + +private: + + int m_nCurrentParticlesAllocated; + + CParticleLightInfo m_DirectionalLight; + + unsigned short m_FrameCode; + + bool m_bUpdatingEffects; + bool m_bRenderParticleEffects; + + CUtlLinkedList m_Effects; + + CUtlIntrusiveDList< CNewParticleEffect > m_NewEffects; + CUtlIntrusiveDList< CNonDrawingParticleSystem > m_NonDrawingParticleSystems; + + + + CUtlVector< IClientParticleListener*> m_effectListeners; + + IMaterialSystem* m_pMaterialSystem; + + VMatrix m_mModelView; + + CUtlVector m_SubTextureGroups; + CUtlDict m_SubTextures; + CParticleSubTexture m_DefaultInvalidSubTexture; + + CUtlMap< const char*, CreateParticleEffectFN > m_effectFactories; + + int m_nToolParticleEffectId; + + IThreadPool* m_pThreadPool[2]; +}; + +inline int CParticleMgr::AllocateToolParticleEffectId() +{ + return m_nToolParticleEffectId++; +} + +class IClientParticleListener +{ +public: + virtual void OnParticleEffectAdded(IParticleEffect* pEffect) = 0; + virtual void OnParticleEffectRemoved(IParticleEffect* pEffect) = 0; +}; + + + +float Helper_GetTime(); +float Helper_GetFrameTime(); +float Helper_RandomFloat(float minVal, float maxVal); +int Helper_RandomInt(int minVal, int maxVal); + + + +inline VMatrix& CParticleMgr::GetModelView() +{ + return m_mModelView; +} + + + +inline const matrix3x4_t& CParticleEffectBinding::GetLocalSpaceTransform() const +{ + return m_LocalSpaceTransform.As3x4(); +} + + + +CParticleMgr* ParticleMgr(); + + + + +struct StandardParticle_t : public Particle +{ + void SetColor(float r, float g, float b); + void SetAlpha(float a); + + Vector m_Velocity; + + float m_Lifetime; + + unsigned char m_EffectData; + unsigned short m_EffectDataWord; + + unsigned char m_Color[4]; +}; + + +inline void TransformParticle(const VMatrix& vMat, const Vector& vIn, Vector& vOut) +{ + vOut.x = vMat.m[0][0] * vIn.x + vMat.m[0][1] * vIn.y + vMat.m[0][2] * vIn.z + vMat.m[0][3]; + vOut.y = vMat.m[1][0] * vIn.x + vMat.m[1][1] * vIn.y + vMat.m[1][2] * vIn.z + vMat.m[1][3]; + vOut.z = vMat.m[2][0] * vIn.x + vMat.m[2][1] * vIn.y + vMat.m[2][2] * vIn.z + vMat.m[2][3]; +} + + +inline void StandardParticle_t::SetColor(float r, float g, float b) +{ + m_Color[0] = (unsigned char)(r * 255.9f); + m_Color[1] = (unsigned char)(g * 255.9f); + m_Color[2] = (unsigned char)(b * 255.9f); +} + +inline void StandardParticle_t::SetAlpha(float a) +{ + m_Color[3] = (unsigned char)(a * 255.9f); +} + + + +inline void UnlinkParticle(Particle* pParticle) +{ + pParticle->m_pPrev->m_pNext = pParticle->m_pNext; + pParticle->m_pNext->m_pPrev = pParticle->m_pPrev; +} + +inline void InsertParticleBefore(Particle* pInsert, Particle* pNext) +{ + pInsert->m_pNext = pNext; + pInsert->m_pPrev = pNext->m_pPrev; + pInsert->m_pNext->m_pPrev = pInsert->m_pPrev->m_pNext = pInsert; +} + +inline void InsertParticleAfter(Particle* pInsert, Particle* pPrev) +{ + pInsert->m_pPrev = pPrev; + pInsert->m_pNext = pPrev->m_pNext; + + pInsert->m_pNext->m_pPrev = pInsert->m_pPrev->m_pNext = pInsert; +} + +inline void SwapParticles(Particle* pPrev, Particle* pCur) +{ + UnlinkParticle(pCur); + InsertParticleBefore(pCur, pPrev); +} + + +#include "particle_iterators.h" + + +#endif diff --git a/SpyCustom/sdk/particles.h b/SpyCustom/sdk/particles.h new file mode 100644 index 0000000..be72c49 --- /dev/null +++ b/SpyCustom/sdk/particles.h @@ -0,0 +1,1954 @@ +#ifndef PARTICLES_H +#define PARTICLES_H +#ifdef _WIN32 +#pragma once +#endif + +#include "mathlib.h" +#include "vector.h" +#include "ssemath.h" +#include "imaterialsystem.h" +#include "dmxelement.h" +#include "utlintrusivelist.h" +#include "random.h" +#include "utlobjectreference.h" +#include "UtlStringMap.h" +#include "utlmap.h" +#include "MaterialSystemUtil.h" +#include "trace.h" +#include "utlsoacontainer.h" + +#if defined( CLIENT_DLL ) +#include "c_pixel_visibility.h" +#endif + +struct DmxElementUnpackStructure_t; +class CParticleSystemDefinition; +class CParticleCollection; +class CParticleOperatorInstance; +class CParticleSystemDictionary; +class CUtlBuffer; +class IParticleOperatorDefinition; +class CSheet; +class CMeshBuilder; +extern float s_pRandomFloats[]; + + +#define MAX_RANDOM_FLOATS 4096 +#define RANDOM_FLOAT_MASK ( MAX_RANDOM_FLOATS - 1 ) + + +#define MAX_PARTICLE_ATTRIBUTES 32 + +#define DEFPARTICLE_ATTRIBUTE( name, bit ) \ + const int PARTICLE_ATTRIBUTE_##name##_MASK = (1 << bit); \ + const int PARTICLE_ATTRIBUTE_##name = bit; + +DEFPARTICLE_ATTRIBUTE(XYZ, 0); + +DEFPARTICLE_ATTRIBUTE(LIFE_DURATION, 1); + +DEFPARTICLE_ATTRIBUTE(PREV_XYZ, 2); + +DEFPARTICLE_ATTRIBUTE(RADIUS, 3); + +DEFPARTICLE_ATTRIBUTE(ROTATION, 4); + +DEFPARTICLE_ATTRIBUTE(ROTATION_SPEED, 5); + +DEFPARTICLE_ATTRIBUTE(TINT_RGB, 6); + +DEFPARTICLE_ATTRIBUTE(ALPHA, 7); + +DEFPARTICLE_ATTRIBUTE(CREATION_TIME, 8); + +DEFPARTICLE_ATTRIBUTE(SEQUENCE_NUMBER, 9); + +DEFPARTICLE_ATTRIBUTE(TRAIL_LENGTH, 10); + +DEFPARTICLE_ATTRIBUTE(PARTICLE_ID, 11); + +DEFPARTICLE_ATTRIBUTE(YAW, 12); + +DEFPARTICLE_ATTRIBUTE(SEQUENCE_NUMBER1, 13); + +DEFPARTICLE_ATTRIBUTE(HITBOX_INDEX, 14); + +DEFPARTICLE_ATTRIBUTE(HITBOX_RELATIVE_XYZ, 15); + +DEFPARTICLE_ATTRIBUTE(ALPHA2, 16); + +DEFPARTICLE_ATTRIBUTE(TRACE_P0, 17); +DEFPARTICLE_ATTRIBUTE(TRACE_P1, 18); +DEFPARTICLE_ATTRIBUTE(TRACE_HIT_T, 19); +DEFPARTICLE_ATTRIBUTE(TRACE_HIT_NORMAL, 20); + + +#define MAX_PARTICLE_CONTROL_POINTS 64 + +#define ATTRIBUTES_WHICH_ARE_VEC3S_MASK ( PARTICLE_ATTRIBUTE_TRACE_P0_MASK | PARTICLE_ATTRIBUTE_TRACE_P1_MASK | \ + PARTICLE_ATTRIBUTE_TRACE_HIT_NORMAL | PARTICLE_ATTRIBUTE_XYZ_MASK | \ + PARTICLE_ATTRIBUTE_PREV_XYZ_MASK | PARTICLE_ATTRIBUTE_TINT_RGB_MASK | \ + PARTICLE_ATTRIBUTE_HITBOX_RELATIVE_XYZ_MASK ) +#define ATTRIBUTES_WHICH_ARE_0_TO_1 (PARTICLE_ATTRIBUTE_ALPHA_MASK | PARTICLE_ATTRIBUTE_ALPHA2_MASK) +#define ATTRIBUTES_WHICH_ARE_ANGLES (PARTICLE_ATTRIBUTE_ROTATION_MASK | PARTICLE_ATTRIBUTE_YAW_MASK ) +#define ATTRIBUTES_WHICH_ARE_INTS (PARTICLE_ATTRIBUTE_PARTICLE_ID_MASK | PARTICLE_ATTRIBUTE_HITBOX_INDEX_MASK ) + +#if defined( _X360 ) +#define MAX_PARTICLES_IN_A_SYSTEM 2000 +#else +#define MAX_PARTICLES_IN_A_SYSTEM 5000 +#endif + +#define MEASURE_PARTICLE_PERF 0 + + +enum ParticleFunctionType_t +{ + FUNCTION_RENDERER = 0, + FUNCTION_OPERATOR, + FUNCTION_INITIALIZER, + FUNCTION_EMITTER, + FUNCTION_CHILDREN, + FUNCTION_FORCEGENERATOR, + FUNCTION_CONSTRAINT, + PARTICLE_FUNCTION_COUNT +}; + +struct CParticleVisibilityInputs +{ + float m_flCameraBias; + float m_flInputMin; + float m_flInputMax; + float m_flAlphaScaleMin; + float m_flAlphaScaleMax; + float m_flRadiusScaleMin; + float m_flRadiusScaleMax; + float m_flProxyRadius; + float m_flBBoxScale; + bool m_bUseBBox; + int m_nCPin; +}; + +struct ModelHitBoxInfo_t +{ + Vector m_vecBoxMins; + Vector m_vecBoxMaxes; + matrix3x4_t m_Transform; +}; + +class CModelHitBoxesInfo +{ +public: + float m_flLastUpdateTime; + float m_flPrevLastUpdateTime; + int m_nNumHitBoxes; + int m_nNumPrevHitBoxes; + ModelHitBoxInfo_t* m_pHitBoxes; + ModelHitBoxInfo_t* m_pPrevBoxes; + + bool CurAndPrevValid(void) const + { + return (m_nNumHitBoxes && (m_nNumPrevHitBoxes == m_nNumHitBoxes)); + } + + CModelHitBoxesInfo(void) + { + m_flLastUpdateTime = -1; + m_nNumHitBoxes = 0; + m_nNumPrevHitBoxes = 0; + m_pHitBoxes = NULL; + m_pPrevBoxes = NULL; + } + + ~CModelHitBoxesInfo(void) + { + if (m_pHitBoxes) + delete[] m_pHitBoxes; + if (m_pPrevBoxes) + delete[] m_pPrevBoxes; + } + +}; + + + + +#define PARTICLE_SYSTEM_QUERY_INTERFACE_VERSION "VParticleSystemQuery001" + +class IParticleSystemQuery : public IAppSystem +{ +public: + virtual void GetLightingAtPoint(const Vector& vecOrigin, Color& tint) = 0; + virtual void TraceLine(const Vector& vecAbsStart, + const Vector& vecAbsEnd, unsigned int mask, + const class IHandleEntity* ignore, + int collisionGroup, + CBaseTrace* ptr) = 0; + + virtual bool MovePointInsideControllingObject(CParticleCollection* pParticles, + void* pObject, + Vector* pPnt) + { + return true; + } + + virtual bool IsPointInControllingObjectHitBox( + CParticleCollection* pParticles, + int nControlPointNumber, Vector vecPos, bool bBBoxOnly = false) + { + return true; + } + + virtual int GetCollisionGroupFromName(const char* pszCollisionGroupName) + { + return 0; + } + + virtual void GetRandomPointsOnControllingObjectHitBox( + CParticleCollection* pParticles, + int nControlPointNumber, + int nNumPtsOut, + float flBBoxScale, + int nNumTrysToGetAPointInsideTheModel, + Vector* pPntsOut, + Vector vecDirectionBias, + Vector* pHitBoxRelativeCoordOut = NULL, + int* pHitBoxIndexOut = NULL) = 0; + + + virtual int GetControllingObjectHitBoxInfo( + CParticleCollection* pParticles, + int nControlPointNumber, + int nBufSize, + ModelHitBoxInfo_t* pHitBoxOutputBuffer) + { + return 0; + } + + virtual Vector GetLocalPlayerPos(void) + { + return vec3_origin; + } + + virtual void GetLocalPlayerEyeVectors(Vector* pForward, Vector* pRight = NULL, Vector* pUp = NULL) + { + *pForward = vec3_origin; + *pRight = vec3_origin; + *pUp = vec3_origin; + } + + virtual float GetPixelVisibility(int* pQueryHandle, const Vector& vecOrigin, float flScale) = 0; + + virtual void SetUpLightingEnvironment(const Vector& pos) + { + } +}; + + +typedef int ParticleSystemHandle_t; + +class CParticleSystemMgr +{ +public: + CParticleSystemMgr(); + ~CParticleSystemMgr(); + + bool Init(IParticleSystemQuery* pQuery); + + void AddBuiltinSimulationOperators(void); + void AddBuiltinRenderingOperators(void); + + + + void AddParticleOperator(ParticleFunctionType_t nOpType, IParticleOperatorDefinition* pOpFactory); + + bool ReadParticleConfigFile(const char* pFileName, bool bPrecache, bool bDecommitTempMemory = true); + bool ReadParticleConfigFile(CUtlBuffer& buf, bool bPrecache, bool bDecommitTempMemory = true, const char* pFileName = NULL); + void DecommitTempMemory(); + + bool WriteParticleConfigFile(const char* pParticleSystemName, CUtlBuffer& buf, bool bPreventNameBasedLookup = false); + bool WriteParticleConfigFile(const DmObjectId_t& id, CUtlBuffer& buf, bool bPreventNameBasedLookup = false); + + CParticleCollection* CreateParticleCollection(const char* pParticleSystemName, float flDelay = 0.0f, int nRandomSeed = 0); + + CParticleCollection* CreateParticleCollection(const DmObjectId_t& id, float flDelay = 0.0f, int nRandomSeed = 0); + + bool IsParticleSystemDefined(const char* pParticleSystemName); + bool IsParticleSystemDefined(const DmObjectId_t& id); + + ParticleSystemHandle_t GetParticleSystemIndex(const char* pParticleSystemName); + + const char* GetParticleSystemNameFromIndex(ParticleSystemHandle_t iIndex); + + int GetParticleSystemCount(void); + + CUtlVector< IParticleOperatorDefinition*>& GetAvailableParticleOperatorList(ParticleFunctionType_t nWhichList); + + const DmxElementUnpackStructure_t* GetParticleSystemDefinitionUnpackStructure(); + + void ShouldLoadSheets(bool bLoadSheets); + CSheet* FindOrLoadSheet(char const* pszFname, ITexture* pTexture); + CSheet* FindOrLoadSheet(IMaterial* pMaterial); + void FlushAllSheets(void); + + + void ResetRenderCache(void); + void AddToRenderCache(CParticleCollection* pParticles); + void DrawRenderCache(bool bShadowDepth); + + IParticleSystemQuery* Query(void) { return m_pQuery; } + + const char* GetParticleFieldName(int nParticleField) const; + + CParticleSystemDefinition* FindParticleSystem(const char* pName); + CParticleSystemDefinition* FindParticleSystem(const DmObjectId_t& id); + + void CommitProfileInformation(bool bCommit); + + void DumpProfileInformation(void); + + void PrecacheParticleSystem(const char* pName); + void UncacheAllParticleSystems(); + + void SetLastSimulationTime(float flTime); + float GetLastSimulationTime() const; + + int Debug_GetTotalParticleCount() const; + bool Debug_FrameWarningNeededTestAndReset(); + float ParticleThrottleScaling() const; + bool ParticleThrottleRandomEnable() const; + + void TallyParticlesRendered(int nVertexCount, int nIndexCount = 0); + +private: + struct RenderCache_t + { + IMaterial* m_pMaterial; + CUtlVector< CParticleCollection* > m_ParticleCollections; + }; + + struct BatchStep_t + { + CParticleCollection* m_pParticles; + CParticleOperatorInstance* m_pRenderer; + void* m_pContext; + int m_nFirstParticle; + int m_nParticleCount; + int m_nVertCount; + }; + + struct Batch_t + { + int m_nVertCount; + int m_nIndexCount; + CUtlVector< BatchStep_t > m_BatchStep; + }; + + bool ReadParticleDefinitions(CUtlBuffer& buf, const char* pFileName, bool bPrecache, bool bDecommitTempMemory); + void AddParticleSystem(CDmxElement* pParticleSystem); + + CDmxElement* CreateParticleDmxElement(const DmObjectId_t& id); + CDmxElement* CreateParticleDmxElement(const char* pParticleSystemName); + + bool WriteParticleConfigFile(CDmxElement* pParticleSystem, CUtlBuffer& buf, bool bPreventNameBasedLookup); + + void BuildBatchList(int iRenderCache, IMatRenderContext* pRenderContext, CUtlVector< Batch_t >& batches); + + CUtlVector m_ParticleOperators[PARTICLE_FUNCTION_COUNT]; + + CParticleSystemDictionary* m_pParticleSystemDictionary; + + typedef CUtlStringMap< CSheet* > SheetsCache_t; + SheetsCache_t m_SheetList; + + void AttachKillList(CParticleCollection* pParticles); + void DetachKillList(CParticleCollection* pParticles); + + CParticleCollection* m_pVisualizedParticles; + DmObjectId_t m_VisualizedOperatorId; + IParticleSystemQuery* m_pQuery; + CUtlVector< RenderCache_t > m_RenderCache; + IMaterial* m_pShadowDepthMaterial; + float m_flLastSimulationTime; + + bool m_bDidInit; + bool m_bUsingDefaultQuery; + bool m_bShouldLoadSheets; + + int m_nNumFramesMeasured; + + enum { c_nNumFramesTracked = 10 }; + int m_nParticleVertexCountHistory[c_nNumFramesTracked]; + float m_fParticleCountScaling; + int m_nParticleIndexCount; + int m_nParticleVertexCount; + bool m_bFrameWarningNeeded; + + friend class CParticleSystemDefinition; + friend class CParticleCollection; +}; + +extern CParticleSystemMgr* g_pParticleSystemMgr; + + +enum ParticleOperatorId_t +{ + OPERATOR_GENERIC = -2, + OPERATOR_SINGLETON = -1, + + OPERATOR_PI_POSITION, + OPERATOR_PI_RADIUS, + OPERATOR_PI_ALPHA, + OPERATOR_PI_TINT_RGB, + OPERATOR_PI_ROTATION, + OPERATOR_PI_YAW, + + OPERATOR_ID_COUNT, +}; + + +class IParticleOperatorDefinition +{ +public: + virtual const char* GetName() const = 0; + virtual CParticleOperatorInstance* CreateInstance(const DmObjectId_t& id) const = 0; + virtual const DmxElementUnpackStructure_t* GetUnpackStructure() const = 0; + virtual ParticleOperatorId_t GetId() const = 0; + virtual bool IsObsolete() const = 0; + virtual size_t GetClassSize() const = 0; + +#if MEASURE_PARTICLE_PERF + float m_flMaxExecutionTime; + float m_flTotalExecutionTime; + float m_flUncomittedTime; + + FORCEINLINE void RecordExecutionTime(float flETime) + { + m_flUncomittedTime += flETime; + m_flMaxExecutionTime = MAX(m_flMaxExecutionTime, flETime); + } + + FORCEINLINE float TotalRecordedExecutionTime(void) const + { + return m_flTotalExecutionTime; + } + + FORCEINLINE float MaximumRecordedExecutionTime(void) const + { + return m_flMaxExecutionTime; + } +#endif +}; + + +class CParticleOperatorInstance +{ +public: + void* operator new(size_t nSize); + void* operator new(size_t size, int nBlockUse, const char* pFileName, int nLine); + void operator delete(void* pData); + void operator delete(void* p, int nBlockUse, const char* pFileName, int nLine); + + virtual void InitParams(CParticleSystemDefinition* pDef, CDmxElement* pElement) + { + } + + virtual size_t GetRequiredContextBytes() const + { + return 0; + } + + virtual void InitializeContextData(CParticleCollection* pParticles, void* pContext) const + { + } + + virtual uint32 GetWrittenAttributes(void) const = 0; + virtual uint32 GetReadAttributes(void) const = 0; + virtual uint64 GetReadControlPointMask() const + { + return 0; + } + + virtual uint32 GetReadInitialAttributes(void) const + { + return 0; + } + + virtual void Operate(CParticleCollection* pParticles, float flOpStrength, void* pContext) const + { + } + + virtual void Render(IMatRenderContext* pRenderContext, + CParticleCollection* pParticles, void* pContext) const + { + } + + virtual bool IsBatchable() const + { + return true; + } + + virtual void RenderUnsorted(CParticleCollection* pParticles, void* pContext, IMatRenderContext* pRenderContext, CMeshBuilder& meshBuilder, int nVertexOffset, int nFirstParticle, int nParticleCount) const + { + } + + virtual int GetParticlesToRender(CParticleCollection* pParticles, void* pContext, int nFirstParticle, int nRemainingVertices, int nRemainingIndices, int* pVertsUsed, int* pIndicesUsed) const + { + *pVertsUsed = 0; + *pIndicesUsed = 0; + return 0; + } + + + virtual uint32 Emit(CParticleCollection* pParticles, float flOpCurStrength, + void* pContext) const + { + return 0; + } + + virtual void StopEmission(CParticleCollection* pParticles, void* pContext, bool bInfiniteOnly = false) const + { + } + virtual void StartEmission(CParticleCollection* pParticles, void* pContext, bool bInfiniteOnly = false) const + { + } + virtual void Restart(CParticleCollection* pParticles, void* pContext) {} + + virtual void InitParticleSystem(CParticleCollection* pParticles, void* pContext) const + { + } + + + virtual void AddForces(FourVectors* AccumulatedForces, + CParticleCollection* pParticles, + int nBlocks, + float flCurStrength, + void* pContext) const + { + } + + + virtual void SetupConstraintPerFrameData(CParticleCollection* pParticles, + void* pContext) const + { + } + + + virtual bool EnforceConstraint(int nStartBlock, + int nNumBlocks, + CParticleCollection* pParticles, + void* pContext, + int nNumValidParticlesInLastChunk) const + { + return false; + } + + virtual bool IsFinalConstraint(void) const + { + return false; + } + + virtual bool InitMultipleOverride() + { + return false; + } + + + virtual bool IsScrubSafe() + { + return false; + } + + virtual void InitNewParticlesScalar(CParticleCollection* pParticles, int nFirstParticle, int n_particles, int attribute_write_mask, void* pContext) const + { + } + + virtual void InitNewParticlesBlock(CParticleCollection* pParticles, int start_block, int n_blocks, int attribute_write_mask, void* pContext) const + { + InitNewParticlesScalar(pParticles, 4 * start_block, 4 * n_blocks, attribute_write_mask, pContext); + } + + void InitNewParticles(CParticleCollection* pParticles, int nFirstParticle, int n_particles, int attribute_write_mask, void* pContext) const; + + + virtual bool MayCreateMoreParticles(CParticleCollection* pParticles, void* pContext) const + { + return false; + } + + const IParticleOperatorDefinition* GetDefinition() + { + return m_pDef; + } + + virtual bool ShouldRunBeforeEmitters(void) const + { + return false; + } + + virtual bool RequiresOrderInvariance(void) const + { + return false; + } + + virtual void SkipToTime(float flTime, CParticleCollection* pParticles, void* pContext) const {} + + const DmObjectId_t& GetId() { return m_Id; } + + virtual void Render(CParticleCollection* pParticles) const {} + + int RandomInt(int nMin, int nMax) + { + Assert(0); + return 0; + } + + float RandomFloat(float flMinVal = 0.0f, float flMaxVal = 1.0f) + { + Assert(0); + return 0.0f; + } + + float RandomFloatExp(float flMinVal = 0.0f, float flMaxVal = 1.0f, float flExponent = 1.0f) + { + Assert(0); + return 0.0f; + } + + float m_flOpStartFadeInTime; + float m_flOpEndFadeInTime; + float m_flOpStartFadeOutTime; + float m_flOpEndFadeOutTime; + float m_flOpFadeOscillatePeriod; + + virtual ~CParticleOperatorInstance(void) + { + } + +protected: + void InitScalarAttributeRandomRangeBlock(int nAttributeId, float fMinValue, float fMaxValue, + CParticleCollection* pParticles, int nStartBlock, int nBlockCount) const; + void InitScalarAttributeRandomRangeExpBlock(int nAttributeId, float fMinValue, float fMaxValue, float fExp, + CParticleCollection* pParticles, int nStartBlock, int nBlockCount) const; + void AddScalarAttributeRandomRangeBlock(int nAttributeId, float fMinValue, float fMaxValue, float fExp, + CParticleCollection* pParticles, int nStartBlock, int nBlockCount, bool bRandomlyInvert) const; + +private: + friend class CParticleCollection; + + const IParticleOperatorDefinition* m_pDef; + void SetDefinition(const IParticleOperatorDefinition* pDef, const DmObjectId_t& id) + { + m_pDef = pDef; + CopyUniqueId(id, &m_Id); + } + + DmObjectId_t m_Id; + + template friend class CParticleOperatorDefinition; +}; + +class CParticleRenderOperatorInstance : public CParticleOperatorInstance +{ +public: + + CParticleVisibilityInputs VisibilityInputs; +}; + +template < class T > +class CParticleOperatorDefinition : public IParticleOperatorDefinition +{ +public: + CParticleOperatorDefinition(const char* pFactoryName, ParticleOperatorId_t id, bool bIsObsolete) : m_pFactoryName(pFactoryName), m_Id(id) + { +#if MEASURE_PARTICLE_PERF + m_flTotalExecutionTime = 0.0f; + m_flMaxExecutionTime = 0.0f; + m_flUncomittedTime = 0.0f; +#endif + m_bIsObsolete = bIsObsolete; + } + + virtual const char* GetName() const + { + return m_pFactoryName; + } + + virtual ParticleOperatorId_t GetId() const + { + return m_Id; + } + + virtual CParticleOperatorInstance* CreateInstance(const DmObjectId_t& id) const + { + CParticleOperatorInstance* pOp = new T; + pOp->SetDefinition(this, id); + return pOp; + } + + virtual const DmxElementUnpackStructure_t* GetUnpackStructure() const + { + return m_pUnpackParams; + } + + virtual bool IsObsolete() const + { + return m_bIsObsolete; + } + + virtual size_t GetClassSize() const + { + return sizeof(T); + } + +private: + const char* m_pFactoryName; + ParticleOperatorId_t m_Id; + bool m_bIsObsolete; + static DmxElementUnpackStructure_t* m_pUnpackParams; +}; + +#define DECLARE_PARTICLE_OPERATOR( _className ) \ + DECLARE_DMXELEMENT_UNPACK() \ + friend class CParticleOperatorDefinition<_className > + +#define DEFINE_PARTICLE_OPERATOR( _className, _operatorName, _id ) \ + static CParticleOperatorDefinition<_className> s_##_className##Factory( _operatorName, _id, false ) + +#define DEFINE_PARTICLE_OPERATOR_OBSOLETE( _className, _operatorName, _id ) \ + static CParticleOperatorDefinition<_className> s_##_className##Factory( _operatorName, _id, true ) + +#define BEGIN_PARTICLE_OPERATOR_UNPACK( _className ) \ + BEGIN_DMXELEMENT_UNPACK( _className ) \ + DMXELEMENT_UNPACK_FIELD( "operator start fadein","0", float, m_flOpStartFadeInTime ) \ + DMXELEMENT_UNPACK_FIELD( "operator end fadein","0", float, m_flOpEndFadeInTime ) \ + DMXELEMENT_UNPACK_FIELD( "operator start fadeout","0", float, m_flOpStartFadeOutTime ) \ + DMXELEMENT_UNPACK_FIELD( "operator end fadeout","0", float, m_flOpEndFadeOutTime ) \ + DMXELEMENT_UNPACK_FIELD( "operator fade oscillate","0", float, m_flOpFadeOscillatePeriod ) + +#define END_PARTICLE_OPERATOR_UNPACK( _className ) \ + END_DMXELEMENT_UNPACK_TEMPLATE( _className, CParticleOperatorDefinition<_className>::m_pUnpackParams ) + +#define BEGIN_PARTICLE_RENDER_OPERATOR_UNPACK( _className ) \ + BEGIN_PARTICLE_OPERATOR_UNPACK( _className ) \ + DMXELEMENT_UNPACK_FIELD( "Visibility Proxy Input Control Point Number", "-1", int, VisibilityInputs.m_nCPin ) \ + DMXELEMENT_UNPACK_FIELD( "Visibility Proxy Radius", "1.0", float, VisibilityInputs.m_flProxyRadius ) \ + DMXELEMENT_UNPACK_FIELD( "Visibility input minimum","0", float, VisibilityInputs.m_flInputMin ) \ + DMXELEMENT_UNPACK_FIELD( "Visibility input maximum","1", float, VisibilityInputs.m_flInputMax ) \ + DMXELEMENT_UNPACK_FIELD( "Visibility Alpha Scale minimum","0", float, VisibilityInputs.m_flAlphaScaleMin ) \ + DMXELEMENT_UNPACK_FIELD( "Visibility Alpha Scale maximum","1", float, VisibilityInputs.m_flAlphaScaleMax ) \ + DMXELEMENT_UNPACK_FIELD( "Visibility Radius Scale minimum","1", float, VisibilityInputs.m_flRadiusScaleMin ) \ + DMXELEMENT_UNPACK_FIELD( "Visibility Radius Scale maximum","1", float, VisibilityInputs.m_flRadiusScaleMax ) \ + DMXELEMENT_UNPACK_FIELD( "Visibility Camera Depth Bias", "0", float, VisibilityInputs.m_flCameraBias ) + +#define REGISTER_PARTICLE_OPERATOR( _type, _className ) \ + g_pParticleSystemMgr->AddParticleOperator( _type, &s_##_className##Factory ) + + + +enum +{ + PCFLAGS_FIRST_FRAME = 0x1, + PCFLAGS_PREV_CONTROL_POINTS_INITIALIZED = 0x2, +}; + + + +#define DEBUG_PARTICLE_SORT 0 + +struct ParticleRenderData_t +{ + float m_flSortKey; + int m_nIndex; + float m_flRadius; +#if VALVE_LITTLE_ENDIAN + uint8 m_nAlpha; + uint8 m_nAlphaPad[3]; +#else + uint8 m_nAlphaPad[3]; + uint8 m_nAlpha; +#endif +}; + +struct ExtendedParticleRenderData_t : ParticleRenderData_t +{ + float m_flX; + float m_flY; + float m_flZ; + float m_flPad; +}; + + +typedef struct ALIGN16 _FourInts +{ + int32 m_nValue[4]; +} ALIGN16_POST FourInts; + + + +struct CPathParameters +{ + int m_nStartControlPointNumber; + int m_nEndControlPointNumber; + int m_nBulgeControl; + float m_flBulge; + float m_flMidPoint; + + void ClampControlPointIndices(void) + { + m_nStartControlPointNumber = MAX(0, MIN(MAX_PARTICLE_CONTROL_POINTS - 1, m_nStartControlPointNumber)); + m_nEndControlPointNumber = MAX(0, MIN(MAX_PARTICLE_CONTROL_POINTS - 1, m_nEndControlPointNumber)); + } +}; + +struct CParticleVisibilityData +{ + float m_flAlphaVisibility; + float m_flRadiusVisibility; + float m_flCameraBias; + bool m_bUseVisibility; +}; + +struct CParticleControlPoint +{ + Vector m_Position; + Vector m_PrevPosition; + + Vector m_ForwardVector; + Vector m_UpVector; + Vector m_RightVector; + + void* m_pObject; + + int m_nParent; +}; + + +struct CParticleSIMDTransformation +{ + FourVectors m_v4Origin; + FourVectors m_v4Fwd; + FourVectors m_v4Up; + FourVectors m_v4Right; + + + FORCEINLINE void VectorRotate(FourVectors& InPnt) + { + fltx4 fl4OutX = SubSIMD(AddSIMD(MulSIMD(InPnt.x, m_v4Fwd.x), MulSIMD(InPnt.z, m_v4Up.x)), MulSIMD(InPnt.y, m_v4Right.x)); + fltx4 fl4OutY = SubSIMD(AddSIMD(MulSIMD(InPnt.x, m_v4Fwd.y), MulSIMD(InPnt.z, m_v4Up.y)), MulSIMD(InPnt.y, m_v4Right.y)); + InPnt.z = SubSIMD(AddSIMD(MulSIMD(InPnt.x, m_v4Fwd.z), MulSIMD(InPnt.z, m_v4Up.z)), MulSIMD(InPnt.y, m_v4Right.z)); + InPnt.x = fl4OutX; + InPnt.y = fl4OutY; + } + + FORCEINLINE void VectorTransform(FourVectors& InPnt) + { + VectorRotate(InPnt); + InPnt.x = AddSIMD(InPnt.x, m_v4Origin.x); + InPnt.y = AddSIMD(InPnt.y, m_v4Origin.y); + InPnt.z = AddSIMD(InPnt.z, m_v4Origin.z); + } +}; + +#define NUM_COLLISION_CACHE_MODES 4 + +class CParticleCollection +{ +public: + ~CParticleCollection(void); + + void Restart(); + + void RecomputeBounds(void); + + void SetControlPoint(int nWhichPoint, const Vector& v); + void SetControlPointObject(int nWhichPoint, void* pObject); + + void SetControlPointOrientation(int nWhichPoint, const Vector& forward, + const Vector& right, const Vector& up); + void SetControlPointOrientation(int nWhichPoint, const Quaternion& q); + void SetControlPointForwardVector(int nWhichPoint, const Vector& v); + void SetControlPointUpVector(int nWhichPoint, const Vector& v); + void SetControlPointRightVector(int nWhichPoint, const Vector& v); + void SetControlPointParent(int nWhichPoint, int n); + + const float* GetFloatAttributePtr(int nAttribute, int nParticleNumber) const; + const int* GetIntAttributePtr(int nAttribute, int nParticleNumber) const; + const fltx4* GetM128AttributePtr(int nAttribute, size_t* pStrideOut) const; + const FourVectors* Get4VAttributePtr(int nAttribute, size_t* pStrideOut) const; + const FourInts* Get4IAttributePtr(int nAttribute, size_t* pStrideOut) const; + const int* GetIntAttributePtr(int nAttribute, size_t* pStrideOut) const; + + + int* GetIntAttributePtrForWrite(int nAttribute, int nParticleNumber); + + float* GetFloatAttributePtrForWrite(int nAttribute, int nParticleNumber); + fltx4* GetM128AttributePtrForWrite(int nAttribute, size_t* pStrideOut); + FourVectors* Get4VAttributePtrForWrite(int nAttribute, size_t* pStrideOut); + + const float* GetInitialFloatAttributePtr(int nAttribute, int nParticleNumber) const; + const fltx4* GetInitialM128AttributePtr(int nAttribute, size_t* pStrideOut) const; + const FourVectors* GetInitial4VAttributePtr(int nAttribute, size_t* pStrideOut) const; + float* GetInitialFloatAttributePtrForWrite(int nAttribute, int nParticleNumber); + fltx4* GetInitialM128AttributePtrForWrite(int nAttribute, size_t* pStrideOut); + + void Simulate(float dt, bool updateBboxOnly); + void SkipToTime(float t); + + void Render(IMatRenderContext* pRenderContext, bool bTranslucentOnly = false, void* pCameraObject = NULL); + + bool IsValid(void) const; + const char* GetName() const; + + bool IsFinished(void); + + bool IsValidAttributePtr(int nAttribute, const void* pPtr) const; + + void SwapPosAndPrevPos(void); + + void SetNActiveParticles(int nCount); + void KillParticle(int nPidx); + + void StopEmission(bool bInfiniteOnly = false, bool bRemoveAllParticles = false, bool bWakeOnStop = false); + void StartEmission(bool bInfiniteOnly = false); + void SetDormant(bool bDormant); + + const Vector& GetControlPointAtCurrentTime(int nControlPoint) const; + void GetControlPointOrientationAtCurrentTime(int nControlPoint, Vector* pForward, Vector* pRight, Vector* pUp) const; + void GetControlPointTransformAtCurrentTime(int nControlPoint, matrix3x4_t* pMat); + void GetControlPointTransformAtCurrentTime(int nControlPoint, VMatrix* pMat); + int GetControlPointParent(int nControlPoint) const; + + void GetControlPointAtTime(int nControlPoint, float flTime, Vector* pControlPoint) const; + void GetControlPointAtPrevTime(int nControlPoint, Vector* pControlPoint) const; + void GetControlPointOrientationAtTime(int nControlPoint, float flTime, Vector* pForward, Vector* pRight, Vector* pUp); + void GetControlPointTransformAtTime(int nControlPoint, float flTime, matrix3x4_t* pMat); + void GetControlPointTransformAtTime(int nControlPoint, float flTime, VMatrix* pMat); + void GetControlPointTransformAtTime(int nControlPoint, float flTime, CParticleSIMDTransformation* pXForm); + int GetHighestControlPoint(void) const; + + bool HasMoved() const; + + bool ReadsControlPoint(int nPoint) const; + + int RandomInt(int nMin, int nMax); + float RandomFloat(float flMin, float flMax); + float RandomFloatExp(float flMin, float flMax, float flExponent); + void RandomVector(float flMin, float flMax, Vector* pVector); + void RandomVector(const Vector& vecMin, const Vector& vecMax, Vector* pVector); + float RandomVectorInUnitSphere(Vector* pVector); + + int RandomInt(int nRandomSampleId, int nMin, int nMax); + float RandomFloat(int nRandomSampleId, float flMin, float flMax); + float RandomFloatExp(int nRandomSampleId, float flMin, float flMax, float flExponent); + void RandomVector(int nRandomSampleId, float flMin, float flMax, Vector* pVector); + void RandomVector(int nRandomSampleId, const Vector& vecMin, const Vector& vecMax, Vector* pVector); + float RandomVectorInUnitSphere(int nRandomSampleId, Vector* pVector); + + fltx4 RandomFloat(const FourInts& ParticleID, int nRandomSampleOffset); + + + int OperatorRandomSampleOffset() const; + + void GetBounds(Vector* pMin, Vector* pMax); + + void VisualizeOperator(const DmObjectId_t* pOpId = NULL); + + bool UsesPowerOfTwoFrameBufferTexture(bool bThisFrame) const; + + bool UsesFullFrameBufferTexture(bool bThisFrame) const; + + bool IsTranslucent() const; + + bool IsTwoPass() const; + + bool IsBatchable() const; + + int GetRendererCount() const; + CParticleOperatorInstance* GetRenderer(int i); + void* GetRendererContext(int i); + + + bool CheckIfOperatorShouldRun(CParticleOperatorInstance const* op, float* pflCurStrength = NULL); + + Vector TransformAxis(const Vector& SrcAxis, bool bLocalSpace, int nControlPointNumber = 0); + + const ParticleRenderData_t* GetRenderList(IMatRenderContext* pRenderContext, bool bSorted, int* pNparticles, CParticleVisibilityData* pVisibilityData); + + void CalculatePathValues(CPathParameters const& PathIn, + float flTimeStamp, + Vector* pStartPnt, + Vector* pMidPnt, + Vector* pEndPnt + ); + + int GetGroupID() const; + + void InitializeNewParticles(int nFirstParticle, int nParticleCount, uint32 nInittedMask); + + void UpdateHitBoxInfo(int nControlPointNumber); + + void UnlinkFromDefList(); + + CParticleCollection* GetNextCollectionUsingSameDef() { return m_pNextDef; } + + CUtlReference< CSheet > m_Sheet; + + + +protected: + CParticleCollection(); + + bool Init(const char* pParticleSystemName); + bool Init(CParticleSystemDefinition* pDef); + + void BloatBoundsUsingControlPoint(); + +private: + void GenerateSortedIndexList(Vector vecCameraPos, CParticleVisibilityData* pVisibilityData, bool bSorted); + + void Init(CParticleSystemDefinition* pDef, float flDelay, int nRandomSeed); + void InitStorage(CParticleSystemDefinition* pDef); + void InitParticleCreationTime(int nFirstParticle, int nNumToInit); + void CopyInitialAttributeValues(int nStartParticle, int nNumParticles); + void ApplyKillList(void); + void SetAttributeToConstant(int nAttribute, float fValue); + void SetAttributeToConstant(int nAttribute, float fValueX, float fValueY, float fValueZ); + void InitParticleAttributes(int nStartParticle, int nNumParticles, int nAttrsLeftToInit); + + void FillAttributeWithConstant(int nAttribute, float fValue); + + void UpdatePrevControlPoints(float dt); + + float* GetConstantAttributeMemory(int nAttribute); + + void SwapAdjacentParticles(int hParticle); + + void UnlinkParticle(int hParticle); + + void InsertParticleBefore(int hParticle, int hBefore); + + void MoveParticle(int nInitialIndex, int nNewIndex); + + float ComputeSqrDistanceToParticle(int hParticle, const Vector& vecPosition) const; + + void GrowDistSqrBounds(float flDistSqr); + + void SimulateFirstFrame(); + + bool SystemContainsParticlesWithBoolSet(bool CParticleCollection::* pField) const; + bool ContainsOpaqueCollections(); + bool ComputeUsesPowerOfTwoFrameBufferTexture(); + bool ComputeUsesFullFrameBufferTexture(); + bool ComputeIsTranslucent(); + bool ComputeIsTwoPass(); + bool ComputeIsBatchable(); + bool ComputeRequiresOrderInvariance(); + + void LabelTextureUsage(void); + + void LinkIntoDefList(); + +public: + fltx4 m_fl4CurTime; + + int m_nPaddedActiveParticles; + float m_flCurTime; + + int m_nActiveParticles; + float m_flDt; + float m_flPreviousDt; + float m_flNextSleepTime; + + CUtlReference< CParticleSystemDefinition > m_pDef; + int m_nAllocatedParticles; + int m_nMaxAllowedParticles; + bool m_bDormant; + bool m_bEmissionStopped; + bool m_bRequiresOrderInvariance; + + int m_LocalLightingCP; + Color m_LocalLighting; + + CParticleControlPoint m_ControlPoints[MAX_PARTICLE_CONTROL_POINTS]; + + CModelHitBoxesInfo m_ControlPointHitBoxes[MAX_PARTICLE_CONTROL_POINTS]; + + uint8* m_pOperatorContextData; + CParticleCollection* m_pNext; + CParticleCollection* m_pPrev; + + struct CWorldCollideContextData* m_pCollisionCacheData[NUM_COLLISION_CACHE_MODES]; + CParticleCollection* m_pParent; + + CUtlIntrusiveDList m_Children; + + void* operator new(size_t nSize); + void* operator new(size_t size, int nBlockUse, const char* pFileName, int nLine); + void operator delete(void* pData); + void operator delete(void* p, int nBlockUse, const char* pFileName, int nLine); + + +protected: + bool m_bBoundsValid; + Vector m_MinBounds; + Vector m_MaxBounds; + int m_nHighestCP; + +private: + + + unsigned char* m_pParticleMemory; + unsigned char* m_pParticleInitialMemory; + unsigned char* m_pConstantMemory; + + int m_nPerParticleInitializedAttributeMask; + int m_nPerParticleUpdatedAttributeMask; + int m_nPerParticleReadInitialAttributeMask; + float* m_pParticleAttributes[MAX_PARTICLE_ATTRIBUTES]; + float* m_pParticleInitialAttributes[MAX_PARTICLE_ATTRIBUTES]; + size_t m_nParticleFloatStrides[MAX_PARTICLE_ATTRIBUTES]; + size_t m_nParticleInitialFloatStrides[MAX_PARTICLE_ATTRIBUTES]; + + float* m_pConstantAttributes; + + uint64 m_nControlPointReadMask; + int m_nParticleFlags; + bool m_bIsScrubbable : 1; + bool m_bIsRunningInitializers : 1; + bool m_bIsRunningOperators : 1; + bool m_bIsTranslucent : 1; + bool m_bIsTwoPass : 1; + bool m_bAnyUsesPowerOfTwoFrameBufferTexture : 1; + bool m_bAnyUsesFullFrameBufferTexture : 1; + bool m_bIsBatchable : 1; + + bool m_bUsesPowerOfTwoFrameBufferTexture; + bool m_bUsesFullFrameBufferTexture; + + int m_nDrawnFrames; + int m_nSimulatedFrames; + + Vector m_Center; + + int m_nUniqueParticleId; + + int m_nRandomQueryCount; + int m_nRandomSeed; + int m_nOperatorRandomSampleOffset; + + float m_flMinDistSqr; + float m_flMaxDistSqr; + float m_flOOMaxDistSqr; + Vector m_vecLastCameraPos; + float m_flLastMinDistSqr; + float m_flLastMaxDistSqr; + + int m_nNumParticlesToKill; + int* m_pParticleKillList; + + CParticleCollection* m_pNextDef; + CParticleCollection* m_pPrevDef; + + void LoanKillListTo(CParticleCollection* pBorrower) const; + bool HasAttachedKillList(void) const; + + + CParticleOperatorInstance* m_pRenderOp; + friend class CParticleSystemMgr; + friend class CParticleOperatorInstance; +}; + + + +class CM128InitialAttributeIterator : public CStridedConstPtr +{ +public: + FORCEINLINE CM128InitialAttributeIterator(int nAttribute, CParticleCollection* pParticles) + { + m_pData = pParticles->GetInitialM128AttributePtr(nAttribute, &m_nStride); + } +}; + + +class CM128AttributeIterator : public CStridedConstPtr +{ +public: + FORCEINLINE CM128AttributeIterator(int nAttribute, CParticleCollection* pParticles) + { + m_pData = pParticles->GetM128AttributePtr(nAttribute, &m_nStride); + } +}; + +class C4IAttributeIterator : public CStridedConstPtr +{ +public: + FORCEINLINE C4IAttributeIterator(int nAttribute, CParticleCollection* pParticles) + { + m_pData = pParticles->Get4IAttributePtr(nAttribute, &m_nStride); + } +}; + +class CM128AttributeWriteIterator : public CStridedPtr +{ +public: + FORCEINLINE CM128AttributeWriteIterator(void) + { + } + FORCEINLINE void Init(int nAttribute, CParticleCollection* pParticles) + { + m_pData = pParticles->GetM128AttributePtrForWrite(nAttribute, &m_nStride); + } + FORCEINLINE CM128AttributeWriteIterator(int nAttribute, CParticleCollection* pParticles) + { + Init(nAttribute, pParticles); + } +}; + +class C4VAttributeIterator : public CStridedConstPtr +{ +public: + FORCEINLINE C4VAttributeIterator(int nAttribute, CParticleCollection* pParticles) + { + m_pData = pParticles->Get4VAttributePtr(nAttribute, &m_nStride); + } +}; + +class C4VInitialAttributeIterator : public CStridedConstPtr +{ +public: + FORCEINLINE C4VInitialAttributeIterator(int nAttribute, CParticleCollection* pParticles) + { + m_pData = pParticles->GetInitial4VAttributePtr(nAttribute, &m_nStride); + } +}; + +class C4VAttributeWriteIterator : public CStridedPtr +{ +public: + FORCEINLINE C4VAttributeWriteIterator(int nAttribute, CParticleCollection* pParticles) + { + m_pData = pParticles->Get4VAttributePtrForWrite(nAttribute, &m_nStride); + } +}; + + +inline bool CParticleCollection::HasAttachedKillList(void) const +{ + return m_pParticleKillList != NULL; +} + +inline bool CParticleCollection::ReadsControlPoint(int nPoint) const +{ + return (m_nControlPointReadMask & (1ULL << nPoint)) != 0; +} + +inline void CParticleCollection::SetNActiveParticles(int nCount) +{ + Assert(nCount <= m_nMaxAllowedParticles); + m_nActiveParticles = nCount; + m_nPaddedActiveParticles = (nCount + 3) / 4; +} + +inline void CParticleCollection::SwapPosAndPrevPos(void) +{ + Assert(m_nParticleFloatStrides[PARTICLE_ATTRIBUTE_XYZ] == m_nParticleFloatStrides[PARTICLE_ATTRIBUTE_PREV_XYZ]); + V_swap(m_pParticleAttributes[PARTICLE_ATTRIBUTE_XYZ], m_pParticleAttributes[PARTICLE_ATTRIBUTE_PREV_XYZ]); +} + +inline void CParticleCollection::LoanKillListTo(CParticleCollection* pBorrower) const +{ + Assert(!pBorrower->m_pParticleKillList); + pBorrower->m_nNumParticlesToKill = 0; + pBorrower->m_pParticleKillList = m_pParticleKillList; +} + +inline void CParticleCollection::SetAttributeToConstant(int nAttribute, float fValue) +{ + float* fconst = m_pConstantAttributes + 4 * 3 * nAttribute; + fconst[0] = fconst[1] = fconst[2] = fconst[3] = fValue; +} + +inline void CParticleCollection::SetAttributeToConstant(int nAttribute, float fValueX, float fValueY, float fValueZ) +{ + float* fconst = m_pConstantAttributes + 4 * 3 * nAttribute; + fconst[0] = fconst[1] = fconst[2] = fconst[3] = fValueX; + fconst[4] = fconst[5] = fconst[6] = fconst[7] = fValueY; + fconst[8] = fconst[9] = fconst[10] = fconst[11] = fValueZ; +} + +inline void CParticleCollection::SetControlPoint(int nWhichPoint, const Vector& v) +{ + Assert((nWhichPoint >= 0) && (nWhichPoint < MAX_PARTICLE_CONTROL_POINTS)); + m_nHighestCP = MAX(m_nHighestCP, nWhichPoint); + m_ControlPoints[nWhichPoint].m_Position = v; + for (CParticleCollection* i = m_Children.m_pHead; i; i = i->m_pNext) + { + i->SetControlPoint(nWhichPoint, v); + } +} + +inline void CParticleCollection::SetControlPointObject(int nWhichPoint, void* pObject) +{ + Assert((nWhichPoint >= 0) && (nWhichPoint < MAX_PARTICLE_CONTROL_POINTS)); + m_ControlPoints[nWhichPoint].m_pObject = pObject; + for (CParticleCollection* i = m_Children.m_pHead; i; i = i->m_pNext) + { + i->SetControlPointObject(nWhichPoint, pObject); + } +} + +inline void CParticleCollection::SetControlPointOrientation(int nWhichPoint, const Vector& forward, + const Vector& right, const Vector& up) +{ + Assert((nWhichPoint >= 0) && (nWhichPoint < MAX_PARTICLE_CONTROL_POINTS)); + + if (fabs(DotProduct(forward, up)) <= 0.1f + && fabs(DotProduct(forward, right)) <= 0.1f + && fabs(DotProduct(right, up)) <= 0.1f) + { + m_ControlPoints[nWhichPoint].m_ForwardVector = forward; + m_ControlPoints[nWhichPoint].m_UpVector = up; + m_ControlPoints[nWhichPoint].m_RightVector = right; + + for (CParticleCollection* i = m_Children.m_pHead; i; i = i->m_pNext) + { + i->SetControlPointOrientation(nWhichPoint, forward, right, up); + } + } + else + { + Warning("Attempt to set particle collection %s to invalid orientation matrix\n", GetName()); + } +} + +inline Vector CParticleCollection::TransformAxis(const Vector& SrcAxis, bool bLocalSpace, + int nControlPointNumber) +{ + if (bLocalSpace) + { + return + (SrcAxis.x * m_ControlPoints[nControlPointNumber].m_RightVector) + + (SrcAxis.y * m_ControlPoints[nControlPointNumber].m_ForwardVector) + + (SrcAxis.z * m_ControlPoints[nControlPointNumber].m_UpVector); + } + else + return SrcAxis; +} + + +inline void CParticleCollection::SetControlPointOrientation(int nWhichPoint, const Quaternion& q) +{ + matrix3x4_t mat; + Vector vecForward, vecUp, vecRight; + QuaternionMatrix(q, mat); + MatrixVectors(mat, &vecForward, &vecRight, &vecUp); + SetControlPointOrientation(nWhichPoint, vecForward, vecRight, vecUp); +} + +inline void CParticleCollection::SetControlPointForwardVector(int nWhichPoint, const Vector& v) +{ + Assert((nWhichPoint >= 0) && (nWhichPoint < MAX_PARTICLE_CONTROL_POINTS)); + m_ControlPoints[nWhichPoint].m_ForwardVector = v; + for (CParticleCollection* i = m_Children.m_pHead; i; i = i->m_pNext) + { + i->SetControlPointForwardVector(nWhichPoint, v); + } +} + +inline void CParticleCollection::SetControlPointUpVector(int nWhichPoint, const Vector& v) +{ + Assert((nWhichPoint >= 0) && (nWhichPoint < MAX_PARTICLE_CONTROL_POINTS)); + m_ControlPoints[nWhichPoint].m_UpVector = v; + for (CParticleCollection* i = m_Children.m_pHead; i; i = i->m_pNext) + { + i->SetControlPointUpVector(nWhichPoint, v); + } +} + +inline void CParticleCollection::SetControlPointRightVector(int nWhichPoint, const Vector& v) +{ + Assert((nWhichPoint >= 0) && (nWhichPoint < MAX_PARTICLE_CONTROL_POINTS)); + m_ControlPoints[nWhichPoint].m_RightVector = v; + for (CParticleCollection* i = m_Children.m_pHead; i; i = i->m_pNext) + { + i->SetControlPointRightVector(nWhichPoint, v); + } +} + +inline void CParticleCollection::SetControlPointParent(int nWhichPoint, int n) +{ + Assert((nWhichPoint >= 0) && (nWhichPoint < MAX_PARTICLE_CONTROL_POINTS)); + m_ControlPoints[nWhichPoint].m_nParent = n; + for (CParticleCollection* i = m_Children.m_pHead; i; i = i->m_pNext) + { + i->SetControlPointParent(nWhichPoint, n); + } +} + + +inline float* CParticleCollection::GetConstantAttributeMemory(int nAttribute) +{ + return m_pConstantAttributes + 3 * 4 * nAttribute; +} + +inline int CParticleCollection::OperatorRandomSampleOffset() const +{ + return m_nOperatorRandomSampleOffset; +} + +inline int CParticleCollection::RandomInt(int nRandomSampleId, int nMin, int nMax) +{ + float flRand = s_pRandomFloats[(m_nRandomSeed + nRandomSampleId) & RANDOM_FLOAT_MASK]; + flRand *= (nMax + 1 - nMin); + int nRand = (int)flRand + nMin; + return nRand; +} + +inline float CParticleCollection::RandomFloat(int nRandomSampleId, float flMin, float flMax) +{ + float flRand = s_pRandomFloats[(m_nRandomSeed + nRandomSampleId) & RANDOM_FLOAT_MASK]; + flRand *= (flMax - flMin); + flRand += flMin; + return flRand; +} + +inline fltx4 CParticleCollection::RandomFloat(const FourInts& ParticleID, int nRandomSampleOffset) +{ + fltx4 Retval; + int nOfs = m_nRandomSeed + nRandomSampleOffset; + SubFloat(Retval, 0) = s_pRandomFloats[(nOfs + ParticleID.m_nValue[0]) & RANDOM_FLOAT_MASK]; + SubFloat(Retval, 1) = s_pRandomFloats[(nOfs + ParticleID.m_nValue[1]) & RANDOM_FLOAT_MASK]; + SubFloat(Retval, 2) = s_pRandomFloats[(nOfs + ParticleID.m_nValue[2]) & RANDOM_FLOAT_MASK]; + SubFloat(Retval, 3) = s_pRandomFloats[(nOfs + ParticleID.m_nValue[3]) & RANDOM_FLOAT_MASK]; + return Retval; +} + + +inline float CParticleCollection::RandomFloatExp(int nRandomSampleId, float flMin, float flMax, float flExponent) +{ + float flRand = s_pRandomFloats[(m_nRandomSeed + nRandomSampleId) & RANDOM_FLOAT_MASK]; + flRand = powf(flRand, flExponent); + flRand *= (flMax - flMin); + flRand += flMin; + return flRand; +} + +inline void CParticleCollection::RandomVector(int nRandomSampleId, float flMin, float flMax, Vector* pVector) +{ + float flDelta = flMax - flMin; + int nBaseId = m_nRandomSeed + nRandomSampleId; + + pVector->x = s_pRandomFloats[nBaseId & RANDOM_FLOAT_MASK]; + pVector->x *= flDelta; + pVector->x += flMin; + + pVector->y = s_pRandomFloats[(nBaseId + 1) & RANDOM_FLOAT_MASK]; + pVector->y *= flDelta; + pVector->y += flMin; + + pVector->z = s_pRandomFloats[(nBaseId + 2) & RANDOM_FLOAT_MASK]; + pVector->z *= flDelta; + pVector->z += flMin; +} + +inline void CParticleCollection::RandomVector(int nRandomSampleId, const Vector& vecMin, const Vector& vecMax, Vector* pVector) +{ + int nBaseId = m_nRandomSeed + nRandomSampleId; + pVector->x = RandomFloat(nBaseId, vecMin.x, vecMax.x); + pVector->y = RandomFloat(nBaseId + 1, vecMin.y, vecMax.y); + pVector->z = RandomFloat(nBaseId + 2, vecMin.z, vecMax.z); +} + +inline int CParticleCollection::RandomInt(int nMin, int nMax) +{ + return RandomInt(m_nRandomQueryCount++, nMin, nMax); +} + +inline float CParticleCollection::RandomFloat(float flMin, float flMax) +{ + return RandomFloat(m_nRandomQueryCount++, flMin, flMax); +} + +inline float CParticleCollection::RandomFloatExp(float flMin, float flMax, float flExponent) +{ + return RandomFloatExp(m_nRandomQueryCount++, flMin, flMax, flExponent); +} + +inline void CParticleCollection::RandomVector(float flMin, float flMax, Vector* pVector) +{ + RandomVector(m_nRandomQueryCount++, flMin, flMax, pVector); +} + +inline void CParticleCollection::RandomVector(const Vector& vecMin, const Vector& vecMax, Vector* pVector) +{ + RandomVector(m_nRandomQueryCount++, vecMin, vecMax, pVector); +} + +inline float CParticleCollection::RandomVectorInUnitSphere(Vector* pVector) +{ + return RandomVectorInUnitSphere(m_nRandomQueryCount++, pVector); +} + + +inline const float* CParticleCollection::GetFloatAttributePtr(int nAttribute, int nParticleNumber) const +{ + Assert(nParticleNumber < m_nAllocatedParticles); + int block_ofs = nParticleNumber / 4; + return m_pParticleAttributes[nAttribute] + + m_nParticleFloatStrides[nAttribute] * block_ofs + + (nParticleNumber & 3); +} + +inline int* CParticleCollection::GetIntAttributePtrForWrite(int nAttribute, int nParticleNumber) +{ + return reinterpret_cast(GetFloatAttributePtrForWrite(nAttribute, nParticleNumber)); +} + +inline const int* CParticleCollection::GetIntAttributePtr(int nAttribute, int nParticleNumber) const +{ + return (int*)GetFloatAttributePtr(nAttribute, nParticleNumber); +} + +inline const fltx4* CParticleCollection::GetM128AttributePtr(int nAttribute, size_t* pStrideOut) const +{ + *(pStrideOut) = m_nParticleFloatStrides[nAttribute] / 4; + return reinterpret_cast(m_pParticleAttributes[nAttribute]); +} + +inline const FourInts* CParticleCollection::Get4IAttributePtr(int nAttribute, size_t* pStrideOut) const +{ + *(pStrideOut) = m_nParticleFloatStrides[nAttribute] / 4; + return reinterpret_cast(m_pParticleAttributes[nAttribute]); +} + +inline const int32* CParticleCollection::GetIntAttributePtr(int nAttribute, size_t* pStrideOut) const +{ + *(pStrideOut) = m_nParticleFloatStrides[nAttribute]; + return reinterpret_cast(m_pParticleAttributes[nAttribute]); +} + +inline const FourVectors* CParticleCollection::Get4VAttributePtr(int nAttribute, size_t* pStrideOut) const +{ + *(pStrideOut) = m_nParticleFloatStrides[nAttribute] / 12; + return reinterpret_cast(m_pParticleAttributes[nAttribute]); +} + +inline FourVectors* CParticleCollection::Get4VAttributePtrForWrite(int nAttribute, size_t* pStrideOut) +{ + *(pStrideOut) = m_nParticleFloatStrides[nAttribute] / 12; + return reinterpret_cast(m_pParticleAttributes[nAttribute]); +} + +inline const FourVectors* CParticleCollection::GetInitial4VAttributePtr(int nAttribute, size_t* pStrideOut) const +{ + *(pStrideOut) = m_nParticleInitialFloatStrides[nAttribute] / 12; + return reinterpret_cast(m_pParticleInitialAttributes[nAttribute]); +} + +inline float* CParticleCollection::GetFloatAttributePtrForWrite(int nAttribute, int nParticleNumber) +{ + Assert(!m_bIsRunningInitializers || (m_nPerParticleInitializedAttributeMask & (1 << nAttribute))); + Assert(!m_bIsRunningOperators || (m_nPerParticleUpdatedAttributeMask & (1 << nAttribute))); + + Assert(m_nParticleFloatStrides[nAttribute] != 0); + + Assert(nParticleNumber < m_nAllocatedParticles); + int block_ofs = nParticleNumber / 4; + return m_pParticleAttributes[nAttribute] + + m_nParticleFloatStrides[nAttribute] * block_ofs + + (nParticleNumber & 3); +} + +inline fltx4* CParticleCollection::GetM128AttributePtrForWrite(int nAttribute, size_t* pStrideOut) +{ + if (!HushAsserts()) + { + Assert(!m_bIsRunningInitializers || (m_nPerParticleInitializedAttributeMask & (1 << nAttribute))); + Assert(!m_bIsRunningOperators || (m_nPerParticleUpdatedAttributeMask & (1 << nAttribute))); + Assert(m_nParticleFloatStrides[nAttribute] != 0); + } + + *(pStrideOut) = m_nParticleFloatStrides[nAttribute] / 4; + return reinterpret_cast(m_pParticleAttributes[nAttribute]); +} + +inline const float* CParticleCollection::GetInitialFloatAttributePtr(int nAttribute, int nParticleNumber) const +{ + Assert(nParticleNumber < m_nAllocatedParticles); + int block_ofs = nParticleNumber / 4; + return m_pParticleInitialAttributes[nAttribute] + m_nParticleInitialFloatStrides[nAttribute] * block_ofs + (nParticleNumber & 3); +} + +inline const fltx4* CParticleCollection::GetInitialM128AttributePtr(int nAttribute, size_t* pStrideOut) const +{ + *(pStrideOut) = m_nParticleInitialFloatStrides[nAttribute] / 4; + return reinterpret_cast(m_pParticleInitialAttributes[nAttribute]); +} + +inline float* CParticleCollection::GetInitialFloatAttributePtrForWrite(int nAttribute, int nParticleNumber) +{ + Assert(nParticleNumber < m_nAllocatedParticles); + Assert(m_nPerParticleReadInitialAttributeMask & (1 << nAttribute)); + int block_ofs = nParticleNumber / 4; + return m_pParticleInitialAttributes[nAttribute] + m_nParticleInitialFloatStrides[nAttribute] * block_ofs + (nParticleNumber & 3); +} + +inline fltx4* CParticleCollection::GetInitialM128AttributePtrForWrite(int nAttribute, size_t* pStrideOut) +{ + Assert(m_nPerParticleReadInitialAttributeMask & (1 << nAttribute)); + *(pStrideOut) = m_nParticleInitialFloatStrides[nAttribute] / 4; + return reinterpret_cast(m_pParticleInitialAttributes[nAttribute]); +} + +inline bool CParticleCollection::IsValidAttributePtr(int nAttribute, const void* pPtr) const +{ + if (pPtr < m_pParticleAttributes[nAttribute]) + return false; + + size_t nArraySize = m_nParticleFloatStrides[nAttribute] * m_nAllocatedParticles / 4; + void* pMaxPtr = m_pParticleAttributes[nAttribute] + nArraySize; + return (pPtr <= pMaxPtr); +} + + +FORCEINLINE void CParticleCollection::KillParticle(int nPidx) +{ + Assert(nPidx < m_nActiveParticles + 4); + + Assert(m_nNumParticlesToKill < MAX_PARTICLES_IN_A_SYSTEM); + m_pParticleKillList[m_nNumParticlesToKill++] = nPidx; +} + +inline void CParticleCollection::FillAttributeWithConstant(int nAttribute, float fValue) +{ + size_t stride; + fltx4* pAttr = GetM128AttributePtrForWrite(nAttribute, &stride); + fltx4 fill = ReplicateX4(fValue); + for (int i = 0; i < m_nPaddedActiveParticles; i++) + { + *(pAttr) = fill; + pAttr += stride; + } +} + + +FORCEINLINE void SetVectorAttribute(float* pAttribute, float x, float y, float z) +{ + pAttribute[0] = x; + pAttribute[4] = y; + pAttribute[8] = z; +} + +FORCEINLINE void SetVectorAttribute(float* pAttribute, const Vector& v) +{ + pAttribute[0] = v.x; + pAttribute[4] = v.y; + pAttribute[8] = v.z; +} + +FORCEINLINE void SetVectorFromAttribute(Vector& v, const float* pAttribute) +{ + v.x = pAttribute[0]; + v.y = pAttribute[4]; + v.z = pAttribute[8]; +} + + +FORCEINLINE float CParticleCollection::ComputeSqrDistanceToParticle(int hParticle, const Vector& vecPosition) const +{ + const float* xyz = GetFloatAttributePtr(PARTICLE_ATTRIBUTE_XYZ, hParticle); + Vector vecParticlePosition(xyz[0], xyz[4], xyz[8]); + return vecParticlePosition.DistToSqr(vecPosition); +} + + +FORCEINLINE void CParticleCollection::GrowDistSqrBounds(float flDistSqr) +{ + if (m_flLastMinDistSqr > flDistSqr) + { + m_flLastMinDistSqr = flDistSqr; + } + else if (m_flLastMaxDistSqr < flDistSqr) + { + m_flLastMaxDistSqr = flDistSqr; + } +} + + + + +struct ParticleChildrenInfo_t +{ + DmObjectId_t m_Id; + CUtlString m_Name; + bool m_bUseNameBasedLookup; + float m_flDelay; +}; + + +class CParticleSystemDefinition +{ + DECLARE_DMXELEMENT_UNPACK(); + DECLARE_REFERENCED_CLASS(CParticleSystemDefinition); + + +public: + CParticleSystemDefinition(void); + ~CParticleSystemDefinition(void); + + void Read(CDmxElement* pElement); + CDmxElement* Write(); + + const char* MaterialName() const; + IMaterial* GetMaterial() const; + const char* GetName() const; + const DmObjectId_t& GetId() const; + + bool UsesPowerOfTwoFrameBufferTexture(); + + bool UsesFullFrameBufferTexture(); + + bool ShouldAlwaysPrecache() const; + + bool ShouldBatch() const; + + bool IsViewModelEffect() const; + + CParticleCollection* FirstCollection(); + + float GetCullRadius() const; + float GetCullFillCost() const; + int GetCullControlPoint() const; + const char* GetCullReplacementDefinition() const; + + bool HasRetirementBeenChecked(int nFrame) const; + void MarkRetirementCheck(int nFrame); + + void MarkReadsControlPoint(int nPoint); + bool ReadsControlPoint(int nPoint) const; + +private: + void Precache(); + void Uncache(); + bool IsPrecached() const; + + void UnlinkAllCollections(); + + void SetupContextData(); + void ParseChildren(CDmxElement* pElement); + void ParseOperators(const char* pszName, ParticleFunctionType_t nFunctionType, + CDmxElement* pElement, CUtlVector& out_list); + void WriteChildren(CDmxElement* pElement); + void WriteOperators(CDmxElement* pElement, const char* pOpKeyName, + const CUtlVector& inList); + CUtlVector* GetOperatorList(ParticleFunctionType_t type); + CParticleOperatorInstance* FindOperatorById(ParticleFunctionType_t type, const DmObjectId_t& id); + +private: + int m_nInitialParticles; + int m_nPerParticleUpdatedAttributeMask; + int m_nPerParticleInitializedAttributeMask; + int m_nInitialAttributeReadMask; + int m_nAttributeReadMask; + uint64 m_nControlPointReadMask; + Vector m_BoundingBoxMin; + Vector m_BoundingBoxMax; + char m_pszMaterialName[MAX_PATH]; + CMaterialReference m_Material; + CParticleCollection* m_pFirstCollection; + char m_pszCullReplacementName[128]; + float m_flCullRadius; + float m_flCullFillCost; + int m_nCullControlPoint; + int m_nRetireCheckFrame; + + Color m_ConstantColor; + float m_flConstantRadius; + float m_flConstantRotation; + float m_flConstantRotationSpeed; + int m_nConstantSequenceNumber; + int m_nConstantSequenceNumber1; + int m_nGroupID; + float m_flMaximumTimeStep; + float m_flMaximumSimTime; + float m_flMinimumSimTime; + int m_nMinimumFrames; + + + bool m_bViewModelEffect; + + + size_t m_nContextDataSize; + DmObjectId_t m_Id; + +public: + float m_flMaxDrawDistance; + float m_flNoDrawTimeToGoToSleep; + + int m_nMaxParticles; + int m_nSkipRenderControlPoint; + CUtlString m_Name; + + CUtlVector m_Operators; + CUtlVector m_Renderers; + CUtlVector m_Initializers; + CUtlVector m_Emitters; + CUtlVector m_ForceGenerators; + CUtlVector m_Constraints; + CUtlVector m_Children; + + CUtlVector m_nOperatorsCtxOffsets; + CUtlVector m_nRenderersCtxOffsets; + CUtlVector m_nInitializersCtxOffsets; + CUtlVector m_nEmittersCtxOffsets; + CUtlVector m_nForceGeneratorsCtxOffsets; + CUtlVector m_nConstraintsCtxOffsets; + + float m_flTotalSimTime; + float m_flUncomittedTotalSimTime; + float m_flMaxMeasuredSimTime; + int m_nMaximumActiveParticles; + bool m_bShouldSort; + bool m_bShouldBatch; + bool m_bIsPrecached : 1; + bool m_bAlwaysPrecache : 1; + + friend class CParticleCollection; + friend class CParticleSystemMgr; +}; + + +inline CParticleSystemDefinition::CParticleSystemDefinition(void) +{ + m_nControlPointReadMask = 0; + m_nInitialAttributeReadMask = 0; + m_nPerParticleInitializedAttributeMask = 0; + m_nPerParticleUpdatedAttributeMask = 0; + m_nAttributeReadMask = 0; + m_flTotalSimTime = 0.0; + m_flMaxMeasuredSimTime = 0.0; + m_nMaximumActiveParticles = 0; + m_bIsPrecached = false; + m_bAlwaysPrecache = false; + m_bShouldBatch = false; + m_bShouldSort = true; + m_pFirstCollection = NULL; + m_flCullRadius = 0.0f; + m_flCullFillCost = 1.0f; + m_nRetireCheckFrame = 0; +} + +inline CParticleSystemDefinition::~CParticleSystemDefinition(void) +{ + UnlinkAllCollections(); + m_Operators.PurgeAndDeleteElements(); + m_Renderers.PurgeAndDeleteElements(); + m_Initializers.PurgeAndDeleteElements(); + m_Emitters.PurgeAndDeleteElements(); + m_ForceGenerators.PurgeAndDeleteElements(); + m_Constraints.PurgeAndDeleteElements(); +} + +inline CParticleCollection* CParticleSystemDefinition::FirstCollection() +{ + return m_pFirstCollection; +} + +inline float CParticleSystemDefinition::GetCullRadius() const +{ + return m_flCullRadius; +} + +inline float CParticleSystemDefinition::GetCullFillCost() const +{ + return m_flCullFillCost; +} + +inline const char* CParticleSystemDefinition::GetCullReplacementDefinition() const +{ + return m_pszCullReplacementName; +} + +inline int CParticleSystemDefinition::GetCullControlPoint() const +{ + return m_nCullControlPoint; +} + +inline void CParticleSystemDefinition::MarkReadsControlPoint(int nPoint) +{ + m_nControlPointReadMask |= (1ULL << nPoint); +} + +inline bool CParticleSystemDefinition::ReadsControlPoint(int nPoint) const +{ + return (m_nControlPointReadMask & (1ULL << nPoint)) != 0; +} + +inline bool CParticleSystemDefinition::HasRetirementBeenChecked(int nFrame) const +{ + return m_nRetireCheckFrame == nFrame; +} + +inline void CParticleSystemDefinition::MarkRetirementCheck(int nFrame) +{ + m_nRetireCheckFrame = nFrame; +} + +inline bool CParticleSystemDefinition::ShouldBatch() const +{ + return m_bShouldBatch; +} + +inline bool CParticleSystemDefinition::IsViewModelEffect() const +{ + return m_bViewModelEffect; +} + +inline const char* CParticleSystemDefinition::MaterialName() const +{ + return m_pszMaterialName; +} + +inline const DmObjectId_t& CParticleSystemDefinition::GetId() const +{ + return m_Id; +} + +inline int CParticleCollection::GetGroupID(void) const +{ + return m_pDef->m_nGroupID; +} + +FORCEINLINE const Vector& CParticleCollection::GetControlPointAtCurrentTime(int nControlPoint) const +{ + Assert(nControlPoint <= GetHighestControlPoint()); + Assert(m_pDef->ReadsControlPoint(nControlPoint)); + return m_ControlPoints[nControlPoint].m_Position; +} + +FORCEINLINE void CParticleCollection::GetControlPointOrientationAtCurrentTime(int nControlPoint, Vector* pForward, Vector* pRight, Vector* pUp) const +{ + Assert(nControlPoint <= GetHighestControlPoint()); + Assert(m_pDef->ReadsControlPoint(nControlPoint)); + + *pForward = m_ControlPoints[nControlPoint].m_ForwardVector; + *pRight = m_ControlPoints[nControlPoint].m_RightVector; + *pUp = m_ControlPoints[nControlPoint].m_UpVector; +} + +FORCEINLINE int CParticleCollection::GetControlPointParent(int nControlPoint) const +{ + Assert(nControlPoint <= GetHighestControlPoint()); + Assert(m_pDef->ReadsControlPoint(nControlPoint)); + return m_ControlPoints[nControlPoint].m_nParent; +} + +FORCEINLINE bool CParticleCollection::IsValid(void) const +{ + return (m_pDef != NULL && m_pDef->GetMaterial()); +} + + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/particles_new.h b/SpyCustom/sdk/particles_new.h new file mode 100644 index 0000000..32abaf7 --- /dev/null +++ b/SpyCustom/sdk/particles_new.h @@ -0,0 +1,295 @@ +#ifndef PARTICLES_NEW_H +#define PARTICLES_NEW_H +#ifdef _WIN32 +#pragma once +#endif + +#include "particlemgr.h" +#include "particles.h" +#include "particlesphererenderer.h" +#include "smartptr.h" +#include "particles_simple.h" +#include "utlobjectreference.h" + + +class CNewParticleEffect : public IParticleEffect, public CParticleCollection, public CDefaultClientRenderable +{ +public: + DECLARE_CLASS_NOBASE(CNewParticleEffect); + DECLARE_REFERENCED_CLASS(CNewParticleEffect); + +public: + friend class CRefCountAccessor; + + CNewParticleEffect* m_pNext; + CNewParticleEffect* m_pPrev; + + void SetSortOrigin(const Vector& vSortOrigin); + bool ShouldDraw(void); + virtual bool IsTransparent(void); + virtual bool IsTwoPass(void); + virtual bool UsesPowerOfTwoFrameBufferTexture(void); + virtual bool UsesFullFrameBufferTexture(void); + const QAngle& GetRenderAngles(void); + const matrix3x4_t& RenderableToWorldTransform(); + void GetRenderBounds(Vector& mins, Vector& maxs); + + void DetectChanges(void); + const Vector& GetRenderOrigin(void); + PMaterialHandle GetPMaterial(const char* name); + bool RecalculateBoundingBox(); + Particle* AddParticle(unsigned int particleSize, PMaterialHandle material, const Vector& origin); + const char* GetEffectName(); + void SetDontRemove(bool bSet); + void SetDrawn(bool bDrawn); + void SetFirstFrameFlag(bool bFirst); + void SetNeedsBBoxUpdate(bool bNeedsUpdate); + void SetAutoUpdateBBox(bool bNeedsUpdate); + void SetRemoveFlag(void); + bool GetRemoveFlag(void); + bool GetFirstFrameFlag(void); + bool GetNeedsBBoxUpdate(void); + bool GetAutoUpdateBBox(void); + bool ShouldPerformCullCheck() const; + void MarkShouldPerformCullCheck(bool bEnable); + CBaseEntity* GetOwner(void) { return m_hOwner; } + void SetOwner(CBaseEntity* pOwner) { m_hOwner = pOwner; } + CNewParticleEffect* ReplaceWith(const char* pParticleSystemName); + + static CSmartPtr Create(CBaseEntity* pOwner, const char* pParticleSystemName, + const char* pDebugName = NULL); + static CSmartPtr Create(CBaseEntity* pOwner, CParticleSystemDefinition* pDef, + const char* pDebugName = NULL); + virtual int DrawModel(int flags); + + void DebugDrawBbox(bool bCulled); + +public: + void StopEmission(bool bInfiniteOnly = false, bool bRemoveAllParticles = false, bool bWakeOnStop = false); + void SetDormant(bool bDormant); + void SetControlPoint(int nWhichPoint, const Vector& v); + void SetControlPointEntity(int nWhichPoint, CBaseEntity* pEntity); + void SetControlPointOrientation(int nWhichPoint, const Quaternion& q); + void SetControlPointOrientation(int nWhichPoint, const Vector& forward, const Vector& right, const Vector& up); + void SetControlPointForwardVector(int nWhichPoint, const Vector& v); + void SetControlPointUpVector(int nWhichPoint, const Vector& v); + void SetControlPointRightVector(int nWhichPoint, const Vector& v); + + FORCEINLINE EHANDLE const& GetControlPointEntity(int nWhichPoint) + { + return m_hControlPointOwners[nWhichPoint]; + } + + +public: + + virtual void SimulateParticles(CParticleSimulateIterator* pIterator) + { + } + virtual void RenderParticles(CParticleRenderIterator* pIterator) + { + } + + virtual void SetParticleCullRadius(float radius); + virtual void NotifyRemove(void); + virtual const Vector& GetSortOrigin(void); + + virtual void Update(float flTimeDelta); + + void SetDynamicallyAllocated(bool bDynamic = true); + + virtual bool ShouldSimulate() const { return m_bSimulate; } + virtual void SetShouldSimulate(bool bSim) { m_bSimulate = bSim; } + + int AllocateToolParticleEffectId(); + int GetToolParticleEffectId() const; + CNewParticleEffect(CBaseEntity* pOwner, const char* pEffectName); + CNewParticleEffect(CBaseEntity* pOwner, CParticleSystemDefinition* pEffect); + virtual ~CNewParticleEffect(); + +protected: + int IsReleased(); + + const char* m_pDebugName; + + bool m_bDontRemove : 1; + bool m_bRemove : 1; + bool m_bDrawn : 1; + bool m_bNeedsBBoxUpdate : 1; + bool m_bIsFirstFrame : 1; + bool m_bAutoUpdateBBox : 1; + bool m_bAllocated : 1; + bool m_bSimulate : 1; + bool m_bShouldPerformCullCheck : 1; + + int m_nToolParticleEffectId; + Vector m_vSortOrigin; + EHANDLE m_hOwner; + EHANDLE m_hControlPointOwners[MAX_PARTICLE_CONTROL_POINTS]; + + Vector m_LastMin; + Vector m_LastMax; + +private: + void AddRef(); + void Release(); + void RecordControlPointOrientation(int nWhichPoint); + void Construct(); + + int m_RefCount; + CNewParticleEffect(const CNewParticleEffect&); +}; + + +inline int CNewParticleEffect::GetToolParticleEffectId() const +{ + return m_nToolParticleEffectId; +} + +inline int CNewParticleEffect::AllocateToolParticleEffectId() +{ + m_nToolParticleEffectId = ParticleMgr()->AllocateToolParticleEffectId(); + return m_nToolParticleEffectId; +} + +inline void CNewParticleEffect::SetSortOrigin(const Vector& vSortOrigin) +{ + m_vSortOrigin = vSortOrigin; +} + +inline const Vector& CNewParticleEffect::GetSortOrigin(void) +{ + return m_vSortOrigin; +} + +inline bool CNewParticleEffect::ShouldDraw(void) +{ + return true; +} + +inline bool CNewParticleEffect::IsTransparent(void) +{ + return CParticleCollection::IsTranslucent(); +} + +inline const QAngle& CNewParticleEffect::GetRenderAngles(void) +{ + return vec3_angle; +} + +inline const matrix3x4_t& CNewParticleEffect::RenderableToWorldTransform() +{ + static matrix3x4_t mat; + SetIdentityMatrix(mat); + PositionMatrix(GetRenderOrigin(), mat); + return mat; +} + +inline Vector const& CNewParticleEffect::GetRenderOrigin(void) +{ + return m_vSortOrigin; +} + +inline PMaterialHandle CNewParticleEffect::GetPMaterial(const char* name) +{ + Assert(0); + return NULL; +} + +inline Particle* CNewParticleEffect::AddParticle(unsigned int particleSize, PMaterialHandle material, const Vector& origin) +{ + Assert(0); + return NULL; +} + + +inline const char* CNewParticleEffect::GetEffectName() +{ + return GetName(); +} + +inline void CNewParticleEffect::SetDontRemove(bool bSet) +{ + m_bDontRemove = bSet; +} + +inline void CNewParticleEffect::SetDrawn(bool bDrawn) +{ + m_bDrawn = bDrawn; +} + +inline void CNewParticleEffect::SetFirstFrameFlag(bool bFirst) +{ + m_bIsFirstFrame = bFirst; +} + +inline void CNewParticleEffect::SetDynamicallyAllocated(bool bDynamic) +{ + m_bAllocated = bDynamic; +} + +inline void CNewParticleEffect::SetNeedsBBoxUpdate(bool bNeedsUpdate) +{ + m_bNeedsBBoxUpdate = bNeedsUpdate; +} + +inline void CNewParticleEffect::SetAutoUpdateBBox(bool bNeedsUpdate) +{ + m_bAutoUpdateBBox = bNeedsUpdate; +} + +inline void CNewParticleEffect::SetRemoveFlag(void) +{ + m_bRemove = true; +} + +inline bool CNewParticleEffect::GetRemoveFlag(void) +{ + return m_bRemove; +} + +inline bool CNewParticleEffect::GetFirstFrameFlag(void) +{ + return m_bIsFirstFrame; +} + +inline bool CNewParticleEffect::GetNeedsBBoxUpdate(void) +{ + return m_bNeedsBBoxUpdate; +} + +inline bool CNewParticleEffect::GetAutoUpdateBBox(void) +{ + return m_bAutoUpdateBBox; +} + +inline bool CNewParticleEffect::ShouldPerformCullCheck() const +{ + return m_bShouldPerformCullCheck; +} + +inline void CNewParticleEffect::MarkShouldPerformCullCheck(bool bEnable) +{ + m_bShouldPerformCullCheck = bEnable; +} + +inline CSmartPtr CNewParticleEffect::Create(CBaseEntity* pOwner, const char* pParticleSystemName, const char* pDebugName) +{ + CNewParticleEffect* pRet = new CNewParticleEffect(pOwner, pParticleSystemName); + pRet->m_pDebugName = pDebugName; + pRet->SetDynamicallyAllocated(true); + return pRet; +} + +inline CSmartPtr CNewParticleEffect::Create(CBaseEntity* pOwner, CParticleSystemDefinition* pDef, const char* pDebugName) +{ + CNewParticleEffect* pRet = new CNewParticleEffect(pOwner, pDef); + pRet->m_pDebugName = pDebugName; + pRet->SetDynamicallyAllocated(true); + return pRet; +} + +typedef CUtlReference HPARTICLEFFECT; + + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/particles_simple.h b/SpyCustom/sdk/particles_simple.h new file mode 100644 index 0000000..71ea268 --- /dev/null +++ b/SpyCustom/sdk/particles_simple.h @@ -0,0 +1,206 @@ +#ifndef PARTICLES_SIMPLE_H +#define PARTICLES_SIMPLE_H +#ifdef _WIN32 +#pragma once +#endif + +#include "particlemgr.h" +#include "ParticleSphereRenderer.h" +#include "smartptr.h" + + +class CParticleEffect : public IParticleEffect +{ +public: + DECLARE_CLASS_NOBASE(CParticleEffect); + + friend class CRefCountAccessor; + + void SetSortOrigin(const Vector& vSortOrigin); + + PMaterialHandle GetPMaterial(const char* name); + + Particle* AddParticle(unsigned int particleSize, PMaterialHandle material, const Vector& origin); + + CParticleEffectBinding& GetBinding() { return m_ParticleEffect; } + + const char* GetEffectName(); + + void AddFlags(int iFlags) { m_Flags |= iFlags; } + void RemoveFlags(int iFlags) { m_Flags &= ~iFlags; } + + void SetDontRemove(bool bSet) + { + if (bSet) + AddFlags(FLAG_DONT_REMOVE); + else + RemoveFlags(FLAG_DONT_REMOVE); + } + +public: + + virtual void SetParticleCullRadius(float radius); + virtual void NotifyRemove(void); + virtual const Vector& GetSortOrigin(); + virtual void NotifyDestroyParticle(Particle* pParticle); + virtual void Update(float flTimeDelta); + + void SetDynamicallyAllocated(bool bDynamic = true); + + virtual bool ShouldSimulate() const { return m_bSimulate; } + virtual void SetShouldSimulate(bool bSim) { m_bSimulate = bSim; } + + int AllocateToolParticleEffectId(); + int GetToolParticleEffectId() const; +protected: + CParticleEffect(const char* pDebugName); + virtual ~CParticleEffect(); + + int IsReleased(); + + enum + { + FLAG_ALLOCATED = (1 << 1), + FLAG_DONT_REMOVE = (1 << 2), + }; + + char const* m_pDebugName; + + CParticleEffectBinding m_ParticleEffect; + Vector m_vSortOrigin; + + int m_Flags; + + bool m_bSimulate; + int m_nToolParticleEffectId; + +private: + void AddRef(); + void Release(); + + int m_RefCount; + CParticleEffect(const CParticleEffect&); +}; + +inline int CParticleEffect::GetToolParticleEffectId() const +{ + return m_nToolParticleEffectId; +} + +inline int CParticleEffect::AllocateToolParticleEffectId() +{ + m_nToolParticleEffectId = ParticleMgr()->AllocateToolParticleEffectId(); + return m_nToolParticleEffectId; +} + + +enum SimpleParticleFlag_t +{ + SIMPLE_PARTICLE_FLAG_WINDBLOWN = 0x1, + SIMPLE_PARTICLE_FLAG_NO_VEL_DECAY = 0x2 +}; + +class SimpleParticle : public Particle +{ +public: + SimpleParticle() : m_iFlags(0) {} + + Vector m_vecVelocity; + float m_flRoll; + float m_flDieTime; + float m_flLifetime; + unsigned char m_uchColor[3]; + unsigned char m_uchStartAlpha; + unsigned char m_uchEndAlpha; + unsigned char m_uchStartSize; + unsigned char m_uchEndSize; + unsigned char m_iFlags; + float m_flRollDelta; +}; + + + +class CSimpleEmitter : public CParticleEffect +{ +public: + + DECLARE_CLASS(CSimpleEmitter, CParticleEffect); + + static CSmartPtr Create(const char* pDebugName); + + virtual void SimulateParticles(CParticleSimulateIterator* pIterator); + virtual void RenderParticles(CParticleRenderIterator* pIterator); + + void SetNearClip(float nearClipMin, float nearClipMax); + + void SetDrawBeforeViewModel(bool state = true); + + SimpleParticle* AddSimpleParticle(PMaterialHandle hMaterial, const Vector& vOrigin, float flDieTime = 3, unsigned char uchSize = 10); + + void SetShouldDrawForSplitScreenUser(int nSlot); + +protected: + CSimpleEmitter(const char* pDebugName = NULL); + virtual ~CSimpleEmitter(); + + virtual float UpdateAlpha(const SimpleParticle* pParticle); + virtual float UpdateScale(const SimpleParticle* pParticle); + virtual float UpdateRoll(SimpleParticle* pParticle, float timeDelta); + virtual void UpdateVelocity(SimpleParticle* pParticle, float timeDelta); + virtual Vector UpdateColor(const SimpleParticle* pParticle); + + float m_flNearClipMin; + float m_flNearClipMax; + + int m_nSplitScreenPlayerSlot; + + +private: + CSimpleEmitter(const CSimpleEmitter&); +}; + +class CEmberEffect : public CSimpleEmitter +{ +public: + CEmberEffect(const char* pDebugName); + static CSmartPtr Create(const char* pDebugName); + + virtual void UpdateVelocity(SimpleParticle* pParticle, float timeDelta); + virtual Vector UpdateColor(const SimpleParticle* pParticle); + +private: + CEmberEffect(const CEmberEffect&); +}; + + +class CFireSmokeEffect : public CSimpleEmitter +{ +public: + CFireSmokeEffect(const char* pDebugName); + static CSmartPtr Create(const char* pDebugName); + + virtual void UpdateVelocity(SimpleParticle* pParticle, float timeDelta); + virtual float UpdateAlpha(const SimpleParticle* pParticle); + +protected: + VPlane m_planeClip; + +private: + CFireSmokeEffect(const CFireSmokeEffect&); +}; + + +class CFireParticle : public CSimpleEmitter +{ +public: + CFireParticle(const char* pDebugName); + static CSmartPtr Create(const char* pDebugName); + + virtual Vector UpdateColor(const SimpleParticle* pParticle); + +private: + CFireParticle(const CFireParticle&); +}; + + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/platform.h b/SpyCustom/sdk/platform.h new file mode 100644 index 0000000..5c4f3ed --- /dev/null +++ b/SpyCustom/sdk/platform.h @@ -0,0 +1,1280 @@ +#ifndef PLATFORM_H +#define PLATFORM_H + +#if defined( _X360 ) +#define NO_STEAM +#define NO_VOICE +#define _XBOX +#include +#include +#include +#include +#include +#include +#include +#undef _XBOX +#endif + +#include "wchartypes.h" +#include "basetypes.h" +#include "valve_off.h" + +#ifdef _DEBUG +#if !defined( PLAT_COMPILE_TIME_ASSERT ) +#define PLAT_COMPILE_TIME_ASSERT( pred ) switch(0){case 0:case pred:;} +#endif +#else +#if !defined( PLAT_COMPILE_TIME_ASSERT ) +#define PLAT_COMPILE_TIME_ASSERT( pred ) +#endif +#endif + +#ifdef _WIN32 +#pragma once +#endif + +#define NEW_SOFTWARE_LIGHTING + +#ifdef POSIX +#include +#include +#include +#include +#endif + +#include +#include + + +#include + +#include "valve_minmax_on.h" + +#ifdef _RETAIL +#define IsRetail() true +#else +#define IsRetail() false +#endif + +#ifdef _DEBUG +#define IsRelease() false +#define IsDebug() true +#else +#define IsRelease() true +#define IsDebug() false +#endif + +#define IsXbox() false + +#ifdef _WIN32 +#define IsLinux() false +#define IsOSX() false +#define IsPosix() false +#define PLATFORM_WINDOWS 1 +#ifndef _X360 +#define IsWindows() true +#define IsPC() true +#define IsConsole() false +#define IsX360() false +#define IsPS3() false +#define IS_WINDOWS_PC +#define PLATFORM_WINDOWS_PC 1 +#ifdef _WIN64 +#define IsPlatformWindowsPC64() true +#define IsPlatformWindowsPC32() false +#define PLATFORM_WINDOWS_PC64 1 +#else +#define IsPlatformWindowsPC64() false +#define IsPlatformWindowsPC32() true +#define PLATFORM_WINDOWS_PC32 1 +#endif +#else +#define PLATFORM_X360 1 +#ifndef _CONSOLE +#define _CONSOLE +#endif +#define IsWindows() false +#define IsPC() false +#define IsConsole() true +#define IsX360() true +#define IsPS3() false +#endif +#if defined( DX_TO_GL_ABSTRACTION ) +#define IsPlatformOpenGL() true +#else +#define IsPlatformOpenGL() false +#endif +#elif defined(POSIX) +#define IsPC() true +#define IsWindows() false +#define IsConsole() false +#define IsX360() false +#define IsPS3() false +#if defined( LINUX ) +#define IsLinux() true +#else +#define IsLinux() false +#endif + +#if defined( OSX ) +#define IsOSX() true +#else +#define IsOSX() false +#endif + +#define IsPosix() true +#define IsPlatformOpenGL() true +#else +#error +#endif + +typedef unsigned char uint8; +typedef signed char int8; + +#if defined(__x86_64__) || defined(_WIN64) +#define X64BITS +#endif + +#if defined( _WIN32 ) + +typedef __int16 int16; +typedef unsigned __int16 uint16; +typedef __int32 int32; +typedef unsigned __int32 uint32; +typedef __int64 int64; +typedef unsigned __int64 uint64; + +#ifdef PLATFORM_64BITS +typedef __int64 intp; +typedef unsigned __int64 uintp; +#else +typedef __int32 intp; +typedef unsigned __int32 uintp; +#endif + +#if defined( _X360 ) +#ifdef __m128 +#undef __m128 +#endif +#define __m128 __vector4 +#endif + +#define OVERRIDE override + +#else + +typedef short int16; +typedef unsigned short uint16; +typedef int int32; +typedef unsigned int uint32; +typedef long long int64; +typedef unsigned long long uint64; +#ifdef X64BITS +typedef long long intp; +typedef unsigned long long uintp; +#else +typedef int intp; +typedef unsigned int uintp; +#endif +typedef void* HWND; + +#undef OVERRIDE +#if defined(__clang__) +#define OVERRIDE override +#pragma GCC diagnostic ignored "-Wc++11-extensions" +#else +#define OVERRIDE +#endif + +#endif + +typedef uint32 RTime32; + +typedef float float32; +typedef double float64; + +typedef unsigned int uint; + +#ifdef _MSC_VER +#pragma once +#if _MSC_FULL_VER > 160000000 +#if _MSC_FULL_VER < 160040219 +#error You must install VS 2010 SP1 +#endif +#else +#if _MSC_FULL_VER < 140050727 +#error You must install VS 2005 SP1 +#endif +#endif +#endif + +#ifdef _MSC_VER +#define SINGLE_INHERITANCE __single_inheritance +#define MULTIPLE_INHERITANCE __multiple_inheritance +#else +#define SINGLE_INHERITANCE +#define MULTIPLE_INHERITANCE +#endif + +#ifdef _MSC_VER +#define NO_VTABLE __declspec( novtable ) +#else +#define NO_VTABLE +#endif + +#ifdef _MSC_VER +#define NORETURN __declspec( noreturn ) +#else +#define NORETURN +#endif + +#ifndef _X360 +#define abstract_class class +#else +#define abstract_class class NO_VTABLE +#endif + + +#define VALVE_RAND_MAX 0x7fff + + + +#if defined(_WIN32) && !defined(WINDED) + +#if defined(_M_IX86) +#define __i386__ 1 +#endif + +#elif POSIX +#if defined( OSX ) && defined( CARBON_WORKAROUND ) +#define DWORD unsigned int +#else +typedef unsigned int DWORD; +#endif +typedef unsigned short WORD; +typedef void* HINSTANCE; +#define _MAX_PATH PATH_MAX +#define __cdecl +#define __stdcall +#define __declspec + +#endif + + +#ifndef MAX_PATH +#define MAX_PATH 260 +#endif + +#ifdef _WIN32 +#define MAX_UNICODE_PATH 32767 +#else +#define MAX_UNICODE_PATH MAX_PATH +#endif + +#define MAX_UNICODE_PATH_IN_UTF8 MAX_UNICODE_PATH*4 + +#ifdef GNUC +#undef offsetof +#define offsetof(s,m) (size_t)&(((s *)0)->m) +#else +#undef offsetof +#define offsetof(s,m) (size_t)&(((s *)0)->m) +#endif + + +#define ALIGN_VALUE( val, alignment ) ( ( val + alignment - 1 ) & ~( alignment - 1 ) ) + +#if defined( _WIN32 ) && !defined( _X360 ) +#define DebuggerBreak() __debugbreak() +#elif defined( _X360 ) +#define DebuggerBreak() DebugBreak() +#else +#ifdef OSX +#define DebuggerBreak() if ( Plat_IsInDebugSession() ) { __asm ( "int $3" ); } else { raise(SIGTRAP); } +#else +#define DebuggerBreak() raise(SIGTRAP) +#endif +#endif +#define DebuggerBreakIfDebugging() if ( !Plat_IsInDebugSession() ) ; else DebuggerBreak() + +#ifndef EXPORT +#ifdef _WIN32 +#define EXPORT _declspec( dllexport ) +#else +#define EXPORT +#endif +#endif + +#if defined __i386__ && !defined __linux__ +#define id386 1 +#else +#define id386 0 +#endif + +#ifdef _WIN32 +#define DECL_ALIGN(x) __declspec(align(x)) + +#elif GNUC +#define DECL_ALIGN(x) __attribute__((aligned(x))) +#else +#define DECL_ALIGN(x) +#endif + +#ifdef _MSC_VER +#define ALIGN4 DECL_ALIGN(4) +#define ALIGN8 DECL_ALIGN(8) +#define ALIGN16 DECL_ALIGN(16) +#define ALIGN32 DECL_ALIGN(32) +#define ALIGN128 DECL_ALIGN(128) + +#define ALIGN4_POST +#define ALIGN8_POST +#define ALIGN16_POST +#define ALIGN32_POST +#define ALIGN128_POST +#elif defined( GNUC ) +#define ALIGN4 +#define ALIGN8 +#define ALIGN16 +#define ALIGN32 +#define ALIGN128 + +#define ALIGN4_POST DECL_ALIGN(4) +#define ALIGN8_POST DECL_ALIGN(8) +#define ALIGN16_POST DECL_ALIGN(16) +#define ALIGN32_POST DECL_ALIGN(32) +#define ALIGN128_POST DECL_ALIGN(128) +#else +#error +#endif + +#ifdef __GNUC__ +#define COMPILE_TIME_ASSERT( pred ) typedef int UNIQUE_ID[ (pred) ? 1 : -1 ] +#else +#if _MSC_VER >= 1600 +#define COMPILE_TIME_ASSERT( pred ) static_assert( pred, "Compile time assert constraint is not true: " #pred ) +#else +#define COMPILE_TIME_ASSERT( pred ) typedef char compile_time_assert_type[(pred) ? 1 : -1]; +#endif +#endif +#define ASSERT_INVARIANT( pred ) COMPILE_TIME_ASSERT( pred ) + +#if defined( PLATFORM_WINDOWS_PC ) + void Plat_MessageBox(const char* pTitle, const tchar * pMessage); +#else +#define Plat_MessageBox( t, m ) ((void)0) +#endif +#define DebuggerBreakIfDebugging() if ( !Plat_IsInDebugSession() ) ; else DebuggerBreak() +void Plat_GetModuleFilename(char* pOut, int nMaxBytes); +void Plat_ExitProcess(int nCode); + +void Plat_ExitProcessWithError(int nCode, bool bGenerateMinidump = false); +#if defined( PLATFORM_X360 ) || defined( _PS3 ) +#ifndef _GAMECONSOLE +#define _GAMECONSOLE +#endif +#define IsPC() 0 +#define IsGameConsole() 1 +#else +#define IsPC() 1 +#define IsGameConsole() 0 +#endif + + +inline int64 CastPtrToInt64(const void* p) +{ + return (int64)((uintp)p); +} + +#include "annotations.h" + +#define INT_TO_POINTER( i ) (void *)( ( i ) + (char *)NULL ) +#define POINTER_TO_INT( p ) ( (int)(uintp)( p ) ) + + +#if defined( GNUC ) +#define stackalloc( _size ) alloca( ALIGN_VALUE( _size, 16 ) ) +#ifdef _LINUX +#define mallocsize( _p ) ( malloc_usable_size( _p ) ) +#elif defined(OSX) +#define mallocsize( _p ) ( malloc_size( _p ) ) +#else +#error +#endif +#elif defined ( _WIN32 ) +#define stackalloc( _size ) _alloca( ALIGN_VALUE( _size, 16 ) ) +#define mallocsize( _p ) ( _msize( _p ) ) +#endif + +#define stackfree( _p ) 0 + +#ifdef POSIX +#define CONSTRUCT_EARLY __attribute__((init_priority(101))) +#else +#define CONSTRUCT_EARLY +#endif + +#if defined(_MSC_VER) +#define SELECTANY __declspec(selectany) +#define RESTRICT __restrict +#define RESTRICT_FUNC __declspec(restrict) +#define FMTFUNCTION( a, b ) +#elif defined(GNUC) +#define SELECTANY __attribute__((weak)) +#if defined(LINUX) && !defined(DEDICATED) +#define RESTRICT +#else +#define RESTRICT __restrict +#endif +#define RESTRICT_FUNC +#define FMTFUNCTION( fmtargnumber, firstvarargnumber ) __attribute__ (( format( __printf__, fmtargnumber, firstvarargnumber ))) +#else +#define SELECTANY static +#define RESTRICT +#define RESTRICT_FUNC +#define FMTFUNCTION( a, b ) +#endif + +#if defined( _WIN32 ) + +#define DLL_EXPORT extern "C" __declspec( dllexport ) +#define DLL_IMPORT extern "C" __declspec( dllimport ) + +#define DLL_CLASS_EXPORT __declspec( dllexport ) +#define DLL_CLASS_IMPORT __declspec( dllimport ) + +#define DLL_GLOBAL_EXPORT extern __declspec( dllexport ) +#define DLL_GLOBAL_IMPORT extern __declspec( dllimport ) + +#define DLL_LOCAL + +#elif defined GNUC +#define DLL_EXPORT extern "C" __attribute__ ((visibility("default"))) +#define DLL_IMPORT extern "C" + +#define DLL_CLASS_EXPORT __attribute__ ((visibility("default"))) +#define DLL_CLASS_IMPORT + +#define DLL_GLOBAL_EXPORT extern __attribute ((visibility("default"))) +#define DLL_GLOBAL_IMPORT extern + +#define DLL_LOCAL __attribute__ ((visibility("hidden"))) + +#else +#error "Unsupported Platform." +#endif + +#if defined( _WIN32 ) && !defined( _X360 ) +#define STDCALL __stdcall +#define FASTCALL __fastcall +#define FORCEINLINE __forceinline +#define FORCEINLINE_TEMPLATE __forceinline +#elif defined( _X360 ) +#define STDCALL __stdcall +#ifdef FORCEINLINE +#undef FORCEINLINE +#endif +#define FORCEINLINE __forceinline +#define FORCEINLINE_TEMPLATE __forceinline +#else +#define STDCALL +#define FASTCALL +#ifdef _LINUX_DEBUGGABLE +#define FORCEINLINE +#else +#define FORCEINLINE inline __attribute__ ((always_inline)) +#endif +#define FORCEINLINE_TEMPLATE inline +#endif + +#define DONT_INLINE(a) (((int)(a)+1)?(a):(a)) + +#ifdef _MSC_VER +#define HINT(THE_HINT) __assume((THE_HINT)) +#else +#define HINT(THE_HINT) 0 +#endif + +#define UNREACHABLE() { Assert(0); HINT(0); } + +#define NO_DEFAULT default: UNREACHABLE(); + + +#ifdef _WIN32 + +#pragma warning(disable : 4514) +#pragma warning(disable : 4100) +#pragma warning(disable : 4127) +#pragma warning(disable : 4512) +#pragma warning(disable : 4611) +#pragma warning(disable : 4710) +#pragma warning(disable : 4702) +#pragma warning(disable : 4505) +#pragma warning(disable : 4239) +#pragma warning(disable : 4097) +#pragma warning(disable : 4324) +#pragma warning(disable : 4244) +#pragma warning(disable : 4305) +#pragma warning(disable : 4786) +#pragma warning(disable : 4250) +#pragma warning(disable : 4201) +#pragma warning(disable : 4481) +#pragma warning(disable : 4748) + +#if _MSC_VER >= 1300 +#pragma warning(disable : 4511) +#pragma warning(disable : 4121) +#pragma warning(disable : 4530) +#endif + +#if _MSC_VER >= 1400 +#pragma warning(disable : 4996) +#endif + + +#endif + +#if defined( LINUX ) && ((__GNUC__ * 100) + __GNUC_MINOR__) >= 406 +#define GCC_DIAG_STR(s) #s +#define GCC_DIAG_JOINSTR(x,y) GCC_DIAG_STR(x ## y) +#define GCC_DIAG_DO_PRAGMA(x) _Pragma (#x) +#define GCC_DIAG_PRAGMA(x) GCC_DIAG_DO_PRAGMA(GCC diagnostic x) + +#define GCC_DIAG_PUSH_OFF(x) GCC_DIAG_PRAGMA(push) GCC_DIAG_PRAGMA(ignored GCC_DIAG_JOINSTR(-W,x)) +#define GCC_DIAG_POP() GCC_DIAG_PRAGMA(pop) +#else +#define GCC_DIAG_PUSH_OFF(x) +#define GCC_DIAG_POP() +#endif + +#ifdef LINUX +#pragma GCC diagnostic ignored "-Wconversion-null" +#pragma GCC diagnostic ignored "-Wpointer-arith" +#pragma GCC diagnostic ignored "-Wswitch" +#endif + +#ifdef OSX +#pragma GCC diagnostic ignored "-Wconversion-null" +#pragma GCC diagnostic ignored "-Wnull-arithmetic" +#pragma GCC diagnostic ignored "-Wswitch-enum" +#pragma GCC diagnostic ignored "-Wswitch" +#endif + + +#if !defined( _WIN64 ) +#pragma warning( disable : 4267 ) +#pragma warning( disable : 4311 ) +#pragma warning( disable : 4312 ) +#endif + + +#ifdef POSIX +#define _stricmp stricmp +#define strcmpi stricmp +#define stricmp strcasecmp +#define _vsnprintf vsnprintf +#define _alloca alloca +#ifdef _snprintf +#undef _snprintf +#endif +#define _snprintf snprintf +#define GetProcAddress dlsym +#define _chdir chdir +#define _strnicmp strnicmp +#define strnicmp strncasecmp +#define _getcwd getcwd +#define _snwprintf swprintf +#define swprintf_s swprintf +#define wcsicmp _wcsicmp +#define _wcsicmp wcscmp +#define _finite finite +#define _tempnam tempnam +#define _unlink unlink +#define _access access +#define _mkdir(dir) mkdir( dir, S_IRWXU | S_IRWXG | S_IRWXO ) +#define _wtoi(arg) wcstol(arg, NULL, 10) +#define _wtoi64(arg) wcstoll(arg, NULL, 10) + +typedef uint32 HMODULE; +typedef void* HANDLE; +#endif + +#ifndef _X360 + +static FORCEINLINE float fsel(float fComparand, float fValGE, float fLT) +{ + return fComparand >= 0 ? fValGE : fLT; +} +static FORCEINLINE double fsel(double fComparand, double fValGE, double fLT) +{ + return fComparand >= 0 ? fValGE : fLT; +} + +#else + +#define fsel __fsel + +#endif + + +#if !defined( _X360 ) +#if defined( _MSC_VER ) + +#if defined( PLATFORM_WINDOWS_PC64 ) +inline void SetupFPUControlWord() +{ +} +#else +inline void SetupFPUControlWordForceExceptions() +{ + uint16 tmpCtrlW; + __asm + { + fnclex + fnstcw word ptr[tmpCtrlW] + and [tmpCtrlW], 0FCC0h + or [tmpCtrlW], 0230h + fldcw word ptr[tmpCtrlW] + } +} + +#ifdef CHECK_FLOAT_EXCEPTIONS + +inline void SetupFPUControlWord() +{ + SetupFPUControlWordForceExceptions(); +} + +#else + +inline void SetupFPUControlWord() +{ + uint16 tmpCtrlW; + __asm + { + fnstcw word ptr[tmpCtrlW] + and [tmpCtrlW], 0FCC0h + or [tmpCtrlW], 023Fh + fldcw word ptr[tmpCtrlW] + } +} + +#endif +#endif + +#else + +inline void SetupFPUControlWord() +{ + __volatile unsigned short int __cw; + __asm __volatile("fnstcw %0" : "=m" (__cw)); + __cw = __cw & 0x0FCC0; + __cw = __cw | 0x023F; + __asm __volatile("fldcw %0" : : "m" (__cw)); +} + +#endif + +#else + +#ifdef _DEBUG +FORCEINLINE bool IsFPUControlWordSet() +{ + float f = 0.996f; + union + { + double flResult; + int pResult[2]; + }; + flResult = __fctiw(f); + return (pResult[1] == 1); +} +#endif + +inline void SetupFPUControlWord() +{ + __emit(0xFF80010C); + + __vector4 a = { 0.0f, 0.0f, 0.0f, 0.0f }; + a; + __asm + { + mtvscr a; + } +} + +#endif + +template +inline T WordSwapC(T w) +{ + uint16 temp; + + temp = ((*((uint16*)&w) & 0xff00) >> 8); + temp |= ((*((uint16*)&w) & 0x00ff) << 8); + + return *((T*)&temp); +} + +template +inline T DWordSwapC(T dw) +{ + uint32 temp; + + temp = *((uint32*)&dw) >> 24; + temp |= ((*((uint32*)&dw) & 0x00FF0000) >> 8); + temp |= ((*((uint32*)&dw) & 0x0000FF00) << 8); + temp |= ((*((uint32*)&dw) & 0x000000FF) << 24); + + return *((T*)&temp); +} + +template +inline T QWordSwapC(T dw) +{ + PLAT_COMPILE_TIME_ASSERT(sizeof(dw) == sizeof(uint64)); + + uint64 temp; + + temp = *((uint64*)&dw) >> 56; + temp |= ((*((uint64*)&dw) & 0x00FF000000000000ull) >> 40); + temp |= ((*((uint64*)&dw) & 0x0000FF0000000000ull) >> 24); + temp |= ((*((uint64*)&dw) & 0x000000FF00000000ull) >> 8); + temp |= ((*((uint64*)&dw) & 0x00000000FF000000ull) << 8); + temp |= ((*((uint64*)&dw) & 0x0000000000FF0000ull) << 24); + temp |= ((*((uint64*)&dw) & 0x000000000000FF00ull) << 40); + temp |= ((*((uint64*)&dw) & 0x00000000000000FFull) << 56); + + return *((T*)&temp); +} + +#if defined( _X360 ) + +#define WordSwap WordSwap360Intr +#define DWordSwap DWordSwap360Intr + +template +inline T WordSwap360Intr(T w) +{ + T output; + __storeshortbytereverse(w, 0, &output); + return output; +} + +template +inline T DWordSwap360Intr(T dw) +{ + T output; + __storewordbytereverse(dw, 0, &output); + return output; +} + +#elif defined( _MSC_VER ) && !defined( PLATFORM_WINDOWS_PC64 ) + +#define WordSwap WordSwapAsm +#define DWordSwap DWordSwapAsm + +#pragma warning(push) +#pragma warning (disable:4035) + +template +inline T WordSwapAsm(T w) +{ + __asm + { + mov ax, w + xchg al, ah + } +} + +template +inline T DWordSwapAsm(T dw) +{ + __asm + { + mov eax, dw + bswap eax + } +} + +#pragma warning(pop) + +#else + +#define WordSwap WordSwapC +#define DWordSwap DWordSwapC + +#endif + +#define QWordSwap QWordSwapC + +#if defined(__i386__) && !defined(VALVE_LITTLE_ENDIAN) +#define VALVE_LITTLE_ENDIAN 1 +#endif + +#if defined( _SGI_SOURCE ) || defined( _X360 ) +#define VALVE_BIG_ENDIAN 1 +#endif + +#define SafeSwapFloat( pOut, pIn ) (*((uint*)pOut) = DWordSwap( *((uint*)pIn) )) + +#if defined(VALVE_LITTLE_ENDIAN) + +#define BigShort( val ) WordSwap( val ) +#define BigWord( val ) WordSwap( val ) +#define BigLong( val ) DWordSwap( val ) +#define BigDWord( val ) DWordSwap( val ) +#define LittleShort( val ) ( val ) +#define LittleWord( val ) ( val ) +#define LittleLong( val ) ( val ) +#define LittleDWord( val ) ( val ) +#define LittleQWord( val ) ( val ) +#define SwapShort( val ) BigShort( val ) +#define SwapWord( val ) BigWord( val ) +#define SwapLong( val ) BigLong( val ) +#define SwapDWord( val ) BigDWord( val ) + +#define BigFloat( pOut, pIn ) SafeSwapFloat( pOut, pIn ) +#define LittleFloat( pOut, pIn ) ( *pOut = *pIn ) +#define SwapFloat( pOut, pIn ) BigFloat( pOut, pIn ) + +#elif defined(VALVE_BIG_ENDIAN) + +#define BigShort( val ) ( val ) +#define BigWord( val ) ( val ) +#define BigLong( val ) ( val ) +#define BigDWord( val ) ( val ) +#define LittleShort( val ) WordSwap( val ) +#define LittleWord( val ) WordSwap( val ) +#define LittleLong( val ) DWordSwap( val ) +#define LittleDWord( val ) DWordSwap( val ) +#define LittleQWord( val ) QWordSwap( val ) +#define SwapShort( val ) LittleShort( val ) +#define SwapWord( val ) LittleWord( val ) +#define SwapLong( val ) LittleLong( val ) +#define SwapDWord( val ) LittleDWord( val ) + +#define BigFloat( pOut, pIn ) ( *pOut = *pIn ) +#define LittleFloat( pOut, pIn ) SafeSwapFloat( pOut, pIn ) +#define SwapFloat( pOut, pIn ) LittleFloat( pOut, pIn ) + +#else + +inline short BigShort(short val) { int test = 1; return (*(char*)&test == 1) ? WordSwap(val) : val; } +inline uint16 BigWord(uint16 val) { int test = 1; return (*(char*)&test == 1) ? WordSwap(val) : val; } +inline long BigLong(long val) { int test = 1; return (*(char*)&test == 1) ? DWordSwap(val) : val; } +inline uint32 BigDWord(uint32 val) { int test = 1; return (*(char*)&test == 1) ? DWordSwap(val) : val; } +inline short LittleShort(short val) { int test = 1; return (*(char*)&test == 1) ? val : WordSwap(val); } +inline uint16 LittleWord(uint16 val) { int test = 1; return (*(char*)&test == 1) ? val : WordSwap(val); } +inline long LittleLong(long val) { int test = 1; return (*(char*)&test == 1) ? val : DWordSwap(val); } +inline uint32 LittleDWord(uint32 val) { int test = 1; return (*(char*)&test == 1) ? val : DWordSwap(val); } +inline uint64 LittleQWord(uint64 val) { int test = 1; return (*(char*)&test == 1) ? val : QWordSwap(val); } +inline short SwapShort(short val) { return WordSwap(val); } +inline uint16 SwapWord(uint16 val) { return WordSwap(val); } +inline long SwapLong(long val) { return DWordSwap(val); } +inline uint32 SwapDWord(uint32 val) { return DWordSwap(val); } + +inline void BigFloat(float* pOut, const float* pIn) { int test = 1; (*(char*)&test == 1) ? SafeSwapFloat(pOut, pIn) : (*pOut = *pIn); } +inline void LittleFloat(float* pOut, const float* pIn) { int test = 1; (*(char*)&test == 1) ? (*pOut = *pIn) : SafeSwapFloat(pOut, pIn); } +inline void SwapFloat(float* pOut, const float* pIn) { SafeSwapFloat(pOut, pIn); } + +#endif + +#if _X360 +FORCEINLINE unsigned long LoadLittleDWord(const unsigned long* base, unsigned int dwordIndex) +{ + return __loadwordbytereverse(dwordIndex << 2, base); +} + +FORCEINLINE void StoreLittleDWord(unsigned long* base, unsigned int dwordIndex, unsigned long dword) +{ + __storewordbytereverse(dword, dwordIndex << 2, base); +} +#else +FORCEINLINE unsigned long LoadLittleDWord(const unsigned long* base, unsigned int dwordIndex) +{ + return LittleDWord(base[dwordIndex]); +} + +FORCEINLINE void StoreLittleDWord(unsigned long* base, unsigned int dwordIndex, unsigned long dword) +{ + base[dwordIndex] = LittleDWord(dword); +} +#endif + + +#ifndef STATIC_TIER0 + +#ifdef TIER0_DLL_EXPORT +#define PLATFORM_INTERFACE DLL_EXPORT +#define PLATFORM_OVERLOAD DLL_GLOBAL_EXPORT +#define PLATFORM_CLASS DLL_CLASS_EXPORT +#else +#define PLATFORM_INTERFACE DLL_IMPORT +#define PLATFORM_OVERLOAD DLL_GLOBAL_IMPORT +#define PLATFORM_CLASS DLL_CLASS_IMPORT +#endif + +#else + +#define PLATFORM_INTERFACE extern +#define PLATFORM_OVERLOAD +#define PLATFORM_CLASS + +#endif + + +PLATFORM_INTERFACE void Plat_SetBenchmarkMode(bool bBenchmarkMode); +PLATFORM_INTERFACE bool Plat_IsInBenchmarkMode(); + + +PLATFORM_INTERFACE double Plat_FloatTime(); +PLATFORM_INTERFACE unsigned int Plat_MSTime(); +PLATFORM_INTERFACE char* Plat_asctime(const struct tm* tm, char* buf); +PLATFORM_INTERFACE char* Plat_ctime(const time_t* timep, char* buf, size_t bufsize); +PLATFORM_INTERFACE struct tm* Plat_gmtime(const time_t* timep, struct tm* result); +PLATFORM_INTERFACE time_t Plat_timegm(struct tm* timeptr); +PLATFORM_INTERFACE struct tm* Plat_localtime(const time_t* timep, struct tm* result); + +#if defined( _WIN32 ) && defined( _MSC_VER ) && ( _MSC_VER >= 1400 ) +extern "C" unsigned __int64 __rdtsc(); +#pragma intrinsic(__rdtsc) +#endif + +inline uint64 Plat_Rdtsc() +{ +#if defined( _X360 ) + return (uint64)__mftb32(); +#elif defined( _WIN64 ) + return (uint64)__rdtsc(); +#elif defined( _WIN32 ) +#if defined( _MSC_VER ) && ( _MSC_VER >= 1400 ) + return (uint64)__rdtsc(); +#else + __asm rdtsc; + __asm ret; +#endif +#elif defined( __i386__ ) + uint64 val; + __asm__ __volatile__("rdtsc" : "=A" (val)); + return val; +#elif defined( __x86_64__ ) + uint32 lo, hi; + __asm__ __volatile__("rdtsc" : "=a" (lo), "=d" (hi)); + return (((uint64)hi) << 32) | lo; +#else +#error +#endif +} + +#define Sys_FloatTime Plat_FloatTime + +#define DISALLOW_OPERATOR_EQUAL( _classname ) \ + private: \ + _classname &operator=( const _classname & ); \ + public: + +#define IMPLEMENT_OPERATOR_EQUAL( _classname ) \ + public: \ + _classname &operator=( const _classname &src ) \ + { \ + memcpy( this, &src, sizeof(_classname) ); \ + return *this; \ + } + +struct CPUInformation +{ + int m_Size; + + bool m_bRDTSC : 1, + m_bCMOV : 1, + m_bFCMOV : 1, + m_bSSE : 1, + m_bSSE2 : 1, + m_b3DNow : 1, + m_bMMX : 1, + m_bHT : 1; + + uint8 m_nLogicalProcessors; + uint8 m_nPhysicalProcessors; + + bool m_bSSE3 : 1, + m_bSSSE3 : 1, + m_bSSE4a : 1, + m_bSSE41 : 1, + m_bSSE42 : 1; + + int64 m_Speed; + + tchar* m_szProcessorID; + + CPUInformation() : m_Size(0) {} +}; + +PLATFORM_INTERFACE const CPUInformation* GetCPUInformation(); + +PLATFORM_INTERFACE float GetCPUUsage(); + +PLATFORM_INTERFACE void GetCurrentDate(int* pDay, int* pMonth, int* pYear); + +PLATFORM_INTERFACE void InitPME(); +PLATFORM_INTERFACE void ShutdownPME(); + +PLATFORM_INTERFACE void Plat_SetHardwareDataBreakpoint(const void* pAddress, int nWatchBytes, bool bBreakOnRead); + +PLATFORM_INTERFACE void Plat_ApplyHardwareDataBreakpointsToNewThread(unsigned long dwThreadID); + +PLATFORM_INTERFACE const tchar* Plat_GetCommandLine(); +#ifndef _WIN32 +PLATFORM_INTERFACE void Plat_SetCommandLine(const char* cmdLine); +#endif +PLATFORM_INTERFACE const char* Plat_GetCommandLineA(); + +PLATFORM_INTERFACE bool Plat_VerifyHardwareKeyDriver(); + +PLATFORM_INTERFACE bool Plat_VerifyHardwareKey(); + +PLATFORM_INTERFACE bool Plat_VerifyHardwareKeyPrompt(); + +PLATFORM_INTERFACE bool Plat_FastVerifyHardwareKey(); + +PLATFORM_INTERFACE void* Plat_SimpleLog(const tchar* file, int line); + +#if _X360 +#define Plat_FastMemset XMemSet +#define Plat_FastMemcpy XMemCpy +#else +#define Plat_FastMemset memset +#define Plat_FastMemcpy memcpy +#endif + +#if defined(_WIN32) || defined(LINUX) || defined(OSX) +PLATFORM_INTERFACE bool Plat_IsInDebugSession(bool bForceRecheck = false); +PLATFORM_INTERFACE void Plat_DebugString(const char*); +#else +inline bool Plat_IsInDebugSession(bool bForceRecheck = false) { return false; } +#define Plat_DebugString(s) ((void)0) +#endif + +PLATFORM_INTERFACE bool Is64BitOS(); + + +#define XBOX_DVD_SECTORSIZE 2048 +#define XBOX_DVD_ECC_SIZE 32768 +#define XBOX_HDD_SECTORSIZE 512 + +#define WM_XREMOTECOMMAND (WM_USER + 100) +#define WM_XCONTROLLER_KEY (WM_USER + 101) +#define WM_SYS_UI (WM_USER + 102) +#define WM_SYS_SIGNINCHANGED (WM_USER + 103) +#define WM_SYS_STORAGEDEVICESCHANGED (WM_USER + 104) +#define WM_SYS_PROFILESETTINGCHANGED (WM_USER + 105) +#define WM_SYS_MUTELISTCHANGED (WM_USER + 106) +#define WM_SYS_INPUTDEVICESCHANGED (WM_USER + 107) +#define WM_SYS_INPUTDEVICECONFIGCHANGED (WM_USER + 108) +#define WM_LIVE_CONNECTIONCHANGED (WM_USER + 109) +#define WM_LIVE_INVITE_ACCEPTED (WM_USER + 110) +#define WM_LIVE_LINK_STATE_CHANGED (WM_USER + 111) +#define WM_LIVE_CONTENT_INSTALLED (WM_USER + 112) +#define WM_LIVE_MEMBERSHIP_PURCHASED (WM_USER + 113) +#define WM_LIVE_VOICECHAT_AWAY (WM_USER + 114) +#define WM_LIVE_PRESENCE_CHANGED (WM_USER + 115) +#define WM_FRIENDS_PRESENCE_CHANGED (WM_USER + 116) +#define WM_FRIENDS_FRIEND_ADDED (WM_USER + 117) +#define WM_FRIENDS_FRIEND_REMOVED (WM_USER + 118) +#define WM_CUSTOM_GAMEBANNERPRESSED (WM_USER + 119) +#define WM_CUSTOM_ACTIONPRESSED (WM_USER + 120) +#define WM_XMP_STATECHANGED (WM_USER + 121) +#define WM_XMP_PLAYBACKBEHAVIORCHANGED (WM_USER + 122) +#define WM_XMP_PLAYBACKCONTROLLERCHANGED (WM_USER + 123) + +inline const char* GetPlatformExt(void) +{ + return IsX360() ? ".360" : ""; +} + +#define XBOX_PROCESSOR_0 ( 1<<0 ) +#define XBOX_PROCESSOR_1 ( 1<<1 ) +#define XBOX_PROCESSOR_2 ( 1<<2 ) +#define XBOX_PROCESSOR_3 ( 1<<3 ) +#define XBOX_PROCESSOR_4 ( 1<<4 ) +#define XBOX_PROCESSOR_5 ( 1<<5 ) + +#define XBOX_CORE_0_HWTHREAD_0 XBOX_PROCESSOR_0 +#define XBOX_CORE_0_HWTHREAD_1 XBOX_PROCESSOR_1 +#define XBOX_CORE_1_HWTHREAD_0 XBOX_PROCESSOR_2 +#define XBOX_CORE_1_HWTHREAD_1 XBOX_PROCESSOR_3 +#define XBOX_CORE_2_HWTHREAD_0 XBOX_PROCESSOR_4 +#define XBOX_CORE_2_HWTHREAD_1 XBOX_PROCESSOR_5 + +#include "fasttimer.h" + +#if defined( _X360 ) +#include "xbox/xbox_core.h" +#endif + +template +inline T* Construct(T* pMemory) +{ + return ::new(pMemory) T; +} + +template +inline T* Construct(T* pMemory, ARG1 a1) +{ + return ::new(pMemory) T(a1); +} + +template +inline T* Construct(T* pMemory, ARG1 a1, ARG2 a2) +{ + return ::new(pMemory) T(a1, a2); +} + +template +inline T* Construct(T* pMemory, ARG1 a1, ARG2 a2, ARG3 a3) +{ + return ::new(pMemory) T(a1, a2, a3); +} + +template +inline T* Construct(T* pMemory, ARG1 a1, ARG2 a2, ARG3 a3, ARG4 a4) +{ + return ::new(pMemory) T(a1, a2, a3, a4); +} + +template +inline T* Construct(T* pMemory, ARG1 a1, ARG2 a2, ARG3 a3, ARG4 a4, ARG5 a5) +{ + return ::new(pMemory) T(a1, a2, a3, a4, a5); +} + +template +inline void ConstructOneArg(T* pMemory, P const& arg) +{ + ::new(pMemory) T(arg); +} + +template +inline void ConstructTwoArg(T* pMemory, P1 const& arg1, P2 const& arg2) +{ + ::new(pMemory) T(arg1, arg2); +} + +template +inline void ConstructThreeArg(T* pMemory, P1 const& arg1, P2 const& arg2, P3 const& arg3) +{ + ::new(pMemory) T(arg1, arg2, arg3); +} + +template +inline T* CopyConstruct(T* pMemory, T const& src) +{ + return ::new(pMemory) T(src); +} + +template +inline void Destruct(T* pMemory) +{ + pMemory->~T(); + +#ifdef _DEBUG + memset(reinterpret_cast(pMemory), 0xDD, sizeof(T)); +#endif +} + + +#define GET_OUTER( OuterType, OuterMember ) \ + ( ( OuterType * ) ( (uint8 *)this - offsetof( OuterType, OuterMember ) ) ) + + +PLATFORM_INTERFACE bool vtune(bool resume); + + +#define TEMPLATE_FUNCTION_TABLE(RETURN_TYPE, NAME, ARGS, COUNT) \ + \ +typedef RETURN_TYPE (FASTCALL *__Type_##NAME) ARGS; \ + \ +template \ +struct __Function_##NAME \ +{ \ + static RETURN_TYPE FASTCALL Run ARGS; \ +}; \ + \ +template \ +struct __MetaLooper_##NAME : __MetaLooper_##NAME \ +{ \ + __Type_##NAME func; \ + inline __MetaLooper_##NAME() { func = __Function_##NAME::Run; } \ +}; \ + \ +template<> \ +struct __MetaLooper_##NAME<0> \ +{ \ + __Type_##NAME func; \ + inline __MetaLooper_##NAME() { func = __Function_##NAME<0>::Run; } \ +}; \ + \ +class NAME \ +{ \ +private: \ + static const __MetaLooper_##NAME m; \ +public: \ + enum { count = COUNT }; \ + static const __Type_##NAME* functions; \ +}; \ +const __MetaLooper_##NAME NAME::m; \ +const __Type_##NAME* NAME::functions = (__Type_##NAME*)&m; \ +template \ +RETURN_TYPE FASTCALL __Function_##NAME::Run ARGS + + +#define LOOP_INTERCHANGE(BOOLEAN, CODE)\ + if( (BOOLEAN) )\ + {\ + CODE;\ + } else\ + {\ + CODE;\ + } + +#if 0 + +PLATFORM_INTERFACE void* Plat_GetProcAddress(const char* pszModule, const char* pszName); + +template +class CDynamicFunction +{ +public: + CDynamicFunction(const char* pszModule, const char* pszName, FUNCPTR_TYPE pfnFallback = NULL) + { + m_pfn = pfnFallback; + void* pAddr = Plat_GetProcAddress(pszModule, pszName); + if (pAddr) + { + m_pfn = (FUNCPTR_TYPE)pAddr; + } + } + + operator bool() { return m_pfn != NULL; } + bool operator !() { return !m_pfn; } + operator FUNCPTR_TYPE() { return m_pfn; } + +private: + FUNCPTR_TYPE m_pfn; +}; +#endif + + +#include "valve_on.h" + +#if defined(TIER0_DLL_EXPORT) +extern "C" int V_tier0_stricmp(const char* s1, const char* s2); +#undef stricmp +#undef strcmpi +#define stricmp(s1,s2) V_tier0_stricmp( s1, s2 ) +#define strcmpi(s1,s2) V_tier0_stricmp( s1, s2 ) +#endif + + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/playernet_vars.h b/SpyCustom/sdk/playernet_vars.h new file mode 100644 index 0000000..5de8c00 --- /dev/null +++ b/SpyCustom/sdk/playernet_vars.h @@ -0,0 +1,113 @@ +#ifndef PLAYERNET_VARS_H +#define PLAYERNET_VARS_H +#ifdef _WIN32 +#pragma once +#endif + +#include "shared_classnames.h" +#include "networkvar.h" +#include "datamap.h" + +#define NUM_AUDIO_LOCAL_SOUNDS 8 + +struct fogparams_t +{ + DECLARE_CLASS_NOBASE(fogparams_t); + DECLARE_EMBEDDED_NETWORKVAR(); + +#ifndef CLIENT_DLL + DECLARE_SIMPLE_DATADESC(); +#endif + + bool operator !=(const fogparams_t& other) const; + + CNetworkVector(dirPrimary); + CNetworkColor32(colorPrimary); + CNetworkColor32(colorSecondary); + CNetworkColor32(colorPrimaryLerpTo); + CNetworkColor32(colorSecondaryLerpTo); + CNetworkVar(float, start); + CNetworkVar(float, end); + CNetworkVar(float, farz); + CNetworkVar(float, maxdensity); + + CNetworkVar(float, startLerpTo); + CNetworkVar(float, endLerpTo); + CNetworkVar(float, lerptime); + CNetworkVar(float, duration); + CNetworkVar(bool, enable); + CNetworkVar(bool, blend); +}; + +#ifdef CLIENT_DLL +#define CFogController C_FogController +#endif + +class CFogController; + +struct fogplayerparams_t +{ + DECLARE_CLASS_NOBASE(fogplayerparams_t); + DECLARE_EMBEDDED_NETWORKVAR(); + +#ifndef CLIENT_DLL + DECLARE_SIMPLE_DATADESC(); +#endif + + CNetworkHandle(CFogController, m_hCtrl); + float m_flTransitionTime; + + color32 m_OldColor; + float m_flOldStart; + float m_flOldEnd; + + color32 m_NewColor; + float m_flNewStart; + float m_flNewEnd; + + fogplayerparams_t() + { + m_hCtrl.Set(NULL); + m_flTransitionTime = -1.0f; + m_OldColor.r = m_OldColor.g = m_OldColor.b = m_OldColor.a = 0; + m_flOldStart = 0.0f; + m_flOldEnd = 0.0f; + m_NewColor.r = m_NewColor.g = m_NewColor.b = m_NewColor.a = 0; + m_flNewStart = 0.0f; + m_flNewEnd = 0.0f; + } +}; + +struct sky3dparams_t +{ + DECLARE_CLASS_NOBASE(sky3dparams_t); + DECLARE_EMBEDDED_NETWORKVAR(); + +#ifndef CLIENT_DLL + DECLARE_SIMPLE_DATADESC(); +#endif + + CNetworkVar(int, scale); + CNetworkVector(origin); + CNetworkVar(int, area); + + CNetworkVarEmbedded(fogparams_t, fog); +}; + +struct audioparams_t +{ + DECLARE_CLASS_NOBASE(audioparams_t); + DECLARE_EMBEDDED_NETWORKVAR(); + +#ifndef CLIENT_DLL + DECLARE_SIMPLE_DATADESC(); +#endif + + CNetworkArray(Vector, localSound, NUM_AUDIO_LOCAL_SOUNDS) + CNetworkVar(int, soundscapeIndex); + CNetworkVar(int, localBits); + CNetworkHandle(CBaseEntity, ent); +}; + + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/precipitation_shared.h b/SpyCustom/sdk/precipitation_shared.h new file mode 100644 index 0000000..26a0e77 --- /dev/null +++ b/SpyCustom/sdk/precipitation_shared.h @@ -0,0 +1,22 @@ +#ifndef PRECIPITATION_SHARED_H +#define PRECIPITATION_SHARED_H +#ifdef _WIN32 +#pragma once +#endif + + +enum PrecipitationType_t +{ + PRECIPITATION_TYPE_RAIN = 0, + PRECIPITATION_TYPE_SNOW, + PRECIPITATION_TYPE_ASH, + PRECIPITATION_TYPE_SNOWFALL, + PRECIPITATION_TYPE_PARTICLERAIN, + PRECIPITATION_TYPE_PARTICLEASH, + PRECIPITATION_TYPE_PARTICLERAINSTORM, + PRECIPITATION_TYPE_PARTICLESNOW, + NUM_PRECIPITATION_TYPES +}; + + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/predictable_entity.h b/SpyCustom/sdk/predictable_entity.h new file mode 100644 index 0000000..38bcfb9 --- /dev/null +++ b/SpyCustom/sdk/predictable_entity.h @@ -0,0 +1,185 @@ +#ifndef PREDICTABLE_ENTITY_H +#define PREDICTABLE_ENTITY_H +#ifdef _WIN32 +#pragma once +#endif + +#include "platform.h" +#include "predictioncopy.h" +#include "shared_classnames.h" + +#ifndef NO_ENTITY_PREDICTION +#define UsePrediction() 1 +#else +#define UsePrediction() 0 +#endif + +#if defined( CLIENT_DLL ) + +#include "iclassmap.h" +#include "recvproxy.h" + +class SendTable; + +#else + +#include "sendproxy.h" + +#endif + +#if defined( CLIENT_DLL ) + +#define DECLARE_NETWORKCLASS() \ + DECLARE_CLIENTCLASS() + +#define DECLARE_NETWORKCLASS_NOBASE() \ + DECLARE_CLIENTCLASS_NOBASE() + +#else + +#define DECLARE_NETWORKCLASS() \ + DECLARE_SERVERCLASS() + +#define DECLARE_NETWORKCLASS_NOBASE() \ + DECLARE_SERVERCLASS_NOBASE() + +#endif + +#if defined( CLIENT_DLL ) + +#ifndef NO_ENTITY_PREDICTION +#define DECLARE_PREDICTABLE() \ + public: \ + static typedescription_t m_PredDesc[]; \ + static datamap_t m_PredMap; \ + virtual datamap_t *GetPredDescMap( void ); \ + template friend datamap_t *PredMapInit(T *) +#else +#define DECLARE_PREDICTABLE() template friend datamap_t *PredMapInit(T *) +#endif + +#ifndef NO_ENTITY_PREDICTION +#define BEGIN_PREDICTION_DATA( className ) \ + datamap_t className::m_PredMap = { 0, 0, #className, &BaseClass::m_PredMap }; \ + datamap_t *className::GetPredDescMap( void ) { return &m_PredMap; } \ + BEGIN_PREDICTION_DATA_GUTS( className ) + +#define BEGIN_PREDICTION_DATA_NO_BASE( className ) \ + datamap_t className::m_PredMap = { 0, 0, #className, NULL }; \ + datamap_t *className::GetPredDescMap( void ) { return &m_PredMap; } \ + BEGIN_PREDICTION_DATA_GUTS( className ) + +#define BEGIN_PREDICTION_DATA_GUTS( className ) \ + template datamap_t *PredMapInit(T *); \ + template <> datamap_t *PredMapInit( className * ); \ + namespace className##_PredDataDescInit \ + { \ + datamap_t *g_PredMapHolder = PredMapInit( (className *)NULL ); \ + } \ + \ + template <> datamap_t *PredMapInit( className * ) \ + { \ + typedef className classNameTypedef; \ + static typedescription_t predDesc[] = \ + { \ + { FIELD_VOID,0, {0,0},0,0,0,0,0,0}, + +#define END_PREDICTION_DATA() \ + }; \ + \ + if ( sizeof( predDesc ) > sizeof( predDesc[0] ) ) \ + { \ + classNameTypedef::m_PredMap.dataNumFields = ARRAYSIZE( predDesc ) - 1; \ + classNameTypedef::m_PredMap.dataDesc = &predDesc[1]; \ + } \ + else \ + { \ + classNameTypedef::m_PredMap.dataNumFields = 1; \ + classNameTypedef::m_PredMap.dataDesc = predDesc; \ + } \ + return &classNameTypedef::m_PredMap; \ + } +#else +#define BEGIN_PREDICTION_DATA( className ) \ + template <> inline datamap_t *PredMapInit( className * ) \ + { \ + if ( 0 ) \ + { \ + typedef className classNameTypedef; \ + typedescription_t predDesc[] = \ + { \ + { FIELD_VOID,0, {0,0},0,0,0,0,0,0}, + +#define BEGIN_PREDICTION_DATA_NO_BASE( className ) BEGIN_PREDICTION_DATA( className ) + +#define END_PREDICTION_DATA() \ + }; \ + predDesc[0].flags = 0; \ + } \ + } +#endif + +#else + +#define DECLARE_PREDICTABLE() +#define BEGIN_PREDICTION_DATA( className ) +#define END_PREDICTION_DATA() + +#endif + +#if defined( CLIENT_DLL ) + +#define LINK_ENTITY_TO_CLASS( localName, className ) \ + static C_BaseEntity *C##className##Factory( void ) \ + { \ + return static_cast< C_BaseEntity * >( new className ); \ + }; \ + class C##localName##Foo \ + { \ + public: \ + C##localName##Foo( void ) \ + { \ + GetClassMap().Add( #localName, #className, sizeof( className ), \ + &C##className##Factory ); \ + } \ + }; \ + static C##localName##Foo g_C##localName##Foo; + +#define BEGIN_NETWORK_TABLE( className, tableName ) BEGIN_RECV_TABLE( className, tableName ) +#define BEGIN_NETWORK_TABLE_NOBASE( className, tableName ) BEGIN_RECV_TABLE_NOBASE( className, tableName ) + +#define END_NETWORK_TABLE END_RECV_TABLE + +#define IMPLEMENT_NETWORKCLASS_ALIASED(className, dataTable) \ + IMPLEMENT_CLIENTCLASS( C_##className, dataTable, C##className ) +#define IMPLEMENT_NETWORKCLASS(className, dataTable) \ + IMPLEMENT_CLIENTCLASS(className, dataTable, className) +#define IMPLEMENT_NETWORKCLASS_DT(className, dataTable) \ + IMPLEMENT_CLIENTCLASS_DT(className, dataTable, className) + +#else + +#define BEGIN_NETWORK_TABLE( className, tableName ) BEGIN_SEND_TABLE( className, tableName ) +#define BEGIN_NETWORK_TABLE_NOBASE( className, tableName ) BEGIN_SEND_TABLE_NOBASE( className, tableName ) + +#define END_NETWORK_TABLE END_SEND_TABLE + +#define IMPLEMENT_NETWORKCLASS_ALIASED(className, dataTable) \ + IMPLEMENT_SERVERCLASS( C##className, dataTable ) +#define IMPLEMENT_NETWORKCLASS(className, dataTable) \ + IMPLEMENT_SERVERCLASS(className, dataTable) +#define IMPLEMENT_NETWORKCLASS_DT(className, dataTable) \ + IMPLEMENT_SERVERCLASS_ST(className, dataTable) + +#endif + +abstract_class IPredictableList +{ +public: + virtual CBaseEntity* GetPredictable(int slot) = 0; + virtual int GetPredictableCount(void) = 0; +}; + +extern IPredictableList* predictables; + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/predictableid.h b/SpyCustom/sdk/predictableid.h new file mode 100644 index 0000000..5ec7216 --- /dev/null +++ b/SpyCustom/sdk/predictableid.h @@ -0,0 +1,53 @@ +#ifndef PREDICTABLEID_H +#define PREDICTABLEID_H +#ifdef _WIN32 +#pragma once +#endif + +#if !defined( NO_ENTITY_PREDICTION ) +class CPredictableId +{ +public: + CPredictableId(void); + + static void ResetInstanceCounters(void); + + bool IsActive(void) const; + + void Init(int player, int command, const char* classname, const char* module, int line); + + int GetPlayer(void) const; + int GetHash(void) const; + int GetInstanceNumber(void) const; + int GetCommandNumber(void) const; + + void SetAcknowledged(bool ack); + bool GetAcknowledged(void) const; + + int GetRaw(void) const; + void SetRaw(int raw); + + char const* Describe(void) const; + + bool operator ==(const CPredictableId& other) const; + bool operator !=(const CPredictableId& other) const; +private: + void SetCommandNumber(int commandNumber); + void SetPlayer(int playerIndex); + void SetInstanceNumber(int counter); + + struct bitfields + { + unsigned int ack : 1; + unsigned int player : 5; + unsigned int command : 10; + unsigned int hash : 12; + unsigned int instance : 4; + } m_PredictableID; +}; + +FORCEINLINE void NetworkVarConstruct(CPredictableId& x) {} + +#endif + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/predictioncopy.h b/SpyCustom/sdk/predictioncopy.h new file mode 100644 index 0000000..ed24b7e --- /dev/null +++ b/SpyCustom/sdk/predictioncopy.h @@ -0,0 +1,278 @@ +#ifndef PREDICTIONCOPY_H +#define PREDICTIONCOPY_H +#ifdef _WIN32 +#pragma once +#endif + +#include +#include "datamap.h" +#include "ehandle.h" +#include "utlstring.h" + +#if defined( CLIENT_DLL ) +class C_BaseEntity; +typedef CHandle EHANDLE; + +#if defined( _DEBUG ) +class IGameSystem; +IGameSystem* GetPredictionCopyTester(void); +#endif + +#else +class CBaseEntity; +typedef CHandle EHANDLE; +#endif + +enum +{ + PC_EVERYTHING = 0, + PC_NON_NETWORKED_ONLY, + PC_NETWORKED_ONLY, +}; + +#define PC_DATA_PACKED true +#define PC_DATA_NORMAL false + +typedef void (*FN_FIELD_COMPARE)(const char* classname, const char* fieldname, const char* fieldtype, + bool networked, bool noterrorchecked, bool differs, bool withintolerance, const char* value); + +class CPredictionCopy +{ +public: + typedef enum + { + DIFFERS = 0, + IDENTICAL, + WITHINTOLERANCE, + } difftype_t; + + CPredictionCopy(int type, void* dest, bool dest_packed, void const* src, bool src_packed, + bool counterrors = false, bool reporterrors = false, bool performcopy = true, + bool describefields = false, FN_FIELD_COMPARE func = NULL); + + void CopyShort(difftype_t dt, short* outvalue, const short* invalue, int count); + void CopyInt(difftype_t dt, int* outvalue, const int* invalue, int count); + void CopyBool(difftype_t dt, bool* outvalue, const bool* invalue, int count); + void CopyFloat(difftype_t dt, float* outvalue, const float* invalue, int count); + void CopyString(difftype_t dt, char* outstring, const char* instring); + void CopyVector(difftype_t dt, Vector& outValue, const Vector& inValue); + void CopyVector(difftype_t dt, Vector* outValue, const Vector* inValue, int count); + void CopyQuaternion(difftype_t dt, Quaternion& outValue, const Quaternion& inValue); + void CopyQuaternion(difftype_t dt, Quaternion* outValue, const Quaternion* inValue, int count); + void CopyEHandle(difftype_t dt, EHANDLE* outvalue, EHANDLE const* invalue, int count); + + void FORCEINLINE CopyData(difftype_t dt, int size, char* outdata, const char* indata) + { + if (!m_bPerformCopy) + return; + + if (dt == IDENTICAL) + return; + + memcpy(outdata, indata, size); + } + + int TransferData(const char* operation, int entindex, datamap_t* dmap); + +private: + void TransferData_R(int chaincount, datamap_t* dmap); + + void DetermineWatchField(const char* operation, int entindex, datamap_t* dmap); + void DumpWatchField(typedescription_t* field); + void WatchMsg(PRINTF_FORMAT_STRING const char* fmt, ...); + + difftype_t CompareShort(short* outvalue, const short* invalue, int count); + difftype_t CompareInt(int* outvalue, const int* invalue, int count); + difftype_t CompareBool(bool* outvalue, const bool* invalue, int count); + difftype_t CompareFloat(float* outvalue, const float* invalue, int count); + difftype_t CompareData(int size, char* outdata, const char* indata); + difftype_t CompareString(char* outstring, const char* instring); + difftype_t CompareVector(Vector& outValue, const Vector& inValue); + difftype_t CompareVector(Vector* outValue, const Vector* inValue, int count); + difftype_t CompareQuaternion(Quaternion& outValue, const Quaternion& inValue); + difftype_t CompareQuaternion(Quaternion* outValue, const Quaternion* inValue, int count); + difftype_t CompareEHandle(EHANDLE* outvalue, EHANDLE const* invalue, int count); + + void DescribeShort(difftype_t dt, short* outvalue, const short* invalue, int count); + void DescribeInt(difftype_t dt, int* outvalue, const int* invalue, int count); + void DescribeBool(difftype_t dt, bool* outvalue, const bool* invalue, int count); + void DescribeFloat(difftype_t dt, float* outvalue, const float* invalue, int count); + void DescribeData(difftype_t dt, int size, char* outdata, const char* indata); + void DescribeString(difftype_t dt, char* outstring, const char* instring); + void DescribeVector(difftype_t dt, Vector& outValue, const Vector& inValue); + void DescribeVector(difftype_t dt, Vector* outValue, const Vector* inValue, int count); + void DescribeQuaternion(difftype_t dt, Quaternion& outValue, const Quaternion& inValue); + void DescribeQuaternion(difftype_t dt, Quaternion* outValue, const Quaternion* inValue, int count); + void DescribeEHandle(difftype_t dt, EHANDLE* outvalue, EHANDLE const* invalue, int count); + + void WatchShort(difftype_t dt, short* outvalue, const short* invalue, int count); + void WatchInt(difftype_t dt, int* outvalue, const int* invalue, int count); + void WatchBool(difftype_t dt, bool* outvalue, const bool* invalue, int count); + void WatchFloat(difftype_t dt, float* outvalue, const float* invalue, int count); + void WatchData(difftype_t dt, int size, char* outdata, const char* indata); + void WatchString(difftype_t dt, char* outstring, const char* instring); + void WatchVector(difftype_t dt, Vector& outValue, const Vector& inValue); + void WatchVector(difftype_t dt, Vector* outValue, const Vector* inValue, int count); + void WatchQuaternion(difftype_t dt, Quaternion& outValue, const Quaternion& inValue); + void WatchQuaternion(difftype_t dt, Quaternion* outValue, const Quaternion* inValue, int count); + void WatchEHandle(difftype_t dt, EHANDLE* outvalue, EHANDLE const* invalue, int count); + + void ReportFieldsDiffer(PRINTF_FORMAT_STRING const char* fmt, ...); + void DescribeFields(difftype_t dt, PRINTF_FORMAT_STRING const char* fmt, ...); + + bool CanCheck(void); + + void CopyFields(int chaincount, datamap_t* pMap, typedescription_t* pFields, int fieldCount); + +private: + + int m_nType; + void* m_pDest; + void const* m_pSrc; + int m_nDestOffsetIndex; + int m_nSrcOffsetIndex; + + + bool m_bErrorCheck; + bool m_bReportErrors; + bool m_bDescribeFields; + typedescription_t* m_pCurrentField; + char const* m_pCurrentClassName; + datamap_t* m_pCurrentMap; + bool m_bShouldReport; + bool m_bShouldDescribe; + int m_nErrorCount; + bool m_bPerformCopy; + + FN_FIELD_COMPARE m_FieldCompareFunc; + + typedescription_t* m_pWatchField; + char const* m_pOperation; +}; + +typedef void (*FN_FIELD_DESCRIPTION)(const char* classname, const char* fieldname, const char* fieldtype, + bool networked, const char* value); + +class CPredictionDescribeData +{ +public: + CPredictionDescribeData(void const* src, bool src_packed, FN_FIELD_DESCRIPTION func = 0); + + void DescribeShort(const short* invalue, int count); + void DescribeInt(const int* invalue, int count); + void DescribeBool(const bool* invalue, int count); + void DescribeFloat(const float* invalue, int count); + void DescribeData(int size, const char* indata); + void DescribeString(const char* instring); + void DescribeVector(const Vector& inValue); + void DescribeVector(const Vector* inValue, int count); + void DescribeQuaternion(const Quaternion& inValue); + void DescribeQuaternion(const Quaternion* inValue, int count); + void DescribeEHandle(EHANDLE const* invalue, int count); + + void DumpDescription(datamap_t* pMap); + +private: + void DescribeFields_R(int chain_count, datamap_t* pMap, typedescription_t* pFields, int fieldCount); + + void const* m_pSrc; + int m_nSrcOffsetIndex; + + void Describe(PRINTF_FORMAT_STRING const char* fmt, ...); + + typedescription_t* m_pCurrentField; + char const* m_pCurrentClassName; + datamap_t* m_pCurrentMap; + + bool m_bShouldReport; + + FN_FIELD_DESCRIPTION m_FieldDescFunc; +}; + +#if defined( CLIENT_DLL ) +class CValueChangeTracker +{ +public: + CValueChangeTracker(); + + void Reset(); + + void StartTrack(char const* pchContext); + void EndTrack(); + + bool IsActive() const; + + void SetupTracking(C_BaseEntity* ent, char const* pchFieldName); + void ClearTracking(); + + void Spew(); + + C_BaseEntity* GetEntity(); + +private: + + enum + { + eChangeTrackerBufSize = 128, + }; + + void GetValue(char* buf, size_t bufsize); + + bool m_bActive : 1; + bool m_bTracking : 1; + EHANDLE m_hEntityToTrack; + CUtlVector< typedescription_t* > m_FieldStack; + CUtlString m_strFieldName; + CUtlString m_strContext; + char m_OrigValueBuf[eChangeTrackerBufSize]; + CUtlVector< CUtlString > m_History; +}; + +extern CValueChangeTracker* g_pChangeTracker; + +class CValueChangeTrackerScope +{ +public: + CValueChangeTrackerScope(char const* pchContext) + { + m_bCallEndTrack = true; + g_pChangeTracker->StartTrack(pchContext); + } + + CValueChangeTrackerScope(C_BaseEntity* pEntity, char const* pchContext) + { + m_bCallEndTrack = g_pChangeTracker->GetEntity() == pEntity; + if (m_bCallEndTrack) + { + g_pChangeTracker->StartTrack(pchContext); + } + } + + ~CValueChangeTrackerScope() + { + if (m_bCallEndTrack) + { + g_pChangeTracker->EndTrack(); + } + } +private: + + bool m_bCallEndTrack; +}; + +#if defined( _DEBUG ) +#define PREDICTION_TRACKVALUECHANGESCOPE( context ) CValueChangeTrackerScope scope( context ); +#define PREDICTION_TRACKVALUECHANGESCOPE_ENTITY( entity, context ) CValueChangeTrackerScope scope( entity, context ); +#define PREDICTION_STARTTRACKVALUE( context ) g_pChangeTracker->StartTrack( context ); +#define PREDICTION_ENDTRACKVALUE() g_pChangeTracker->EndTrack(); +#define PREDICTION_SPEWVALUECHANGES() g_pChangeTracker->Spew(); +#else +#define PREDICTION_TRACKVALUECHANGESCOPE( context ) +#define PREDICTION_TRACKVALUECHANGESCOPE_ENTITY( entity, context ) +#define PREDICTION_STARTTRACKVALUE( context ) +#define PREDICTION_ENDTRACKVALUE() +#define PREDICTION_SPEWVALUECHANGES() +#endif + +#endif +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/ragdoll.h b/SpyCustom/sdk/ragdoll.h new file mode 100644 index 0000000..9a5de13 --- /dev/null +++ b/SpyCustom/sdk/ragdoll.h @@ -0,0 +1,111 @@ +#ifndef RAGDOLL_H +#define RAGDOLL_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "ragdoll_shared.h" + +#define RAGDOLL_VISUALIZE 0 + +class C_BaseEntity; +class CStudioHdr; +struct mstudiobone_t; +class Vector; +class IPhysicsObject; +class CBoneAccessor; + +abstract_class IRagdoll +{ +public: + virtual ~IRagdoll() {} + + virtual void RagdollBone(C_BaseEntity * ent, mstudiobone_t * pbones, int boneCount, bool* boneSimulated, CBoneAccessor & pBoneToWorld) = 0; + virtual const Vector& GetRagdollOrigin() = 0; + virtual void GetRagdollBounds(Vector& mins, Vector& maxs) = 0; + virtual int RagdollBoneCount() const = 0; + virtual IPhysicsObject* GetElement(int elementNum) = 0; + virtual void DrawWireframe(void) = 0; + virtual void VPhysicsUpdate(IPhysicsObject* pObject) = 0; +}; + +class CRagdoll : public IRagdoll +{ +public: + CRagdoll(); + ~CRagdoll(void); + + DECLARE_SIMPLE_DATADESC(); + + void Init( + C_BaseEntity* ent, + CStudioHdr* pstudiohdr, + const Vector& forceVector, + int forceBone, + const matrix3x4_t* pDeltaBones0, + const matrix3x4_t* pDeltaBones1, + const matrix3x4_t* pCurrentBonePosition, + float boneDt); + + virtual void RagdollBone(C_BaseEntity* ent, mstudiobone_t* pbones, int boneCount, bool* boneSimulated, CBoneAccessor& pBoneToWorld); + virtual const Vector& GetRagdollOrigin(); + virtual void GetRagdollBounds(Vector& theMins, Vector& theMaxs); + void BuildRagdollBounds(C_BaseEntity* ent); + + virtual IPhysicsObject* GetElement(int elementNum); + virtual IPhysicsConstraintGroup* GetConstraintGroup() { return m_ragdoll.pGroup; } + virtual void DrawWireframe(); + virtual void VPhysicsUpdate(IPhysicsObject* pPhysics); + virtual int RagdollBoneCount() const { return m_ragdoll.listCount; } + + + void SetInitialBonePosition(CStudioHdr* pstudiohdr, const CBoneAccessor& pDesiredBonePosition); + + bool IsValid() { return m_ragdoll.listCount > 0; } + bool IsAsleep(void) const { return m_allAsleep; } + + void ResetRagdollSleepAfterTime(void); + float GetLastVPhysicsUpdateTime() const { return m_lastUpdate; } + +private: + + void CheckSettleStationaryRagdoll(); + void PhysForceRagdollToSleep(); + + ragdoll_t m_ragdoll; + Vector m_mins, m_maxs; + Vector m_origin; + float m_lastUpdate; + bool m_allAsleep; + Vector m_vecLastOrigin; + float m_flLastOriginChangeTime; + float m_flAwakeTime; + +#if RAGDOLL_VISUALIZE + matrix3x4_t m_savedBone1[MAXSTUDIOBONES]; + matrix3x4_t m_savedBone2[MAXSTUDIOBONES]; + matrix3x4_t m_savedBone3[MAXSTUDIOBONES]; +#endif + +public: + + ragdoll_t* GetRagdoll(void) { return &m_ragdoll; } +}; + + +CRagdoll* CreateRagdoll( + C_BaseEntity* ent, + CStudioHdr* pstudiohdr, + const Vector& forceVector, + int forceBone, + const matrix3x4_t* pDeltaBones0, + const matrix3x4_t* pDeltaBones1, + const matrix3x4_t* pCurrentBonePosition, + float boneDt); + + +void NoteRagdollCreationTick(C_BaseEntity* pRagdoll); +bool WasRagdollCreatedOnCurrentTick(C_BaseEntity* pRagdoll); + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/ragdoll_shared.h b/SpyCustom/sdk/ragdoll_shared.h new file mode 100644 index 0000000..ca5ed8a --- /dev/null +++ b/SpyCustom/sdk/ragdoll_shared.h @@ -0,0 +1,135 @@ +#ifndef RAGDOLL_SHARED_H +#define RAGDOLL_SHARED_H +#ifdef _WIN32 +#pragma once +#endif + +class IPhysicsObject; +class IPhysicsConstraint; +class IPhysicsConstraintGroup; +class IPhysicsCollision; +class IPhysicsEnvironment; +class IPhysicsSurfaceProps; +struct matrix3x4_t; + +struct vcollide_t; +struct studiohdr_t; +class CStudioHdr; +class CBoneAccessor; + +#include "vector.h" +#include "bone_accessor.h" + +#define RAGDOLL_MAX_ELEMENTS 24 +#define RAGDOLL_INDEX_BITS 5 + +#define CORE_DISSOLVE_FADE_START 0.2f +#define CORE_DISSOLVE_MODEL_FADE_START 0.1f +#define CORE_DISSOLVE_MODEL_FADE_LENGTH 0.05f +#define CORE_DISSOLVE_FADEIN_LENGTH 0.1f + +struct ragdollelement_t +{ + Vector originParentSpace; + IPhysicsObject* pObject; + IPhysicsConstraint* pConstraint; + int parentIndex; +}; + +struct ragdollanimatedfriction_t +{ + float flFrictionTimeIn; + float flFrictionTimeOut; + float flFrictionTimeHold; + int iMinAnimatedFriction; + int iMaxAnimatedFriction; +}; + +struct ragdoll_t +{ + int listCount; + bool allowStretch; + bool unused; + IPhysicsConstraintGroup* pGroup; + ragdollelement_t list[RAGDOLL_MAX_ELEMENTS]; + int boneIndex[RAGDOLL_MAX_ELEMENTS]; + ragdollanimatedfriction_t animfriction; +}; + +struct ragdollparams_t +{ + void* pGameData; + vcollide_t* pCollide; + CStudioHdr* pStudioHdr; + int modelIndex; + Vector forcePosition; + Vector forceVector; + int forceBoneIndex; + const matrix3x4_t* pCurrentBones; + float jointFrictionScale; + bool allowStretch; + bool fixedConstraints; +}; + +class CRagdollLRURetirement : public CAutoGameSystemPerFrame +{ +public: + CRagdollLRURetirement(char const* name) : CAutoGameSystemPerFrame(name) + { + } + + virtual void Update(float frametime); + virtual void FrameUpdatePostEntityThink(void); + + void MoveToTopOfLRU(CBaseAnimating* pRagdoll, bool bImportant = false); + void SetMaxRagdollCount(int iMaxCount) { m_iMaxRagdolls = iMaxCount; } + + virtual void LevelInitPreEntity(void); + int CountRagdolls(bool bOnlySimulatingRagdolls) { return bOnlySimulatingRagdolls ? m_iSimulatedRagdollCount : m_iRagdollCount; } + +private: + typedef CHandle CRagdollHandle; + CUtlLinkedList< CRagdollHandle > m_LRU; + CUtlLinkedList< CRagdollHandle > m_LRUImportantRagdolls; + + int m_iMaxRagdolls; + int m_iSimulatedRagdollCount; + int m_iRagdollCount; +}; + +extern CRagdollLRURetirement s_RagdollLRU; + +class CRagdollLowViolenceManager +{ +public: + CRagdollLowViolenceManager() { m_bLowViolence = false; } + void SetLowViolence(const char* pMapName); + bool IsLowViolence(void) { return m_bLowViolence; } + +private: + bool m_bLowViolence; +}; + +extern CRagdollLowViolenceManager g_RagdollLVManager; + + +bool RagdollCreate(ragdoll_t& ragdoll, const ragdollparams_t& params, IPhysicsEnvironment* pPhysEnv); + +void RagdollActivate(ragdoll_t& ragdoll, vcollide_t* pCollide, int modelIndex, bool bForceWake = true); +void RagdollSetupCollisions(ragdoll_t& ragdoll, vcollide_t* pCollide, int modelIndex); +void RagdollDestroy(ragdoll_t& ragdoll); + +bool RagdollGetBoneMatrix(const ragdoll_t& ragdoll, CBoneAccessor& pBoneToWorld, int objectIndex); + +int RagdollExtractBoneIndices(int* boneIndexOut, CStudioHdr* pStudioHdr, vcollide_t* pCollide); + +void RagdollComputeExactBbox(const ragdoll_t& ragdoll, const Vector& origin, Vector& outMins, Vector& outMaxs); +bool RagdollIsAsleep(const ragdoll_t& ragdoll); +void RagdollSetupAnimatedFriction(IPhysicsEnvironment* pPhysEnv, ragdoll_t* ragdoll, int iModelIndex); + +void RagdollApplyAnimationAsVelocity(ragdoll_t& ragdoll, const matrix3x4_t* pBoneToWorld); +void RagdollApplyAnimationAsVelocity(ragdoll_t& ragdoll, const matrix3x4_t* pPrevBones, const matrix3x4_t* pCurrentBones, float dt); + +void RagdollSolveSeparation(ragdoll_t& ragdoll, CBaseEntity* pEntity); + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/random.h b/SpyCustom/sdk/random.h new file mode 100644 index 0000000..8448e2d --- /dev/null +++ b/SpyCustom/sdk/random.h @@ -0,0 +1,77 @@ +#ifndef VSTDLIB_RANDOM_H +#define VSTDLIB_RANDOM_H + +#include "vstdlib.h" +#include "basetypes.h" +#include "threadtools.h" +#include "interface.h" + +#define NTAB 32 + +#pragma warning(push) +#pragma warning( disable:4251 ) + +class IUniformRandomStream +{ +public: + virtual void SetSeed(int iSeed) = 0; + + virtual float RandomFloat(float flMinVal = 0.0f, float flMaxVal = 1.0f) = 0; + virtual int RandomInt(int iMinVal, int iMaxVal) = 0; + virtual float RandomFloatExp(float flMinVal = 0.0f, float flMaxVal = 1.0f, float flExponent = 1.0f) = 0; +}; + + +class VSTDLIB_CLASS CUniformRandomStream : public IUniformRandomStream +{ +public: + CUniformRandomStream(); + + virtual void SetSeed(int iSeed); + + virtual float RandomFloat(float flMinVal = 0.0f, float flMaxVal = 1.0f); + virtual int RandomInt(int iMinVal, int iMaxVal); + virtual float RandomFloatExp(float flMinVal = 0.0f, float flMaxVal = 1.0f, float flExponent = 1.0f); + +private: + int GenerateRandomNumber(); + + int m_idum; + int m_iy; + int m_iv[NTAB]; + + CThreadFastMutex m_mutex; +}; + + +class VSTDLIB_CLASS CGaussianRandomStream +{ +public: + CGaussianRandomStream(IUniformRandomStream* pUniformStream = NULL); + + void AttachToStream(IUniformRandomStream* pUniformStream = NULL); + + float RandomFloat(float flMean = 0.0f, float flStdDev = 1.0f); + +private: + IUniformRandomStream* m_pUniformStream; + bool m_bHaveValue; + float m_flRandomValue; + + CThreadFastMutex m_mutex; +}; + + +VSTDLIB_INTERFACE void RandomSeed(int iSeed); +VSTDLIB_INTERFACE float RandomFloat(float flMinVal = 0.0f, float flMaxVal = 1.0f); +VSTDLIB_INTERFACE float RandomFloatExp(float flMinVal = 0.0f, float flMaxVal = 1.0f, float flExponent = 1.0f); +VSTDLIB_INTERFACE int RandomInt(int iMinVal, int iMaxVal); +VSTDLIB_INTERFACE float RandomGaussianFloat(float flMean = 0.0f, float flStdDev = 1.0f); + + +VSTDLIB_INTERFACE void InstallUniformRandomStream(IUniformRandomStream* pStream); + + +#pragma warning(pop) + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/rangecheckedvar.h b/SpyCustom/sdk/rangecheckedvar.h new file mode 100644 index 0000000..9c07cb4 --- /dev/null +++ b/SpyCustom/sdk/rangecheckedvar.h @@ -0,0 +1,109 @@ +#ifndef RANGECHECKEDVAR_H +#define RANGECHECKEDVAR_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "dbg.h" +#include "threadtools.h" +#include "vector.h" +#include + + +class CDisableRangeChecks +{ +public: + CDisableRangeChecks(); + ~CDisableRangeChecks(); +}; + + +template< class T > +inline void RangeCheck(const T& value, int minValue, int maxValue) +{ +#ifdef _DEBUG + extern bool g_bDoRangeChecks; + if (ThreadInMainThread() && g_bDoRangeChecks) + { + Assert(_finite(value)); + } +#endif +} + +inline void RangeCheck(const Vector& value, int minValue, int maxValue) +{ +#ifdef _DEBUG + RangeCheck(value.x, minValue, maxValue); + RangeCheck(value.y, minValue, maxValue); + RangeCheck(value.z, minValue, maxValue); +#endif +} + + +template< class T, int minValue, int maxValue, int startValue > +class CRangeCheckedVar +{ +public: + + inline CRangeCheckedVar() + { + m_Val = startValue; + } + + inline CRangeCheckedVar(const T& value) + { + *this = value; + } + + T GetRaw() const + { + return m_Val; + } + + inline void Clamp() + { + if (m_Val < minValue) + m_Val = minValue; + else if (m_Val > maxValue) + m_Val = maxValue; + } + + inline operator const T& () const + { + return m_Val; + } + + inline CRangeCheckedVar& operator=(const T& value) + { + RangeCheck(value, minValue, maxValue); + m_Val = value; + return *this; + } + + inline CRangeCheckedVar& operator+=(const T& value) + { + return (*this = m_Val + value); + } + + inline CRangeCheckedVar& operator-=(const T& value) + { + return (*this = m_Val - value); + } + + inline CRangeCheckedVar& operator*=(const T& value) + { + return (*this = m_Val * value); + } + + inline CRangeCheckedVar& operator/=(const T& value) + { + return (*this = m_Val / value); + } + +private: + + T m_Val; +}; + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/recvproxy.h b/SpyCustom/sdk/recvproxy.h new file mode 100644 index 0000000..412c8c4 --- /dev/null +++ b/SpyCustom/sdk/recvproxy.h @@ -0,0 +1,45 @@ +#ifndef RECVPROXY_H +#define RECVPROXY_H + + +class CRecvProxyData; + + +void RecvProxy_IntToEHandle(const CRecvProxyData* pData, void* pStruct, void* pOut); + +void RecvProxy_IntToMoveParent(const CRecvProxyData* pData, void* pStruct, void* pOut); +void RecvProxy_IntToColor32(const CRecvProxyData* pData, void* pStruct, void* pOut); +void RecvProxy_IntSubOne(const CRecvProxyData* pData, void* pStruct, void* pOut); +void RecvProxy_ShortSubOne(const CRecvProxyData* pData, void* pStruct, void* pOut); +void RecvProxy_InterpolationAmountChanged(const CRecvProxyData* pData, void* pStruct, void* pOut); + +RecvProp RecvPropTime( + char* pVarName, + int offset, + int sizeofVar = SIZEOF_IGNORE); + +#if !defined( NO_ENTITY_PREDICTION ) && defined( USE_PREDICTABLEID ) +RecvProp RecvPropPredictableId( + char* pVarName, + int offset, + int sizeofVar = SIZEOF_IGNORE); +#endif + +RecvProp RecvPropEHandle( + char* pVarName, + int offset, + int sizeofVar = SIZEOF_IGNORE, + RecvVarProxyFn proxyFn = RecvProxy_IntToEHandle); + +RecvProp RecvPropBool( + char* pVarName, + int offset, + int sizeofVar); + +RecvProp RecvPropIntWithMinusOneFlag( + char* pVarName, + int offset, + int sizeofVar = SIZEOF_IGNORE, + RecvVarProxyFn proxyFn = RecvProxy_IntSubOne); + +#endif diff --git a/SpyCustom/sdk/refcount.h b/SpyCustom/sdk/refcount.h new file mode 100644 index 0000000..4f10d10 --- /dev/null +++ b/SpyCustom/sdk/refcount.h @@ -0,0 +1,320 @@ +#ifndef REFCOUNT_H +#define REFCOUNT_H + +#include "threadtools.h" + +#if defined( _WIN32 ) +#pragma once +#endif + +class IRefCounted +{ +public: + virtual int AddRef() = 0; + virtual int Release() = 0; +}; + + +template +inline int SafeRelease(REFCOUNTED_ITEM_PTR& pRef) +{ + REFCOUNTED_ITEM_PTR* ppRef = &pRef; + if (*ppRef) + { + int result = (*ppRef)->Release(); + *ppRef = NULL; + return result; + } + return 0; +} + +template +class CAutoRef +{ +public: + CAutoRef(T* pRef) + : m_pRef(pRef) + { + if (m_pRef) + m_pRef->AddRef(); + } + + ~CAutoRef() + { + if (m_pRef) + m_pRef->Release(); + } + +private: + T* m_pRef; +}; + +#define RetAddRef( p ) ( (p)->AddRef(), (p) ) +#define InlineAddRef( p ) ( (p)->AddRef(), (p) ) + + +template +class CBaseAutoPtr +{ +public: + CBaseAutoPtr() : m_pObject(0) {} + CBaseAutoPtr(T* pFrom) : m_pObject(pFrom) {} + + operator const void* () const { return m_pObject; } + operator void* () { return m_pObject; } + + operator const T* () const { return m_pObject; } + operator const T* () { return m_pObject; } + operator T* () { return m_pObject; } + + int operator=(int i) { AssertMsg(i == 0, "Only NULL allowed on integer assign"); m_pObject = 0; return 0; } + T* operator=(T* p) { m_pObject = p; return p; } + + bool operator !() const { return (!m_pObject); } + bool operator!=(int i) const { AssertMsg(i == 0, "Only NULL allowed on integer compare"); return (m_pObject != NULL); } + bool operator==(const void* p) const { return (m_pObject == p); } + bool operator!=(const void* p) const { return (m_pObject != p); } + bool operator==(T* p) const { return operator==((void*)p); } + bool operator!=(T* p) const { return operator!=((void*)p); } + bool operator==(const CBaseAutoPtr& p) const { return operator==((const void*)p); } + bool operator!=(const CBaseAutoPtr& p) const { return operator!=((const void*)p); } + + T* operator->() { return m_pObject; } + T& operator *() { return *m_pObject; } + T** operator &() { return &m_pObject; } + + const T* operator->() const { return m_pObject; } + const T& operator *() const { return *m_pObject; } + T* const* operator &() const { return &m_pObject; } + +protected: + CBaseAutoPtr(const CBaseAutoPtr& from) : m_pObject(from.m_pObject) {} + void operator=(const CBaseAutoPtr& from) { m_pObject = from.m_pObject; } + + T* m_pObject; +}; + +template +class CRefPtr : public CBaseAutoPtr +{ + typedef CBaseAutoPtr BaseClass; +public: + CRefPtr() {} + CRefPtr(T* pInit) : BaseClass(pInit) {} + CRefPtr(const CRefPtr& from) : BaseClass(from) {} + ~CRefPtr() { if (BaseClass::m_pObject) BaseClass::m_pObject->Release(); } + + void operator=(const CRefPtr& from) { BaseClass::operator=(from); } + + int operator=(int i) { return BaseClass::operator=(i); } + T* operator=(T* p) { return BaseClass::operator=(p); } + + operator bool() const { return !BaseClass::operator!(); } + operator bool() { return !BaseClass::operator!(); } + + void SafeRelease() { if (BaseClass::m_pObject) BaseClass::m_pObject->Release(); BaseClass::m_pObject = 0; } + void AssignAddRef(T* pFrom) { SafeRelease(); if (pFrom) pFrom->AddRef(); BaseClass::m_pObject = pFrom; } + void AddRefAssignTo(T*& pTo) { ::SafeRelease(pTo); if (BaseClass::m_pObject) BaseClass::m_pObject->AddRef(); pTo = BaseClass::m_pObject; } +}; + + +class CRefMT +{ +public: + static int Increment(int* p) { return ThreadInterlockedIncrement((long*)p); } + static int Decrement(int* p) { return ThreadInterlockedDecrement((long*)p); } +}; + +class CRefST +{ +public: + static int Increment(int* p) { return ++(*p); } + static int Decrement(int* p) { return --(*p); } +}; + +template +class NO_VTABLE CRefCountServiceBase +{ +protected: + CRefCountServiceBase() + : m_iRefs(1) + { + } + + virtual ~CRefCountServiceBase() + { + } + + virtual bool OnFinalRelease() + { + return true; + } + + int GetRefCount() const + { + return m_iRefs; + } + + int DoAddRef() + { + return CRefThreading::Increment(&m_iRefs); + } + + int DoRelease() + { + int result = CRefThreading::Decrement(&m_iRefs); + if (result) + return result; + if (OnFinalRelease() && bSelfDelete) + delete this; + return 0; + } + +private: + int m_iRefs; +}; + +class CRefCountServiceNull +{ +protected: + static int DoAddRef() { return 1; } + static int DoRelease() { return 1; } +}; + +template +class NO_VTABLE CRefCountServiceDestruct +{ +protected: + CRefCountServiceDestruct() + : m_iRefs(1) + { + } + + virtual ~CRefCountServiceDestruct() + { + } + + int GetRefCount() const + { + return m_iRefs; + } + + int DoAddRef() + { + return CRefThreading::Increment(&m_iRefs); + } + + int DoRelease() + { + int result = CRefThreading::Decrement(&m_iRefs); + if (result) + return result; + this->~CRefCountServiceDestruct(); + return 0; + } + +private: + int m_iRefs; +}; + + +typedef CRefCountServiceBase CRefCountServiceST; +typedef CRefCountServiceBase CRefCountServiceNoDeleteST; + +typedef CRefCountServiceBase CRefCountServiceMT; +typedef CRefCountServiceBase CRefCountServiceNoDeleteMT; + +typedef CRefCountServiceNoDeleteMT CRefCountServiceNoDelete; +typedef CRefCountServiceMT CRefCountService; + +template < class REFCOUNT_SERVICE = CRefCountService > +class NO_VTABLE CRefCounted : public REFCOUNT_SERVICE +{ +public: + virtual ~CRefCounted() {} + int AddRef() { return REFCOUNT_SERVICE::DoAddRef(); } + int Release() { return REFCOUNT_SERVICE::DoRelease(); } +}; + +template < class BASE1, class REFCOUNT_SERVICE = CRefCountService > +class NO_VTABLE CRefCounted1 : public BASE1, + public REFCOUNT_SERVICE +{ +public: + virtual ~CRefCounted1() {} + int AddRef() { return REFCOUNT_SERVICE::DoAddRef(); } + int Release() { return REFCOUNT_SERVICE::DoRelease(); } +}; + +template < class BASE1, class BASE2, class REFCOUNT_SERVICE = CRefCountService > +class NO_VTABLE CRefCounted2 : public BASE1, public BASE2, + public REFCOUNT_SERVICE +{ +public: + virtual ~CRefCounted2() {} + int AddRef() { return REFCOUNT_SERVICE::DoAddRef(); } + int Release() { return REFCOUNT_SERVICE::DoRelease(); } +}; + +template < class BASE1, class BASE2, class BASE3, class REFCOUNT_SERVICE = CRefCountService > +class NO_VTABLE CRefCounted3 : public BASE1, public BASE2, public BASE3, + public REFCOUNT_SERVICE +{ + virtual ~CRefCounted3() {} + int AddRef() { return REFCOUNT_SERVICE::DoAddRef(); } + int Release() { return REFCOUNT_SERVICE::DoRelease(); } +}; + +template < class BASE1, class BASE2, class BASE3, class BASE4, class REFCOUNT_SERVICE = CRefCountService > +class NO_VTABLE CRefCounted4 : public BASE1, public BASE2, public BASE3, public BASE4, + public REFCOUNT_SERVICE +{ +public: + virtual ~CRefCounted4() {} + int AddRef() { return REFCOUNT_SERVICE::DoAddRef(); } + int Release() { return REFCOUNT_SERVICE::DoRelease(); } +}; + +template < class BASE1, class BASE2, class BASE3, class BASE4, class BASE5, class REFCOUNT_SERVICE = CRefCountService > +class NO_VTABLE CRefCounted5 : public BASE1, public BASE2, public BASE3, public BASE4, public BASE5, + public REFCOUNT_SERVICE +{ +public: + virtual ~CRefCounted5() {} + int AddRef() { return REFCOUNT_SERVICE::DoAddRef(); } + int Release() { return REFCOUNT_SERVICE::DoRelease(); } +}; + +template +class CRefDebug : public BASE_REFCOUNTED +{ +public: +#ifdef _DEBUG + CRefDebug() + { + AssertMsg(this->GetRefCount() == 1, "Expected initial ref count of 1"); + DevMsg("%s:create 0x%x\n", (pszName) ? pszName : "", this); + } + + virtual ~CRefDebug() + { + AssertDevMsg(this->GetRefCount() == FINAL_REFS, "Object still referenced on destroy?"); + DevMsg("%s:destroy 0x%x\n", (pszName) ? pszName : "", this); + } + + int AddRef() + { + DevMsg("%s:(0x%x)->AddRef() --> %d\n", (pszName) ? pszName : "", this, this->GetRefCount() + 1); + return BASE_REFCOUNTED::AddRef(); + } + + int Release() + { + DevMsg("%s:(0x%x)->Release() --> %d\n", (pszName) ? pszName : "", this, this->GetRefCount() - 1); + Assert(this->GetRefCount() > 0); + return BASE_REFCOUNTED::Release(); + } +#endif +}; + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/sceneentity_shared.h b/SpyCustom/sdk/sceneentity_shared.h new file mode 100644 index 0000000..dc5e3d0 --- /dev/null +++ b/SpyCustom/sdk/sceneentity_shared.h @@ -0,0 +1,96 @@ +#ifndef SCENEENTITY_SHARED_H +#define SCENEENTITY_SHARED_H +#ifdef _WIN32 +#pragma once +#endif + +#if defined( CLIENT_DLL ) +#define CBaseFlex C_BaseFlex +#define CSceneEntity C_SceneEntity +#endif + +#include "iscenetokenprocessor.h" + +class CBaseFlex; + +class CChoreoEvent; +class CChoreoScene; +class CChoreoActor; +class CSceneEntity; + +class CSceneEventInfo +{ +public: + CSceneEventInfo() + : + m_pEvent(0), + m_pScene(0), + m_pActor(0), + m_bStarted(false), + m_iLayer(-1), + m_iPriority(0), + m_nSequence(0), + m_bIsGesture(false), + m_flWeight(0.0f), + m_hTarget(), + m_bIsMoving(false), + m_bHasArrived(false), + m_flInitialYaw(0.0f), + m_flTargetYaw(0.0f), + m_flFacingYaw(0.0f), + m_nType(0), + m_flNext(0.0f), + m_bClientSide(false) + { + } + + CChoreoEvent* m_pEvent; + + CChoreoScene* m_pScene; + + CChoreoActor* m_pActor; + + bool m_bStarted; + +public: + int m_iLayer; + int m_iPriority; + int m_nSequence; + bool m_bIsGesture; + float m_flWeight; + + EHANDLE m_hTarget; + bool m_bIsMoving; + bool m_bHasArrived; + float m_flInitialYaw; + float m_flTargetYaw; + float m_flFacingYaw; + + int m_nType; + float m_flNext; + + bool m_bClientSide; + + void InitWeight(CBaseFlex* pActor); + float UpdateWeight(CBaseFlex* pActor); +}; + +class CSceneTokenProcessor : public ISceneTokenProcessor +{ +public: + const char* CurrentToken(void); + bool GetToken(bool crossline); + bool TokenAvailable(void); + void Error(PRINTF_FORMAT_STRING const char* fmt, ...); + void SetBuffer(char* buffer); +private: + const char* m_pBuffer; + char m_szToken[1024]; +}; + +extern CSceneTokenProcessor g_TokenProcessor; + +void Scene_Printf(PRINTF_FORMAT_STRING const char* pFormat, ...); +extern ConVar scene_clientflex; + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/sdk_hud_chat.h b/SpyCustom/sdk/sdk_hud_chat.h new file mode 100644 index 0000000..cd9f6ac --- /dev/null +++ b/SpyCustom/sdk/sdk_hud_chat.h @@ -0,0 +1,79 @@ +#ifndef SDK_HUD_CHAT_H +#define SDK_HUD_CHAT_H +#ifdef _WIN32 +#pragma once +#endif + +#include "hud_basechat.h" + +#include "GetVFunc.hpp" + +class CHudChatLine : public CBaseHudChatLine +{ + DECLARE_CLASS_SIMPLE(CHudChatLine, CBaseHudChatLine); + +public: + CHudChatLine(vgui::Panel* parent, const char* panelName) : CBaseHudChatLine(parent, panelName) {} + + virtual void ApplySchemeSettings(vgui::IScheme* pScheme); + + void PerformFadeout(void); + + void MsgFunc_SayText(bf_read& msg); + +private: + CHudChatLine(const CHudChatLine&); +}; + +class CHudChatInputLine : public CBaseHudChatInputLine +{ + DECLARE_CLASS_SIMPLE(CHudChatInputLine, CBaseHudChatInputLine); + +public: + CHudChatInputLine(CBaseHudChat* parent, char const* panelName) : CBaseHudChatInputLine(parent, panelName) {} + + virtual void ApplySchemeSettings(vgui::IScheme* pScheme); +}; + +class CHudChat : public CBaseHudChat +{ + DECLARE_CLASS_SIMPLE(CHudChat, CBaseHudChat); + +public: + CHudChat(const char* pElementName); + + virtual void CreateChatInputLine(void); + virtual void CreateChatLines(void); + + virtual void Init(void); + virtual void Reset(void); + virtual void ApplySchemeSettings(vgui::IScheme* pScheme); + + void MsgFunc_SayText(bf_read& msg); + void MsgFunc_TextMsg(bf_read& msg); + + enum ChatFilters + { + CHAT_FILTER_NONE = 0, + CHAT_FILTER_JOINLEAVE = 0x000001, + CHAT_FILTER_NAMECHANGE = 0x000002, + CHAT_FILTER_PUBLICCHAT = 0x000004, + CHAT_FILTER_SERVERMSG = 0x000008, + CHAT_FILTER_TEAMCHANGE = 0x000010, + CHAT_FILTER_ACHIEVEMENT = 0x000020, + }; + + void ChatPrintf2(int iPlayerIndex, int iFilter, const char* fmt, ...) + { + char msg[1024]; + va_list args; + va_start(args, fmt); + vsnprintf(msg, 1024, fmt, args); + getvfunc(this, 27)(this, iPlayerIndex, iFilter, fmt); + va_end(args); + } + + int GetChatInputOffset(void); +}; + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/seemath.h b/SpyCustom/sdk/seemath.h new file mode 100644 index 0000000..118a2b0 --- /dev/null +++ b/SpyCustom/sdk/seemath.h @@ -0,0 +1,5073 @@ +#ifndef SSEMATH_H +#define SSEMATH_H + +#if defined( _X360 ) +#include +#elif defined ( _PS3 ) +#include +#include +#else +#include +#ifndef _LINUX +#include +#endif +#endif + +#ifndef SPU +#include "vector.h" +#include "mathlib.h" +#else +#include "mathlib/math_pfns.h" +#endif + +#include "fltx4.h" + +#ifdef _X360 +typedef __vector4 FLTX4; +#elif defined( _PS3 ) +typedef vec_float4 FLTX4; +#else +typedef const fltx4& FLTX4; +#endif + +struct ALIGN16 intx4 +{ + int32 m_i32[4]; + + inline int& operator[](int which) + { + return m_i32[which]; + } + + inline const int& operator[](int which) const + { + return m_i32[which]; + } + + inline int32* Base() { + return m_i32; + } + + inline const int32* Base() const + { + return m_i32; + } + + inline bool operator==(const intx4& other) const + { + return m_i32[0] == other.m_i32[0] && + m_i32[1] == other.m_i32[1] && + m_i32[2] == other.m_i32[2] && + m_i32[3] == other.m_i32[3]; + } +} ALIGN16_POST; + + +#if defined( _DEBUG ) && defined( _X360 ) +FORCEINLINE void TestVPUFlags() +{ + __vector4 a; + __asm + { + mfvscr a; + } + unsigned int* flags = (unsigned int*)&a; + unsigned int controlWord = flags[3]; + Assert(controlWord == 0); +} +#else +FORCEINLINE void TestVPUFlags() {} +#endif + + +#ifdef _X360 +#define Four_Zeros XMVectorZero() +#define Four_Ones XMVectorSplatOne() +extern const fltx4 Four_Twos; +extern const fltx4 Four_Threes; +extern const fltx4 Four_Fours; +extern const fltx4 Four_Point225s; +extern const fltx4 Four_PointFives; +extern const fltx4 Four_Thirds; +extern const fltx4 Four_TwoThirds; +extern const fltx4 Four_NegativeOnes; +extern const fltx4 Four_DegToRad; +#elif defined(SPU) +#define Four_Zeros spu_splats( 0.0f ) +#define Four_Ones spu_splats( 1.0f ) +#define Four_Twos spu_splats( 2.0f ) +#define Four_Threes spu_splats( 3.0f ) +#define Four_Fours spu_splats( 4.0f ) +#define Four_Point225s spu_splats( 0.225f ) +#define Four_PointFives spu_splats( 0.5f ) +#define Four_Thirds spu_splats( 0.33333333 ); +#define Four_TwoThirds spu_splats( 0.66666666 ); +#define Four_NegativeOnes spu_splats( -1.0f ) +#define Four_DegToRad spu_splats((float)(M_PI_F / 180.f)) +#else +extern const fltx4 Four_Zeros; +extern const fltx4 Four_Ones; +extern const fltx4 Four_Twos; +extern const fltx4 Four_Threes; +extern const fltx4 Four_Fours; +extern const fltx4 Four_Point225s; +extern const fltx4 Four_PointFives; +extern const fltx4 Four_Thirds; +extern const fltx4 Four_TwoThirds; +extern const fltx4 Four_NegativeOnes; +extern const fltx4 Four_DegToRad; +#endif +extern const fltx4 Four_Epsilons; +extern const fltx4 Four_2ToThe21s; +extern const fltx4 Four_2ToThe22s; +extern const fltx4 Four_2ToThe23s; +extern const fltx4 Four_2ToThe24s; +extern const fltx4 Four_Origin; +extern const fltx4 Four_FLT_MAX; +extern const fltx4 Four_Negative_FLT_MAX; +extern const fltx4 g_SIMD_0123; + + +extern const fltx4 Four_LinearToGammaCoefficients_A; +extern const fltx4 Four_LinearToGammaCoefficients_B; +extern const fltx4 Four_LinearToGammaCoefficients_C; +extern const fltx4 Four_LinearToGammaCoefficients_D; +extern const fltx4 Four_LinearToGammaCoefficients_E; + +extern const fltx4 Four_GammaToLinearCoefficients_A; +extern const fltx4 Four_GammaToLinearCoefficients_B; +extern const fltx4 Four_GammaToLinearCoefficients_C; +extern const fltx4 Four_GammaToLinearCoefficients_D; + + +#ifndef ALIGN16_POST +#define ALIGN16_POST +#endif +extern const ALIGN16 int32 g_SIMD_clear_signmask[] ALIGN16_POST; +extern const ALIGN16 int32 g_SIMD_signmask[] ALIGN16_POST; +extern const ALIGN16 int32 g_SIMD_lsbmask[] ALIGN16_POST; +extern const ALIGN16 int32 g_SIMD_clear_wmask[] ALIGN16_POST; +extern const ALIGN16 int32 g_SIMD_ComponentMask[4][4] ALIGN16_POST; +extern const ALIGN16 int32 g_SIMD_AllOnesMask[] ALIGN16_POST; +extern const fltx4 g_SIMD_Identity[4]; +extern const ALIGN16 int32 g_SIMD_Low16BitsMask[] ALIGN16_POST; + +extern const int32 ALIGN16 g_SIMD_SkipTailMask[4][4] ALIGN16_POST; + +extern const int32 ALIGN16 g_SIMD_EveryOtherMask[]; +#ifdef PLATFORM_PPC +#if defined(_X360) +#define PREFETCH360(address, offset) __dcbt(offset,address) +#elif defined(_PS3) +#define PREFETCH360(address, offset) __dcbt( reinterpret_cast< const char * >(address) + offset ) +#else +#error Prefetch not defined for this platform! +#endif +#else +#define PREFETCH360(x,y) +#endif + +template +inline T* AlignPointer(void* ptr) +{ +#if defined( __clang__ ) + uintp temp = (uintp)ptr; +#else + unsigned temp = ptr; +#endif + temp = ALIGN_VALUE(temp, sizeof(T)); + return (T*)temp; +} + +#ifdef _PS3 + +#define _VEC_CLEAR_SIGNMASK (__vector unsigned int) {0x7fffffff,0x7fffffff,0x7fffffff,0x7fffffff} +#define _VEC_SIGNMASK (__vector unsigned int) { 0x80000000, 0x80000000, 0x80000000, 0x80000000 } +#define _VEC_LSBMASK (__vector unsigned int) { 0xfffffffe, 0xfffffffe, 0xfffffffe, 0xfffffffe } +#define _VEC_CLEAR_WMASK (__vector unsigned int) {0xffffffff, 0xffffffff, 0xffffffff, 0} +#define _VEC_COMPONENT_MASK_0 (__vector unsigned int) {0xffffffff, 0, 0, 0} +#define _VEC_COMPONENT_MASK_1 (__vector unsigned int) {0, 0xffffffff, 0, 0} +#define _VEC_COMPONENT_MASK_2 (__vector unsigned int) {0, 0, 0xffffffff, 0} +#define _VEC_COMPONENT_MASK_3 (__vector unsigned int) {0, 0, 0, 0xffffffff} + +#define _VEC_SWIZZLE_WZYX (__vector unsigned char) { 0x0c,0x0d,0x0e,0x0f, 0x08,0x09,0x0a,0x0b, 0x04,0x05,0x06,0x07, 0x00,0x01,0x02,0x03 } +#define _VEC_SWIZZLE_ZWXY (__vector unsigned char) { 0x08,0x09,0x0a,0x0b, 0x0c,0x0d,0x0e,0x0f, 0x00,0x01,0x02,0x03, 0x04,0x05,0x06,0x07 } +#define _VEC_SWIZZLE_YXWZ (__vector unsigned char) { 0x04,0x05,0x06,0x07, 0x00,0x01,0x02,0x03, 0x0c,0x0d,0x0e,0x0f, 0x08,0x09,0x0a,0x0b } + +#define _VEC_ZERO (__vector unsigned int) {0,0,0,0} + +#define _VEC_FLTMAX (__vector float) {FLT_MAX,FLT_MAX,FLT_MAX,FLT_MAX} +#define _VEC_FLTMIN (__vector float) {FLT_MIN,FLT_MIN,FLT_MIN,FLT_MIN} + +#define _VEC_ORIGIN (__vector unsigned int) { 0x00000000, 0x00000000, 0x00000000, 0xffffffff } + +#endif + +#if USE_STDC_FOR_SIMD + +FORCEINLINE float SubFloat(const fltx4& a, int idx) +{ + return a.m128_f32[idx]; +} + +FORCEINLINE float& SubFloat(fltx4& a, int idx) +{ + return a.m128_f32[idx]; +} + +FORCEINLINE uint32 SubInt(const fltx4& a, int idx) +{ + return a.m128_u32[idx]; +} + +FORCEINLINE uint32& SubInt(fltx4& a, int idx) +{ + return a.m128_u32[idx]; +} + +FORCEINLINE fltx4 LoadZeroSIMD(void) +{ + return Four_Zeros; +} + +FORCEINLINE fltx4 LoadOneSIMD(void) +{ + return Four_Ones; +} + +FORCEINLINE fltx4 SplatXSIMD(const fltx4& a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = SubFloat(a, 0); + SubFloat(retVal, 1) = SubFloat(a, 0); + SubFloat(retVal, 2) = SubFloat(a, 0); + SubFloat(retVal, 3) = SubFloat(a, 0); + return retVal; +} + +FORCEINLINE fltx4 SplatYSIMD(fltx4 a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = SubFloat(a, 1); + SubFloat(retVal, 1) = SubFloat(a, 1); + SubFloat(retVal, 2) = SubFloat(a, 1); + SubFloat(retVal, 3) = SubFloat(a, 1); + return retVal; +} + +FORCEINLINE fltx4 SplatZSIMD(fltx4 a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = SubFloat(a, 2); + SubFloat(retVal, 1) = SubFloat(a, 2); + SubFloat(retVal, 2) = SubFloat(a, 2); + SubFloat(retVal, 3) = SubFloat(a, 2); + return retVal; +} + +FORCEINLINE fltx4 SplatWSIMD(fltx4 a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = SubFloat(a, 3); + SubFloat(retVal, 1) = SubFloat(a, 3); + SubFloat(retVal, 2) = SubFloat(a, 3); + SubFloat(retVal, 3) = SubFloat(a, 3); + return retVal; +} + +FORCEINLINE fltx4 SetXSIMD(const fltx4& a, const fltx4& x) +{ + fltx4 result = a; + SubFloat(result, 0) = SubFloat(x, 0); + return result; +} + +FORCEINLINE fltx4 SetYSIMD(const fltx4& a, const fltx4& y) +{ + fltx4 result = a; + SubFloat(result, 1) = SubFloat(y, 1); + return result; +} + +FORCEINLINE fltx4 SetZSIMD(const fltx4& a, const fltx4& z) +{ + fltx4 result = a; + SubFloat(result, 2) = SubFloat(z, 2); + return result; +} + +FORCEINLINE fltx4 SetWSIMD(const fltx4& a, const fltx4& w) +{ + fltx4 result = a; + SubFloat(result, 3) = SubFloat(w, 3); + return result; +} + +FORCEINLINE fltx4 SetComponentSIMD(const fltx4& a, int nComponent, float flValue) +{ + fltx4 result = a; + SubFloat(result, nComponent) = flValue; + return result; +} + + +FORCEINLINE fltx4 RotateLeft(const fltx4& a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = SubFloat(a, 1); + SubFloat(retVal, 1) = SubFloat(a, 2); + SubFloat(retVal, 2) = SubFloat(a, 3); + SubFloat(retVal, 3) = SubFloat(a, 0); + return retVal; +} + +FORCEINLINE fltx4 RotateLeft2(const fltx4& a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = SubFloat(a, 2); + SubFloat(retVal, 1) = SubFloat(a, 3); + SubFloat(retVal, 2) = SubFloat(a, 0); + SubFloat(retVal, 3) = SubFloat(a, 1); + return retVal; +} + +#define BINOP(op) \ + fltx4 retVal; \ + SubFloat( retVal, 0 ) = ( SubFloat( a, 0 ) op SubFloat( b, 0 ) ); \ + SubFloat( retVal, 1 ) = ( SubFloat( a, 1 ) op SubFloat( b, 1 ) ); \ + SubFloat( retVal, 2 ) = ( SubFloat( a, 2 ) op SubFloat( b, 2 ) ); \ + SubFloat( retVal, 3 ) = ( SubFloat( a, 3 ) op SubFloat( b, 3 ) ); \ + return retVal; + +#define IBINOP(op) \ + fltx4 retVal; \ + SubInt( retVal, 0 ) = ( SubInt( a, 0 ) op SubInt ( b, 0 ) ); \ + SubInt( retVal, 1 ) = ( SubInt( a, 1 ) op SubInt ( b, 1 ) ); \ + SubInt( retVal, 2 ) = ( SubInt( a, 2 ) op SubInt ( b, 2 ) ); \ + SubInt( retVal, 3 ) = ( SubInt( a, 3 ) op SubInt ( b, 3 ) ); \ + return retVal; + +FORCEINLINE fltx4 AddSIMD(const fltx4& a, const fltx4& b) +{ + BINOP(+); +} + +FORCEINLINE fltx4 SubSIMD(const fltx4& a, const fltx4& b) +{ + BINOP(-); +}; + +FORCEINLINE fltx4 MulSIMD(const fltx4& a, const fltx4& b) +{ + BINOP(*); +} + +FORCEINLINE fltx4 DivSIMD(const fltx4& a, const fltx4& b) +{ + BINOP(/ ); +} + +FORCEINLINE fltx4 DivEstSIMD(const fltx4& a, const fltx4& b) +{ + BINOP(/ ); +} + +FORCEINLINE fltx4 MaddSIMD(const fltx4& a, const fltx4& b, const fltx4& c) +{ + return AddSIMD(MulSIMD(a, b), c); +} + +FORCEINLINE fltx4 MsubSIMD(const fltx4& a, const fltx4& b, const fltx4& c) +{ + return SubSIMD(c, MulSIMD(a, b)); +}; + + +FORCEINLINE fltx4 SinSIMD(const fltx4& radians) +{ + fltx4 result; + SubFloat(result, 0) = sin(SubFloat(radians, 0)); + SubFloat(result, 1) = sin(SubFloat(radians, 1)); + SubFloat(result, 2) = sin(SubFloat(radians, 2)); + SubFloat(result, 3) = sin(SubFloat(radians, 3)); + return result; +} + +FORCEINLINE void SinCos3SIMD(fltx4& sine, fltx4& cosine, const fltx4& radians) +{ + SinCos(SubFloat(radians, 0), &SubFloat(sine, 0), &SubFloat(cosine, 0)); + SinCos(SubFloat(radians, 1), &SubFloat(sine, 1), &SubFloat(cosine, 1)); + SinCos(SubFloat(radians, 2), &SubFloat(sine, 2), &SubFloat(cosine, 2)); +} + +FORCEINLINE void SinCosSIMD(fltx4& sine, fltx4& cosine, const fltx4& radians) +{ + SinCos(SubFloat(radians, 0), &SubFloat(sine, 0), &SubFloat(cosine, 0)); + SinCos(SubFloat(radians, 1), &SubFloat(sine, 1), &SubFloat(cosine, 1)); + SinCos(SubFloat(radians, 2), &SubFloat(sine, 2), &SubFloat(cosine, 2)); + SinCos(SubFloat(radians, 3), &SubFloat(sine, 3), &SubFloat(cosine, 3)); +} + +FORCEINLINE fltx4 ArcSinSIMD(const fltx4& sine) +{ + fltx4 result; + SubFloat(result, 0) = asin(SubFloat(sine, 0)); + SubFloat(result, 1) = asin(SubFloat(sine, 1)); + SubFloat(result, 2) = asin(SubFloat(sine, 2)); + SubFloat(result, 3) = asin(SubFloat(sine, 3)); + return result; +} + +FORCEINLINE fltx4 ArcCosSIMD(const fltx4& cs) +{ + fltx4 result; + SubFloat(result, 0) = acos(SubFloat(cs, 0)); + SubFloat(result, 1) = acos(SubFloat(cs, 1)); + SubFloat(result, 2) = acos(SubFloat(cs, 2)); + SubFloat(result, 3) = acos(SubFloat(cs, 3)); + return result; +} + +FORCEINLINE fltx4 ArcTan2SIMD(const fltx4& a, const fltx4& b) +{ + fltx4 result; + SubFloat(result, 0) = atan2(SubFloat(a, 0), SubFloat(b, 0)); + SubFloat(result, 1) = atan2(SubFloat(a, 1), SubFloat(b, 1)); + SubFloat(result, 2) = atan2(SubFloat(a, 2), SubFloat(b, 2)); + SubFloat(result, 3) = atan2(SubFloat(a, 3), SubFloat(b, 3)); + return result; +} + +FORCEINLINE fltx4 MaxSIMD(const fltx4& a, const fltx4& b) +{ + fltx4 retVal; + SubFloat(retVal, 0) = max(SubFloat(a, 0), SubFloat(b, 0)); + SubFloat(retVal, 1) = max(SubFloat(a, 1), SubFloat(b, 1)); + SubFloat(retVal, 2) = max(SubFloat(a, 2), SubFloat(b, 2)); + SubFloat(retVal, 3) = max(SubFloat(a, 3), SubFloat(b, 3)); + return retVal; +} + +FORCEINLINE fltx4 MinSIMD(const fltx4& a, const fltx4& b) +{ + fltx4 retVal; + SubFloat(retVal, 0) = min(SubFloat(a, 0), SubFloat(b, 0)); + SubFloat(retVal, 1) = min(SubFloat(a, 1), SubFloat(b, 1)); + SubFloat(retVal, 2) = min(SubFloat(a, 2), SubFloat(b, 2)); + SubFloat(retVal, 3) = min(SubFloat(a, 3), SubFloat(b, 3)); + return retVal; +} + +FORCEINLINE fltx4 AndSIMD(const fltx4& a, const fltx4& b) +{ + IBINOP(&); +} + +FORCEINLINE fltx4 AndNotSIMD(const fltx4& a, const fltx4& b) +{ + fltx4 retVal; + SubInt(retVal, 0) = ~SubInt(a, 0) & SubInt(b, 0); + SubInt(retVal, 1) = ~SubInt(a, 1) & SubInt(b, 1); + SubInt(retVal, 2) = ~SubInt(a, 2) & SubInt(b, 2); + SubInt(retVal, 3) = ~SubInt(a, 3) & SubInt(b, 3); + return retVal; +} + +FORCEINLINE fltx4 XorSIMD(const fltx4& a, const fltx4& b) +{ + IBINOP(^); +} + +FORCEINLINE fltx4 OrSIMD(const fltx4& a, const fltx4& b) +{ + IBINOP(| ); +} + +FORCEINLINE fltx4 NegSIMD(const fltx4& a) +{ + fltx4 retval; + SubFloat(retval, 0) = -SubFloat(a, 0); + SubFloat(retval, 1) = -SubFloat(a, 1); + SubFloat(retval, 2) = -SubFloat(a, 2); + SubFloat(retval, 3) = -SubFloat(a, 3); + + return retval; +} + +FORCEINLINE bool IsAllZeros(const fltx4& a) +{ + return (SubFloat(a, 0) == 0.0) && + (SubFloat(a, 1) == 0.0) && + (SubFloat(a, 2) == 0.0) && + (SubFloat(a, 3) == 0.0); +} + + +FORCEINLINE bool IsAllGreaterThan(const fltx4& a, const fltx4& b) +{ + return SubFloat(a, 0) > SubFloat(b, 0) && + SubFloat(a, 1) > SubFloat(b, 1) && + SubFloat(a, 2) > SubFloat(b, 2) && + SubFloat(a, 3) > SubFloat(b, 3); +} + +FORCEINLINE bool IsAllGreaterThanOrEq(const fltx4& a, const fltx4& b) +{ + return SubFloat(a, 0) >= SubFloat(b, 0) && + SubFloat(a, 1) >= SubFloat(b, 1) && + SubFloat(a, 2) >= SubFloat(b, 2) && + SubFloat(a, 3) >= SubFloat(b, 3); +} + +FORCEINLINE bool IsAllEqual(const fltx4& a, const fltx4& b) +{ + return SubFloat(a, 0) == SubFloat(b, 0) && + SubFloat(a, 1) == SubFloat(b, 1) && + SubFloat(a, 2) == SubFloat(b, 2) && + SubFloat(a, 3) == SubFloat(b, 3); +} + +FORCEINLINE bool IsAnyEqual(const fltx4& a, const fltx4& b) +{ + return SubFloat(a, 0) == SubFloat(b, 0) || + SubFloat(a, 1) == SubFloat(b, 1) || + SubFloat(a, 2) == SubFloat(b, 2) || + SubFloat(a, 3) == SubFloat(b, 3); +} + +FORCEINLINE int TestSignSIMD(const fltx4& a) +{ + int nRet = 0; + + nRet |= (SubInt(a, 0) & 0x80000000) >> 31; + nRet |= (SubInt(a, 1) & 0x80000000) >> 30; + nRet |= (SubInt(a, 2) & 0x80000000) >> 29; + nRet |= (SubInt(a, 3) & 0x80000000) >> 28; + + return nRet; +} + +FORCEINLINE bool IsAnyNegative(const fltx4& a) +{ + return (0 != TestSignSIMD(a)); +} + +FORCEINLINE bool IsAnyTrue(const fltx4& a) +{ + return (0 != TestSignSIMD(a)); +} + +FORCEINLINE fltx4 CmpEqSIMD(const fltx4& a, const fltx4& b) +{ + fltx4 retVal; + SubInt(retVal, 0) = (SubFloat(a, 0) == SubFloat(b, 0)) ? ~0 : 0; + SubInt(retVal, 1) = (SubFloat(a, 1) == SubFloat(b, 1)) ? ~0 : 0; + SubInt(retVal, 2) = (SubFloat(a, 2) == SubFloat(b, 2)) ? ~0 : 0; + SubInt(retVal, 3) = (SubFloat(a, 3) == SubFloat(b, 3)) ? ~0 : 0; + return retVal; +} + +FORCEINLINE fltx4 CmpGtSIMD(const fltx4& a, const fltx4& b) +{ + fltx4 retVal; + SubInt(retVal, 0) = (SubFloat(a, 0) > SubFloat(b, 0)) ? ~0 : 0; + SubInt(retVal, 1) = (SubFloat(a, 1) > SubFloat(b, 1)) ? ~0 : 0; + SubInt(retVal, 2) = (SubFloat(a, 2) > SubFloat(b, 2)) ? ~0 : 0; + SubInt(retVal, 3) = (SubFloat(a, 3) > SubFloat(b, 3)) ? ~0 : 0; + return retVal; +} + +FORCEINLINE fltx4 CmpGeSIMD(const fltx4& a, const fltx4& b) +{ + fltx4 retVal; + SubInt(retVal, 0) = (SubFloat(a, 0) >= SubFloat(b, 0)) ? ~0 : 0; + SubInt(retVal, 1) = (SubFloat(a, 1) >= SubFloat(b, 1)) ? ~0 : 0; + SubInt(retVal, 2) = (SubFloat(a, 2) >= SubFloat(b, 2)) ? ~0 : 0; + SubInt(retVal, 3) = (SubFloat(a, 3) >= SubFloat(b, 3)) ? ~0 : 0; + return retVal; +} + +FORCEINLINE fltx4 CmpLtSIMD(const fltx4& a, const fltx4& b) +{ + fltx4 retVal; + SubInt(retVal, 0) = (SubFloat(a, 0) < SubFloat(b, 0)) ? ~0 : 0; + SubInt(retVal, 1) = (SubFloat(a, 1) < SubFloat(b, 1)) ? ~0 : 0; + SubInt(retVal, 2) = (SubFloat(a, 2) < SubFloat(b, 2)) ? ~0 : 0; + SubInt(retVal, 3) = (SubFloat(a, 3) < SubFloat(b, 3)) ? ~0 : 0; + return retVal; +} + +FORCEINLINE fltx4 CmpLeSIMD(const fltx4& a, const fltx4& b) +{ + fltx4 retVal; + SubInt(retVal, 0) = (SubFloat(a, 0) <= SubFloat(b, 0)) ? ~0 : 0; + SubInt(retVal, 1) = (SubFloat(a, 1) <= SubFloat(b, 1)) ? ~0 : 0; + SubInt(retVal, 2) = (SubFloat(a, 2) <= SubFloat(b, 2)) ? ~0 : 0; + SubInt(retVal, 3) = (SubFloat(a, 3) <= SubFloat(b, 3)) ? ~0 : 0; + return retVal; +} + +FORCEINLINE fltx4 CmpInBoundsSIMD(const fltx4& a, const fltx4& b) +{ + fltx4 retVal; + SubInt(retVal, 0) = (SubFloat(a, 0) <= SubFloat(b, 0) && SubFloat(a, 0) >= -SubFloat(b, 0)) ? ~0 : 0; + SubInt(retVal, 1) = (SubFloat(a, 1) <= SubFloat(b, 1) && SubFloat(a, 1) >= -SubFloat(b, 1)) ? ~0 : 0; + SubInt(retVal, 2) = (SubFloat(a, 2) <= SubFloat(b, 2) && SubFloat(a, 2) >= -SubFloat(b, 2)) ? ~0 : 0; + SubInt(retVal, 3) = (SubFloat(a, 3) <= SubFloat(b, 3) && SubFloat(a, 3) >= -SubFloat(b, 3)) ? ~0 : 0; + return retVal; +} + + +FORCEINLINE fltx4 MaskedAssign(const fltx4& ReplacementMask, const fltx4& NewValue, const fltx4& OldValue) +{ + return OrSIMD( + AndSIMD(ReplacementMask, NewValue), + AndNotSIMD(ReplacementMask, OldValue)); +} + +FORCEINLINE fltx4 ReplicateX4(float flValue) +{ + fltx4 retVal; + SubFloat(retVal, 0) = flValue; + SubFloat(retVal, 1) = flValue; + SubFloat(retVal, 2) = flValue; + SubFloat(retVal, 3) = flValue; + return retVal; +} + +FORCEINLINE fltx4 ReplicateIX4(int nValue) +{ + fltx4 retVal; + SubInt(retVal, 0) = nValue; + SubInt(retVal, 1) = nValue; + SubInt(retVal, 2) = nValue; + SubInt(retVal, 3) = nValue; + return retVal; + +} + +FORCEINLINE fltx4 CeilSIMD(const fltx4& a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = ceil(SubFloat(a, 0)); + SubFloat(retVal, 1) = ceil(SubFloat(a, 1)); + SubFloat(retVal, 2) = ceil(SubFloat(a, 2)); + SubFloat(retVal, 3) = ceil(SubFloat(a, 3)); + return retVal; + +} + +FORCEINLINE fltx4 FloorSIMD(const fltx4& a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = floor(SubFloat(a, 0)); + SubFloat(retVal, 1) = floor(SubFloat(a, 1)); + SubFloat(retVal, 2) = floor(SubFloat(a, 2)); + SubFloat(retVal, 3) = floor(SubFloat(a, 3)); + return retVal; + +} + +FORCEINLINE fltx4 SqrtEstSIMD(const fltx4& a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = sqrt(SubFloat(a, 0)); + SubFloat(retVal, 1) = sqrt(SubFloat(a, 1)); + SubFloat(retVal, 2) = sqrt(SubFloat(a, 2)); + SubFloat(retVal, 3) = sqrt(SubFloat(a, 3)); + return retVal; +} + +FORCEINLINE fltx4 SqrtSIMD(const fltx4& a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = sqrt(SubFloat(a, 0)); + SubFloat(retVal, 1) = sqrt(SubFloat(a, 1)); + SubFloat(retVal, 2) = sqrt(SubFloat(a, 2)); + SubFloat(retVal, 3) = sqrt(SubFloat(a, 3)); + return retVal; +} + +FORCEINLINE fltx4 ReciprocalSqrtEstSIMD(const fltx4& a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = 1.0 / sqrt(SubFloat(a, 0)); + SubFloat(retVal, 1) = 1.0 / sqrt(SubFloat(a, 1)); + SubFloat(retVal, 2) = 1.0 / sqrt(SubFloat(a, 2)); + SubFloat(retVal, 3) = 1.0 / sqrt(SubFloat(a, 3)); + return retVal; +} + +FORCEINLINE fltx4 ReciprocalSqrtEstSaturateSIMD(const fltx4& a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = 1.0 / sqrt(SubFloat(a, 0) != 0.0f ? SubFloat(a, 0) : FLT_EPSILON); + SubFloat(retVal, 1) = 1.0 / sqrt(SubFloat(a, 1) != 0.0f ? SubFloat(a, 1) : FLT_EPSILON); + SubFloat(retVal, 2) = 1.0 / sqrt(SubFloat(a, 2) != 0.0f ? SubFloat(a, 2) : FLT_EPSILON); + SubFloat(retVal, 3) = 1.0 / sqrt(SubFloat(a, 3) != 0.0f ? SubFloat(a, 3) : FLT_EPSILON); + return retVal; +} + +FORCEINLINE fltx4 ReciprocalSqrtSIMD(const fltx4& a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = 1.0 / sqrt(SubFloat(a, 0)); + SubFloat(retVal, 1) = 1.0 / sqrt(SubFloat(a, 1)); + SubFloat(retVal, 2) = 1.0 / sqrt(SubFloat(a, 2)); + SubFloat(retVal, 3) = 1.0 / sqrt(SubFloat(a, 3)); + return retVal; +} + +FORCEINLINE fltx4 ReciprocalEstSIMD(const fltx4& a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = 1.0 / SubFloat(a, 0); + SubFloat(retVal, 1) = 1.0 / SubFloat(a, 1); + SubFloat(retVal, 2) = 1.0 / SubFloat(a, 2); + SubFloat(retVal, 3) = 1.0 / SubFloat(a, 3); + return retVal; +} + +FORCEINLINE fltx4 ReciprocalSIMD(const fltx4& a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = 1.0 / SubFloat(a, 0); + SubFloat(retVal, 1) = 1.0 / SubFloat(a, 1); + SubFloat(retVal, 2) = 1.0 / SubFloat(a, 2); + SubFloat(retVal, 3) = 1.0 / SubFloat(a, 3); + return retVal; +} + +FORCEINLINE fltx4 ReciprocalEstSaturateSIMD(const fltx4& a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = 1.0 / (SubFloat(a, 0) == 0.0f ? FLT_EPSILON : SubFloat(a, 0)); + SubFloat(retVal, 1) = 1.0 / (SubFloat(a, 1) == 0.0f ? FLT_EPSILON : SubFloat(a, 1)); + SubFloat(retVal, 2) = 1.0 / (SubFloat(a, 2) == 0.0f ? FLT_EPSILON : SubFloat(a, 2)); + SubFloat(retVal, 3) = 1.0 / (SubFloat(a, 3) == 0.0f ? FLT_EPSILON : SubFloat(a, 3)); + return retVal; +} + +FORCEINLINE fltx4 ReciprocalSaturateSIMD(const fltx4& a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = 1.0 / (SubFloat(a, 0) == 0.0f ? FLT_EPSILON : SubFloat(a, 0)); + SubFloat(retVal, 1) = 1.0 / (SubFloat(a, 1) == 0.0f ? FLT_EPSILON : SubFloat(a, 1)); + SubFloat(retVal, 2) = 1.0 / (SubFloat(a, 2) == 0.0f ? FLT_EPSILON : SubFloat(a, 2)); + SubFloat(retVal, 3) = 1.0 / (SubFloat(a, 3) == 0.0f ? FLT_EPSILON : SubFloat(a, 3)); + return retVal; +} + +FORCEINLINE fltx4 ExpSIMD(const fltx4& toPower) +{ + fltx4 retVal; + SubFloat(retVal, 0) = powf(2, SubFloat(toPower, 0)); + SubFloat(retVal, 1) = powf(2, SubFloat(toPower, 1)); + SubFloat(retVal, 2) = powf(2, SubFloat(toPower, 2)); + SubFloat(retVal, 3) = powf(2, SubFloat(toPower, 3)); + + return retVal; +} + +FORCEINLINE fltx4 Dot3SIMD(const fltx4& a, const fltx4& b) +{ + float flDot = SubFloat(a, 0) * SubFloat(b, 0) + + SubFloat(a, 1) * SubFloat(b, 1) + + SubFloat(a, 2) * SubFloat(b, 2); + return ReplicateX4(flDot); +} + +FORCEINLINE fltx4 Dot4SIMD(const fltx4& a, const fltx4& b) +{ + float flDot = SubFloat(a, 0) * SubFloat(b, 0) + + SubFloat(a, 1) * SubFloat(b, 1) + + SubFloat(a, 2) * SubFloat(b, 2) + + SubFloat(a, 3) * SubFloat(b, 3); + return ReplicateX4(flDot); +} + +FORCEINLINE fltx4 ClampVectorSIMD(FLTX4 in, FLTX4 min, FLTX4 max) +{ + return MaxSIMD(min, MinSIMD(max, in)); +} + +FORCEINLINE fltx4 SetWToZeroSIMD(const fltx4& a) +{ + fltx4 retval; + retval = a; + SubFloat(retval, 0) = 0; + return retval; +} + +FORCEINLINE fltx4 LoadUnalignedSIMD(const void* pSIMD) +{ + return *(reinterpret_cast (pSIMD)); +} + +FORCEINLINE fltx4 LoadUnaligned3SIMD(const void* pSIMD) +{ + return *(reinterpret_cast (pSIMD)); +} + +FORCEINLINE fltx4 LoadUnalignedFloatSIMD(const float* pFlt) +{ + fltx4 retval; + SubFloat(retval, 0) = *pFlt; + return retval; +} + +FORCEINLINE fltx4 LoadAlignedSIMD(const void* pSIMD) +{ + return *(reinterpret_cast (pSIMD)); +} + +FORCEINLINE fltx4 LoadAlignedSIMD(const VectorAligned& pSIMD) +{ + fltx4 retval = LoadAlignedSIMD(pSIMD.Base()); + SubInt(retval, 3) = 0; + return retval; +} + + +FORCEINLINE fltx4 LoadGatherSIMD(const float& x, const float& y, const float& z, const float& w) +{ + fltx4 retval = { x, y, z, w }; + return retval; +} + +FORCEINLINE void StoreAlignedSIMD(float* pSIMD, const fltx4& a) +{ + *(reinterpret_cast (pSIMD)) = a; +} + +FORCEINLINE void StoreUnalignedSIMD(float* pSIMD, const fltx4& a) +{ + *(reinterpret_cast (pSIMD)) = a; +} + +FORCEINLINE void StoreUnalignedFloat(float* pSingleFloat, const fltx4& a) +{ + *pSingleFloat = SubFloat(a, 0); +} + +FORCEINLINE void StoreUnaligned3SIMD(float* pSIMD, const fltx4& a) +{ + *pSIMD = SubFloat(a, 0); + *(pSIMD + 1) = SubFloat(a, 1); + *(pSIMD + 2) = SubFloat(a, 2); +} + + +FORCEINLINE void StoreAligned3SIMD(VectorAligned* RESTRICT pSIMD, const fltx4& a) +{ + StoreAlignedSIMD(pSIMD->Base(), a); +} + +FORCEINLINE void StoreFourUnalignedVector3SIMD(fltx4 a, fltx4 b, fltx4 c, FLTX4 d, + Vector* const pDestination) +{ + StoreUnaligned3SIMD(pDestination->Base(), a); + StoreUnaligned3SIMD((pDestination + 1)->Base(), b); + StoreUnaligned3SIMD((pDestination + 2)->Base(), c); + StoreUnaligned3SIMD((pDestination + 3)->Base(), d); +} + +FORCEINLINE void StoreFourAlignedVector3SIMD(fltx4 a, fltx4 b, fltx4 c, FLTX4 d, + Vector* const pDestination) +{ + StoreUnaligned3SIMD(pDestination->Base(), a); + StoreUnaligned3SIMD((pDestination + 1)->Base(), b); + StoreUnaligned3SIMD((pDestination + 2)->Base(), c); + StoreUnaligned3SIMD((pDestination + 3)->Base(), d); +} + + +FORCEINLINE void TransposeSIMD(fltx4& x, fltx4& y, fltx4& z, fltx4& w) +{ +#define SWAP_FLOATS( _a_, _ia_, _b_, _ib_ ) { float tmp = SubFloat( _a_, _ia_ ); SubFloat( _a_, _ia_ ) = SubFloat( _b_, _ib_ ); SubFloat( _b_, _ib_ ) = tmp; } + SWAP_FLOATS(x, 1, y, 0); + SWAP_FLOATS(x, 2, z, 0); + SWAP_FLOATS(x, 3, w, 0); + SWAP_FLOATS(y, 2, z, 1); + SWAP_FLOATS(y, 3, w, 1); + SWAP_FLOATS(z, 3, w, 2); +} + +FORCEINLINE fltx4 FindLowestSIMD3(const fltx4& a) +{ + float lowest = min(min(SubFloat(a, 0), SubFloat(a, 1)), SubFloat(a, 2)); + return ReplicateX4(lowest); +} + +FORCEINLINE fltx4 FindHighestSIMD3(const fltx4& a) +{ + float highest = max(max(SubFloat(a, 0), SubFloat(a, 1)), SubFloat(a, 2)); + return ReplicateX4(highest); +} + +FORCEINLINE void ConvertStoreAsIntsSIMD(intx4* RESTRICT pDest, const fltx4& vSrc) +{ + (*pDest)[0] = SubFloat(vSrc, 0); + (*pDest)[1] = SubFloat(vSrc, 1); + (*pDest)[2] = SubFloat(vSrc, 2); + (*pDest)[3] = SubFloat(vSrc, 3); +} + +FORCEINLINE fltx4 IntSetImmediateSIMD(int nValue) +{ + fltx4 retval; + SubInt(retval, 0) = SubInt(retval, 1) = SubInt(retval, 2) = SubInt(retval, 3) = nValue; + return retval; +} + +FORCEINLINE i32x4 LoadAlignedIntSIMD(const void* RESTRICT pSIMD) +{ + return *(reinterpret_cast (pSIMD)); +} + +FORCEINLINE i32x4 LoadUnalignedIntSIMD(const void* RESTRICT pSIMD) +{ + return *(reinterpret_cast (pSIMD)); +} + +FORCEINLINE void StoreAlignedIntSIMD(int32* pSIMD, const fltx4& a) +{ + *(reinterpret_cast (pSIMD)) = a; +} + +FORCEINLINE void StoreAlignedIntSIMD(intx4& pSIMD, const fltx4& a) +{ + *(reinterpret_cast (pSIMD.Base())) = a; +} + +FORCEINLINE void StoreUnalignedIntSIMD(int32* pSIMD, const fltx4& a) +{ + *(reinterpret_cast (pSIMD)) = a; +} + +FORCEINLINE fltx4 LoadAndConvertUint16SIMD(const uint16* pInts) +{ + fltx4 retval; + SubFloat(retval, 0) = pInts[0]; + SubFloat(retval, 1) = pInts[1]; + SubFloat(retval, 2) = pInts[2]; + SubFloat(retval, 3) = pInts[3]; +} + + +FORCEINLINE fltx4 UnsignedIntConvertToFltSIMD(const u32x4& vSrcA) +{ + Assert(0); + fltx4 retval; + SubFloat(retval, 0) = ((float)SubInt(vSrcA, 0)); + SubFloat(retval, 1) = ((float)SubInt(vSrcA, 1)); + SubFloat(retval, 2) = ((float)SubInt(vSrcA, 2)); + SubFloat(retval, 3) = ((float)SubInt(vSrcA, 3)); + return retval; +} + + +#if 0 +FORCEINLINE fltx4 SignedIntConvertToFltSIMD(const i32x4& vSrcA) +{ + fltx4 retval; + SubFloat(retval, 0) = ((float)(reinterpret_cast(&vSrcA.m128_s32[0]))); + SubFloat(retval, 1) = ((float)(reinterpret_cast(&vSrcA.m128_s32[1]))); + SubFloat(retval, 2) = ((float)(reinterpret_cast(&vSrcA.m128_s32[2]))); + SubFloat(retval, 3) = ((float)(reinterpret_cast(&vSrcA.m128_s32[3]))); + return retval; +} + + +FORCEINLINE i32x4 IntShiftLeftWordSIMD(const i32x4& vSrcA, const i32x4& vSrcB) +{ + i32x4 retval; + SubInt(retval, 0) = SubInt(vSrcA, 0) << SubInt(vSrcB, 0); + SubInt(retval, 1) = SubInt(vSrcA, 1) << SubInt(vSrcB, 1); + SubInt(retval, 2) = SubInt(vSrcA, 2) << SubInt(vSrcB, 2); + SubInt(retval, 3) = SubInt(vSrcA, 3) << SubInt(vSrcB, 3); + + + return retval; +} + +#endif + +#elif ( defined( _PS3 ) ) +#define SN_IMPROVED_INTRINSICS ( (( __GNUC__ == 4 ) && ( __GNUC_MINOR__ == 1 ) && ( __GNUC_PATCHLEVEL__ == 1 )) ||\ + (defined(__SN_VER__) && (__SN_VER__ > 25002)) ) + +FORCEINLINE float FloatSIMD(fltx4& a, int idx) +{ +#if SN_IMPROVED_INTRINSICS + return vec_extract(a, idx); +#else + fltx4_union a_union; + vec_st(a, 0, &a_union.vmxf); + return a_union.m128_f32[idx]; +#endif +} + +FORCEINLINE unsigned int UIntSIMD(u32x4& a, int idx) +{ +#if SN_IMPROVED_INTRINSICS + return vec_extract(a, idx); +#else + fltx4_union a_union; + vec_st(a, 0, &a_union.vmxui); + return a_union.m128_u32[idx]; +#endif +} + +FORCEINLINE fltx4 AddSIMD(const fltx4& a, const fltx4& b) +{ + return vec_add(a, b); +} + +FORCEINLINE fltx4 SubSIMD(const fltx4& a, const fltx4& b) +{ + return vec_sub(a, b); +} + +FORCEINLINE fltx4 MulSIMD(const fltx4& a, const fltx4& b) +{ + return vec_madd(a, b, _VEC_ZEROF); +} + +FORCEINLINE fltx4 MaddSIMD(const fltx4& a, const fltx4& b, const fltx4& c) +{ + return vec_madd(a, b, c); +} + +FORCEINLINE fltx4 MsubSIMD(const fltx4& a, const fltx4& b, const fltx4& c) +{ + return vec_nmsub(a, b, c); +}; + +FORCEINLINE fltx4 Dot3SIMD(const fltx4& a, const fltx4& b) +{ + fltx4 result; + + result = vec_madd(a, b, _VEC_ZEROF); + result = vec_madd(vec_sld(a, a, 4), vec_sld(b, b, 4), result); + result = vec_madd(vec_sld(a, a, 8), vec_sld(b, b, 8), result); + + result = vec_splat(result, 0); + + return result; +} + +FORCEINLINE fltx4 Dot4SIMD(const fltx4& a, const fltx4& b) +{ + fltx4 result; + + result = vec_madd(a, b, _VEC_ZEROF); + result = vec_madd(vec_sld(a, a, 4), vec_sld(b, b, 4), result); + result = vec_add(vec_sld(result, result, 8), result); + + result = vec_splat(result, 0); + + return result; +} + +FORCEINLINE fltx4 SinSIMD(const fltx4& radians) +{ + return sinf4(radians); +} + +FORCEINLINE void SinCos3SIMD(fltx4& sine, fltx4& cosine, const fltx4& radians) +{ + sincosf4(radians, &sine, &cosine); +} + +FORCEINLINE void SinCosSIMD(fltx4& sine, fltx4& cosine, const fltx4& radians) +{ + sincosf4(radians, &sine, &cosine); +} + +FORCEINLINE fltx4 ArcCosSIMD(const fltx4& cs) +{ + return acosf4(cs); +} + +FORCEINLINE fltx4 ArcTan2SIMD(const fltx4& a, const fltx4& b) +{ + return atan2f4(a, b); +} + +FORCEINLINE fltx4 ArcSinSIMD(const fltx4& sine) +{ + return asinf4(sine); +} + +FORCEINLINE fltx4 MaxSIMD(const fltx4& a, const fltx4& b) +{ + return vec_max(a, b); +} +FORCEINLINE fltx4 MinSIMD(const fltx4& a, const fltx4& b) +{ + return vec_min(a, b); +} + +FORCEINLINE fltx4 AndSIMD(const fltx4& a, const fltx4& b) +{ + return vec_and(a, b); +} +FORCEINLINE fltx4 AndSIMD(const bi32x4& a, const fltx4& b) +{ + return vec_and((fltx4)a, b); +} +FORCEINLINE fltx4 AndSIMD(const fltx4& a, const bi32x4& b) +{ + return vec_and(a, (fltx4)b); +} +FORCEINLINE bi32x4 AndSIMD(const bi32x4& a, const bi32x4& b) +{ + return vec_and(a, b); +} + +#if 0 +FORCEINLINE fltx4 AndNotSIMD(const fltx4& a, const fltx4& b) +{ + return vec_andc(b, a); +} +FORCEINLINE fltx4 AndNotSIMD(const bi32x4& a, const fltx4& b) +{ + return vec_andc(b, (fltx4)a); +} +FORCEINLINE fltx4 AndNotSIMD(const fltx4& a, const bi32x4& b) +{ + return (fltx4)vec_andc(b, (bi32x4)a); +} +FORCEINLINE bi32x4 AndNotSIMD(const bi32x4& a, const bi32x4& b) +{ + return vec_andc(b, a); +} +#else +template< typename T, typename U > +FORCEINLINE T AndNotSIMD(const T& a, const U& b) +{ + return vec_andc(b, (T)a); +} + +FORCEINLINE fltx4 AndNotSIMD(const bi32x4& a, const fltx4& b) +{ + return vec_andc(b, (fltx4)a); +} +#endif + +FORCEINLINE fltx4 XorSIMD(const fltx4& a, const fltx4& b) +{ + return vec_xor(a, b); +} +FORCEINLINE fltx4 XorSIMD(const bi32x4& a, const fltx4& b) +{ + return vec_xor((fltx4)a, b); +} +FORCEINLINE fltx4 XorSIMD(const fltx4& a, const bi32x4& b) +{ + return vec_xor(a, (fltx4)b); +} +FORCEINLINE bi32x4 XorSIMD(const bi32x4& a, const bi32x4& b) +{ + return vec_xor(a, b); +} + +FORCEINLINE fltx4 OrSIMD(const fltx4& a, const fltx4& b) +{ + return vec_or(a, b); +} +FORCEINLINE fltx4 OrSIMD(const bi32x4& a, const fltx4& b) +{ + return vec_or((fltx4)a, b); +} +FORCEINLINE fltx4 OrSIMD(const fltx4& a, const bi32x4& b) +{ + return vec_or(a, (fltx4)b); +} +FORCEINLINE i32x4 OrSIMD(const i32x4& a, const i32x4& b) +{ + return vec_or(a, b); +} +FORCEINLINE u32x4 OrSIMD(const u32x4& a, const u32x4& b) +{ + return vec_or(a, b); +} + +#if !defined(__SPU__) +FORCEINLINE bi32x4 OrSIMD(const bi32x4& a, const bi32x4& b) +{ + return vec_or(a, b); +} +#endif + +FORCEINLINE fltx4 NegSIMD(const fltx4& a) +{ + return(SubSIMD(_VEC_ZEROF, a)); + +} + +FORCEINLINE bool IsAnyZeros(const fltx4& a) +{ + return vec_any_eq(a, _VEC_ZEROF); +} + +FORCEINLINE bool IsAnyZeros(const bi32x4& a) +{ + return vec_any_eq((u32x4)a, _VEC_ZERO); +} + +FORCEINLINE bool IsAllZeros(const bi32x4& a) +{ + return vec_all_eq((u32x4)a, _VEC_ZERO); +} + +FORCEINLINE bool IsAnyXYZZero(const fltx4& a) +{ +#if SN_IMPROVED_INTRINSICS + + fltx4 b = vec_insert(1.0f, a, 3); + + return vec_any_eq(b, _VEC_ZEROF); +#else + fltx4 b = vec_perm(a, _VEC_ONEF, _VEC_PERMUTE_XYZ0W1); + return vec_any_eq(b, _VEC_ZEROF); +#endif +} + +FORCEINLINE bool IsAllGreaterThan(const fltx4& a, const fltx4& b) +{ + return vec_all_gt(a, b); +} + +FORCEINLINE bool IsAllGreaterThanOrEq(const fltx4& a, const fltx4& b) +{ + return vec_all_ge(a, b); +} + +FORCEINLINE bool IsAllEqual(const fltx4& a, const fltx4& b) +{ + return vec_all_eq(a, b); +} + + +FORCEINLINE int TestSignSIMD(const fltx4& a) +{ + int nRet = 0; + + fltx4_union a_union; + vec_st(a, 0, &a_union.vmxf); + + nRet |= (a_union.m128_u32[0] & 0x80000000) >> 31; + nRet |= (a_union.m128_u32[1] & 0x80000000) >> 30; + nRet |= (a_union.m128_u32[2] & 0x80000000) >> 29; + nRet |= (a_union.m128_u32[3] & 0x80000000) >> 28; + + return nRet; +} +FORCEINLINE int TestSignSIMD(const bi32x4& a) +{ + int nRet = 0; + + fltx4_union a_union; + vec_st(a, 0, &a_union.vmxbi); + + nRet |= (a_union.m128_u32[0] & 0x80000000) >> 31; + nRet |= (a_union.m128_u32[1] & 0x80000000) >> 30; + nRet |= (a_union.m128_u32[2] & 0x80000000) >> 29; + nRet |= (a_union.m128_u32[3] & 0x80000000) >> 28; + + return nRet; +} + +FORCEINLINE bool IsAnyNegative(const bi32x4& a) +{ + return (0 != TestSignSIMD(a)); +} + +FORCEINLINE fltx4 SetWToZeroSIMD(const fltx4& a) +{ + return (fltx4)vec_and((u32x4)a, _VEC_CLEAR_WMASK); +} +FORCEINLINE bi32x4 SetWToZeroSIMD(const bi32x4& a) +{ + return (bi32x4)vec_and((u32x4)a, _VEC_CLEAR_WMASK); +} + +FORCEINLINE bool IsAnyNegative(const fltx4& a) +{ + return vec_any_lt(a, _VEC_ZEROF); +} + +FORCEINLINE bool IsAnyTrue(const fltx4& a) +{ + return vec_any_ne(a, _VEC_ZEROF); +} + +#ifdef DIFFERENT_NATIVE_VECTOR_TYPES + +FORCEINLINE bool IsAnyTrue(const bi32x4& a) +{ + return vec_any_ne((vector unsigned int) a, _VEC_0L); +} + +#endif + +FORCEINLINE bi32x4 CmpEqSIMD(const fltx4& a, const fltx4& b) +{ + return (bi32x4)vec_cmpeq(a, b); +} +FORCEINLINE bi32x4 CmpEqSIMD(const i32x4& a, const i32x4& b) +{ + return (bi32x4)vec_cmpeq(a, b); +} +FORCEINLINE bi32x4 CmpEqSIMD(const u32x4& a, const u32x4& b) +{ + return (bi32x4)vec_cmpeq(a, b); +} + +FORCEINLINE bi32x4 CmpGtSIMD(const fltx4& a, const fltx4& b) +{ + return (bi32x4)vec_cmpgt(a, b); +} +FORCEINLINE bi32x4 CmpGtSIMD(const i32x4& a, const i32x4& b) +{ + return (bi32x4)vec_cmpgt(a, b); +} +FORCEINLINE bi32x4 CmpGtSIMD(const u32x4& a, const u32x4& b) +{ + return (bi32x4)vec_cmpgt(a, b); +} + +FORCEINLINE bi32x4 CmpGeSIMD(const fltx4& a, const fltx4& b) +{ + return (bi32x4)vec_cmpge(a, b); +} + + +FORCEINLINE bi32x4 CmpLtSIMD(const fltx4& a, const fltx4& b) +{ + return (bi32x4)vec_cmplt(a, b); +} + +FORCEINLINE bi32x4 CmpLeSIMD(const fltx4& a, const fltx4& b) +{ + return (bi32x4)vec_cmple(a, b); +} + + + +FORCEINLINE bi32x4 CmpInBoundsSIMD(const fltx4& a, const fltx4& b) +{ + i32x4 control; + control = vec_cmpb(a, b); + return (bi32x4)vec_cmpeq((u32x4)control, _VEC_ZERO); +} + +FORCEINLINE int CmpAnyLeSIMD(const fltx4& a, const fltx4& b) +{ + return vec_any_le(a, b); +} + +FORCEINLINE int CmpAnyGeSIMD(const fltx4& a, const fltx4& b) +{ + return vec_any_ge(a, b); +} + +FORCEINLINE int CmpAnyLtSIMD(const fltx4& a, const fltx4& b) +{ + return vec_any_lt(a, b); +} +FORCEINLINE int CmpAnyLtSIMD(const bi32x4& a, const i32x4& b) +{ + return vec_any_lt((i32x4)a, b); +} + +FORCEINLINE int CmpAnyGtSIMD(const fltx4& a, const fltx4& b) +{ + return vec_any_gt(a, b); +} + +FORCEINLINE int CmpAnyNeSIMD(const fltx4& a, const fltx4& b) +{ + return vec_any_ne(a, b); +} +FORCEINLINE int CmpAnyNeSIMD(const bi32x4& a, const bi32x4& b) +{ + return vec_any_ne(a, b); +} +FORCEINLINE int CmpAnyNeSIMD(const bi32x4& a, const i32x4& b) +{ + return vec_any_ne(a, (bi32x4)b); +} + +FORCEINLINE int CmpAllLeSIMD(const fltx4& a, const fltx4& b) +{ + return vec_all_le(a, b); +} + +FORCEINLINE fltx4 MaskedAssign(const bi32x4& ReplacementMask, const fltx4& NewValue, const fltx4& OldValue) +{ + return vec_sel(OldValue, NewValue, ReplacementMask); +} + +FORCEINLINE fltx4 MaskedAssign(const fltx4& ReplacementMask, const fltx4& NewValue, const fltx4& OldValue) +{ + return vec_sel(OldValue, NewValue, (const bi32x4)ReplacementMask); +} + +FORCEINLINE vector signed short MaskedAssign(const vector unsigned short& ReplacementMask, const vector signed short& NewValue, const vector signed short& OldValue) +{ + return vec_sel(OldValue, NewValue, ReplacementMask); +} + +FORCEINLINE fltx4 ReplicateX4(float flValue) +{ +#if SN_IMPROVED_INTRINSICS + return vec_splats(flValue); +#else + float* pValue = &flValue; + Assert(pValue); + Assert(((unsigned int)pValue & 3) == 0); + + fltx4 result; + + result = vec_ld(0, pValue); + result = vec_splat(vec_perm(result, result, vec_lvsl(0, pValue)), 0); + + return result; +#endif +} + +FORCEINLINE fltx4 ReplicateX4(const float* pValue) +{ +#if SN_IMPROVED_INTRINSICS + return vec_splats(*pValue); +#else + Assert(pValue); + fltx4 result; + + result = vec_ld(0, pValue); + result = vec_splat(vec_perm(result, result, vec_lvsl(0, pValue)), 0); + + return result; +#endif +} + +FORCEINLINE i32x4 ReplicateIX4(int nValue) +{ +#if SN_IMPROVED_INTRINSICS + return vec_splats(nValue); +#else + int* pValue = &nValue; + Assert(pValue); + Assert(((unsigned int)pValue & 3) == 0); + i32x4 result; + + result = vec_ld(0, pValue); + result = vec_splat(vec_perm(result, result, vec_lvsl(0, pValue)), 0); + + return result; +#endif +} + +FORCEINLINE fltx4 SqrtSIMD(const fltx4& a) +{ + return sqrtf4(a); +} + +FORCEINLINE fltx4 SqrtEstSIMD(const fltx4& a) +{ +#if defined( _PS3 ) && !defined( SPU ) + fltx4 vRecipSquareRoot = vec_rsqrte(a); + i32x4 vOne = vec_splat_s32(1); + i32x4 vAllOnes = vec_splat_s32(-1); + i32x4 vShiftLeft24 = vec_splat_s32(-8); + fltx4 vZero = (fltx4)vec_splat_s32(0); + u32x4 vInputShifted = vec_sl((u32x4)a, (u32x4)vOne); + u32x4 vInfinityShifted = vec_sl((u32x4)vAllOnes, (u32x4)vShiftLeft24); + bi32x4 vEqualsZero = vec_vcmpeqfp(a, vZero); + bi32x4 vEqualsInfinity = vec_vcmpequw(vInputShifted, vInfinityShifted); + fltx4 vSquareRoot = vec_madd(a, vRecipSquareRoot, _VEC_ZEROF); + bi32x4 vResultMask = vec_vcmpequw((u32x4)vEqualsInfinity, (u32x4)vEqualsZero); + fltx4 vCorrectedSquareRoot = vec_sel(a, vSquareRoot, vResultMask); + + return vCorrectedSquareRoot; +#else + return SqrtSIMD(a); +#endif +} + +FORCEINLINE fltx4 ReciprocalSqrtEstSIMD(const fltx4& a) +{ + return vec_rsqrte(a); +} + +FORCEINLINE fltx4 ReciprocalSqrtSIMD(const fltx4& a) +{ + fltx4 result; + vmathV4RsqrtPerElem((VmathVector4*)&result, (const VmathVector4*)&a); + + return result; +} + +FORCEINLINE fltx4 ReciprocalEstSIMD(const fltx4& a) +{ + return vec_re(a); +} + +FORCEINLINE fltx4 ReciprocalEstSaturateSIMD(const fltx4& a) +{ + bi32x4 zero_mask = CmpEqSIMD(a, Four_Zeros); + fltx4 ret = OrSIMD(a, AndSIMD(Four_Epsilons, zero_mask)); + ret = ReciprocalEstSIMD(ret); + return ret; +} + + +FORCEINLINE fltx4 ReciprocalSIMD(const fltx4& a) +{ + fltx4 result; + vmathV4RecipPerElem((VmathVector4*)&result, (const VmathVector4*)&a); + + return result; +} + +FORCEINLINE fltx4 DivSIMD(const fltx4& a, const fltx4& b) +{ + return MulSIMD(ReciprocalSIMD(b), a); +} + +FORCEINLINE fltx4 DivEstSIMD(const fltx4& a, const fltx4& b) +{ + return MulSIMD(ReciprocalEstSIMD(b), a); +} + +FORCEINLINE fltx4 ReciprocalSaturateSIMD(const fltx4& a) +{ + bi32x4 zero_mask = CmpEqSIMD(a, _VEC_ZEROF); + fltx4 a_safe = OrSIMD(a, AndSIMD(_VEC_EPSILONF, zero_mask)); + return ReciprocalSIMD(a_safe); + +} + + +FORCEINLINE fltx4 ExpSIMD(const fltx4& toPower) +{ + return exp2f4(toPower); +} + +FORCEINLINE fltx4 Exp2EstSIMD(const fltx4& f) +{ + return exp2f4fast(f); +} + + +FORCEINLINE fltx4 ClampVectorSIMD(FLTX4 in, FLTX4 min, FLTX4 max) +{ + fltx4 result = vec_max(min, in); + return vec_min(max, result); +} + + +FORCEINLINE fltx4 LoadUnalignedSIMD(const void* pSIMD) +{ +#if SN_IMPROVED_INTRINSICS + + fltx4 v0, v1; + + Assert(pSIMD); + + + v0 = (fltx4)vec_lvlx(0, (float*)pSIMD); + v1 = (fltx4)vec_lvrx(16, (float*)pSIMD); + return vec_or(v0, v1); + +#else + + fltx4 v0, v1; + vector unsigned char permMask; + + Assert(pSIMD); + + v0 = vec_ld(0, pSIMD); + permMask = vec_lvsl(0, pSIMD); + v1 = vec_ld(15, pSIMD); + + return vec_perm(v0, v1, permMask); + +#endif +} + +FORCEINLINE fltx4 LoadUnsignedByte4SIMD(unsigned char* pBytes) +{ + +#if SN_IMPROVED_INTRINSICS + + __vector unsigned char res_uc; + __vector unsigned short res_us; + + __vector unsigned char vZero8 = (__vector unsigned char)vec_splat_u8(0); + __vector unsigned short vZero16 = (__vector unsigned short)vec_splat_u16(0); + + res_uc = (__vector unsigned char)vec_lvlx(0, pBytes); + res_uc = vec_mergeh(vZero8, res_uc); + res_us = vec_mergeh(vZero16, (__vector unsigned short)res_uc); + return vec_ctf((__vector unsigned int)res_us, 0); + +#else + + vector unsigned char v0, v1; + vector bool char res_uc; + vector unsigned char permMask; + vector bool short res_us; + + vector bool char vZero8 = (vector bool char)vec_splat_u8(0); + vector bool short vZero16 = (vector bool short)vec_splat_u16(0); + + v0 = vec_ld(0, pBytes); + permMask = vec_lvsl(0, pBytes); + v1 = vec_ld(3, pBytes); + res_uc = (vector bool char)vec_perm(v0, v1, permMask); + res_uc = vec_mergeh(vZero8, res_uc); + res_us = vec_mergeh(vZero16, (vector bool short)res_uc); + return vec_ctf((vector unsigned int)res_us, 0); + +#endif + +} + +FORCEINLINE fltx4 LoadSignedByte4SIMD(signed char* pBytes) +{ + +#if SN_IMPROVED_INTRINSICS + + vector signed char res_uc; + vector signed short res_us; + vector signed int res_ui; + + res_uc = (vector signed char)vec_lvlx(0, pBytes); + res_us = vec_unpackh(res_uc); + res_ui = vec_unpackh(res_us); + return vec_ctf(res_ui, 0); + +#else + + vector signed char v0, v1, res_uc; + vector unsigned char permMask; + vector signed short res_us; + vector signed int res_ui; + + v0 = vec_ld(0, pBytes); + permMask = vec_lvsl(0, pBytes); + v1 = vec_ld(3, pBytes); + res_uc = vec_perm(v0, v1, permMask); + res_us = vec_unpackh(res_uc); + res_ui = vec_unpackh(res_us); + return vec_ctf(res_ui, 0); + +#endif + +} + + +FORCEINLINE fltx4 LoadUnaligned3SIMD(const void* pSIMD) +{ + Assert(pSIMD); + + fltx4 v0 = vec_ld(0, (float*)(pSIMD)); + vector unsigned char permMask = vec_lvsl(0, (float*)(pSIMD)); + fltx4 v1 = vec_ld(11, (float*)(pSIMD)); + + return vec_perm(v0, v1, permMask); +} + + +FORCEINLINE fltx4 LoadUnalignedFloatSIMD(const float* pFlt) +{ + fltx4 v0 = vec_lde(0, const_cast(pFlt)); + vector unsigned char permMask = vec_lvsl(0, const_cast(pFlt)); + return vec_perm(v0, v0, permMask); +} + + +FORCEINLINE fltx4 LoadAlignedSIMD(const void* pSIMD) +{ + return vec_ld(0, (float*)pSIMD); +} + +#ifndef SPU +FORCEINLINE fltx4 LoadAlignedSIMD(const VectorAligned& pSIMD) +{ + fltx4 out; + out = vec_ld(0, pSIMD.Base()); + + return (fltx4)vec_and((u32x4)out, _VEC_CLEAR_WMASK); +} + +FORCEINLINE fltx4 LoadAlignedSIMD(const VectorAligned* RESTRICT pSIMD) +{ + fltx4 out; + out = vec_ld(0, pSIMD->Base()); + + return (fltx4)vec_and((u32x4)out, _VEC_CLEAR_WMASK); +} + + +FORCEINLINE void StoreAligned3SIMD(VectorAligned* RESTRICT pSIMD, const fltx4& a) +{ + vec_st(a, 0, pSIMD->Base()); +} +#endif + +FORCEINLINE void StoreAlignedSIMD(float* pSIMD, const fltx4& a) +{ + vec_st(a, 0, pSIMD); +} + +FORCEINLINE void StoreUnalignedSIMD(float* pSIMD, const fltx4& a) +{ +#if ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ == 1 ) && ( __GNUC_PATCHLEVEL__ == 1 ) + vec_stvlx(a, 0, pSIMD); + vec_stvrx(a, 16, pSIMD); +#else + fltx4_union a_union; + vec_st(a, 0, &a_union.vmxf); + pSIMD[0] = a_union.m128_f32[0]; + pSIMD[1] = a_union.m128_f32[1]; + pSIMD[2] = a_union.m128_f32[2]; + pSIMD[3] = a_union.m128_f32[3]; +#endif + +} + +FORCEINLINE void StoreUnaligned3SIMD(float* pSIMD, const fltx4& a) +{ + fltx4_union a_union; + vec_st(a, 0, &a_union.vmxf); + pSIMD[0] = a_union.m128_f32[0]; + pSIMD[1] = a_union.m128_f32[1]; + pSIMD[2] = a_union.m128_f32[2]; +}; + + + +#ifndef SPU + +FORCEINLINE fltx4 Compress4SIMD(fltx4 const a, fltx4 const& b, fltx4 const& c, fltx4 const& d); +FORCEINLINE fltx4 LoadGatherSIMD(const float& x, const float& y, const float& z, const float& w) +{ +#if USING_POINTLESSLY_SLOW_SONY_CODE + return vmathV4MakeFromElems_V(x, y, z, w).vec128; +#else + fltx4 vx = vec_lvlx(0, &x); + fltx4 vy = vec_lvlx(0, &y); + fltx4 vz = vec_lvlx(0, &z); + fltx4 vw = vec_lvlx(0, &w); + return Compress4SIMD(vx, vy, vz, vw); +#endif +} + + +FORCEINLINE void StoreFourUnalignedVector3SIMD(fltx4 a, fltx4 b, fltx4 c, FLTX4 d, + Vector* const pDestination) +{ + StoreUnaligned3SIMD(pDestination->Base(), a); + StoreUnaligned3SIMD((pDestination + 1)->Base(), b); + StoreUnaligned3SIMD((pDestination + 2)->Base(), c); + StoreUnaligned3SIMD((pDestination + 3)->Base(), d); +} + +FORCEINLINE void StoreFourAlignedVector3SIMD(fltx4 a, fltx4 b, fltx4 c, FLTX4 d, + Vector* const pDestination) +{ + StoreUnaligned3SIMD(pDestination->Base(), a); + StoreUnaligned3SIMD((pDestination + 1)->Base(), b); + StoreUnaligned3SIMD((pDestination + 2)->Base(), c); + StoreUnaligned3SIMD((pDestination + 3)->Base(), d); +} +#endif + +FORCEINLINE void ConvertStoreAsIntsSIMD(intx4* RESTRICT pDest, const fltx4& vSrc) +{ + i32x4 asInt = vec_cts(vSrc, 0); + vec_st(asInt, 0, pDest->Base()); +} + +FORCEINLINE void TransposeSIMD(fltx4& x, fltx4& y, fltx4& z, fltx4& w) +{ + fltx4 p0, p1, p2, p3; + + p0 = vec_mergeh(x, z); + p1 = vec_mergeh(y, w); + p2 = vec_mergel(x, z); + p3 = vec_mergel(y, w); + + x = vec_mergeh(p0, p1); + y = vec_mergel(p0, p1); + z = vec_mergeh(p2, p3); + w = vec_mergel(p2, p3); +} + +FORCEINLINE fltx4 LoadZeroSIMD(void) +{ + return _VEC_ZEROF; +} +FORCEINLINE i32x4 LoadZeroISIMD(void) +{ + return vec_splat_s32(0); +} + + +FORCEINLINE fltx4 LoadOneSIMD(void) +{ + return _VEC_ONEF; +} +FORCEINLINE i32x4 LoadOneISIMD(void) +{ + return vec_splat_s32(1); +} + +FORCEINLINE fltx4 SplatXSIMD(fltx4 a) +{ + return vec_splat(a, 0); +} +FORCEINLINE fltx4 SplatYSIMD(fltx4 a) +{ + return vec_splat(a, 1); +} +FORCEINLINE fltx4 SplatZSIMD(fltx4 a) +{ + return vec_splat(a, 2); +} +FORCEINLINE fltx4 SplatWSIMD(fltx4 a) +{ + return vec_splat(a, 3); +} + +FORCEINLINE bi32x4 SplatXSIMD(bi32x4 a) +{ + return vec_splat(a, 0); +} +FORCEINLINE bi32x4 SplatYSIMD(bi32x4 a) +{ + return vec_splat(a, 1); +} +FORCEINLINE bi32x4 SplatZSIMD(bi32x4 a) +{ + return vec_splat(a, 2); +} +FORCEINLINE bi32x4 SplatWSIMD(bi32x4 a) +{ + return vec_splat(a, 3); +} + +FORCEINLINE fltx4 SetXSIMD(const fltx4& a, const fltx4& x) +{ + return vec_sel(a, x, _VEC_COMPONENT_MASK_0); +} + +FORCEINLINE fltx4 SetYSIMD(const fltx4& a, const fltx4& y) +{ + return vec_sel(a, y, _VEC_COMPONENT_MASK_1); +} + +FORCEINLINE fltx4 SetZSIMD(const fltx4& a, const fltx4& z) +{ + return vec_sel(a, z, _VEC_COMPONENT_MASK_2); +} + +FORCEINLINE fltx4 SetWSIMD(const fltx4& a, const fltx4& w) +{ + return vec_sel(a, w, _VEC_COMPONENT_MASK_3); +} + +FORCEINLINE fltx4 SetComponentSIMD(const fltx4& a, int nComponent, float flValue) +{ +#if SN_IMPROVED_INTRINSICS + return vec_insert(flValue, a, nComponent); +#else + fltx4_union a_union; + a_union.vmxf = vec_ld(0, &a); + a_union.m128_f32[nComponent] = flValue; + return a_union.vmxf; +#endif +} + +FORCEINLINE float GetComponentSIMD(const fltx4& a, int nComponent) +{ +#if SN_IMPROVED_INTRINSICS + return vec_extract(a, nComponent); +#else + fltx4_union a_union; + a_union.vmxf = vec_ld(0, &a); + return a_union.m128_f32[nComponent]; +#endif +} + + +FORCEINLINE fltx4 RotateLeft(const fltx4& a) +{ + return vec_sld(a, a, 4); +} + +FORCEINLINE fltx4 RotateLeft2(const fltx4& a) +{ + return vec_sld(a, a, 8); +} + +FORCEINLINE fltx4 RotateRight(const fltx4& a) +{ + return vec_sld(a, a, 12); +} + +FORCEINLINE fltx4 RotateRight2(const fltx4& a) +{ + return vec_sld(a, a, 8); +} + +template < uint nBits, typename T > +FORCEINLINE T ShiftLeftByBits(const T& a) +{ + if (nBits >= 128) + { + return (T)LoadZeroSIMD(); + } + else if (nBits == 0) + { + return a; + } + else if ((nBits > 7)) + { + T t = vec_sld(a, ((T)LoadZeroSIMD()), (nBits >> 3)); + return ShiftLeftByBits< (nBits & 0x7) >(t); + } + else + { + vector unsigned int shifter = (vector unsigned int) (vec_splat_s8(((signed char)(nBits & 0x7)))); + return (T)vec_sll((vector signed int) a, shifter); + } +} + +template < uint nBits, typename T > +FORCEINLINE T ShiftRightByBits(const T& a) +{ + if (nBits >= 128) + { + return (T)LoadZeroSIMD(); + } + else if (nBits == 0) + { + return a; + } + else if ((nBits > 7)) + { + T t = vec_sld(((T)LoadZeroSIMD()), a, 16 - (nBits >> 3)); + return ShiftRightByBits< (nBits & 0x7) >(t); + } + else + { + vector unsigned int shifter = (vector unsigned int) (vec_splat_s8(((signed char)(nBits & 0x7)))); + return (T)vec_srl((vector unsigned int) a, shifter); + } +} + + + + +FORCEINLINE fltx4 FindLowestSIMD3(const fltx4& a) +{ + fltx4 result; + fltx4 x = vec_splat(a, 0); + fltx4 y = vec_splat(a, 1); + fltx4 z = vec_splat(a, 2); + + if (vec_any_nan(a)) + { + x = vec_all_nan(x) ? _VEC_FLTMAX : x; + y = vec_all_nan(y) ? _VEC_FLTMAX : y; + z = vec_all_nan(z) ? _VEC_FLTMAX : z; + } + + result = vec_min(y, x); + result = vec_min(z, result); + + return result; + +} + +FORCEINLINE fltx4 FindHighestSIMD3(const fltx4& a) +{ + fltx4 result; + fltx4 x = vec_splat(a, 0); + fltx4 y = vec_splat(a, 1); + fltx4 z = vec_splat(a, 2); + + if (vec_any_nan(a)) + { + x = vec_all_nan(x) ? _VEC_FLTMIN : x; + y = vec_all_nan(y) ? _VEC_FLTMIN : y; + z = vec_all_nan(z) ? _VEC_FLTMIN : z; + } + + result = vec_max(y, x); + result = vec_max(z, result); + + return result; +} + + +FORCEINLINE i32x4 LoadAlignedIntSIMD(const int32* RESTRICT pSIMD) +{ + return vec_ld(0, const_cast(pSIMD)); +} + +FORCEINLINE i32x4 LoadUnalignedIntSIMD(const int32* RESTRICT pSIMD) +{ + i32x4 v0, v1; + vector unsigned char permMask; + + Assert(pSIMD); + + v0 = vec_ld(0, const_cast(pSIMD)); + permMask = vec_lvsl(0, const_cast(pSIMD)); + v1 = vec_ld(15, const_cast(pSIMD)); + + return vec_perm(v0, v1, permMask); + +} + +FORCEINLINE void StoreAlignedIntSIMD(int32* pSIMD, const i32x4& a) +{ + vec_st(a, 0, pSIMD); +} + +FORCEINLINE void StoreAlignedIntSIMD(int32* pSIMD, const fltx4& a) +{ + vec_st((i32x4)a, 0, pSIMD); +} + +FORCEINLINE void StoreAlignedIntSIMD(intx4& pSIMD, const i32x4& a) +{ + vec_st(a, 0, pSIMD.Base()); +} + +FORCEINLINE void StoreUnalignedIntSIMD(int32* pSIMD, const i32x4& a) +{ +#if SN_IMPROVED_INTRINSICS + + vec_stvlx(a, 0, pSIMD); + vec_stvrx(a, 16, pSIMD); + +#else + + fltx4_union tmp; + vec_st(a, 0, &tmp.vmxi); + + pSIMD[0] = tmp.m128_u32[0]; + pSIMD[1] = tmp.m128_u32[1]; + pSIMD[2] = tmp.m128_u32[2]; + pSIMD[3] = tmp.m128_u32[3]; + +#endif +} + +FORCEINLINE fltx4 CompressSIMD(fltx4 const& a, fltx4 const& b) +{ + const int32 ALIGN16 n4shuffleACXZ[4] ALIGN16_POST = { 0x00010203, 0x08090A0B, 0x10111213, 0x18191A1B }; + return vec_perm(a, b, (vec_uchar16)LoadAlignedIntSIMD(n4shuffleACXZ)); +} + +FORCEINLINE fltx4 Compress4SIMD(fltx4 const a, fltx4 const& b, fltx4 const& c, fltx4 const& d) +{ + fltx4 ab = vec_mergeh(a, b); + fltx4 cd = vec_mergeh(c, d); + static const int32 ALIGN16 shuffleABXY[4] ALIGN16_POST = { 0x00010203, 0x04050607, 0x10111213, 0x14151617 }; + + return vec_perm(ab, cd, (vec_uchar16)LoadAlignedIntSIMD(shuffleABXY)); +} + + +FORCEINLINE fltx4 UnsignedIntConvertToFltSIMD(const i32x4& vSrcA) +{ + return vec_ctf(vSrcA, 0); +} + + +FORCEINLINE fltx4 SignedIntConvertToFltSIMD(const i32x4& vSrcA) +{ + return vec_ctf(vSrcA, 0); +} + +#define UnsignedFixedIntConvertToFltSIMD(vSrcA, uImmed) (vec_ctf( (vSrcA), (uImmed) )) + +#define SignedFixedIntConvertToFltSIMD(vSrcA, uImmed) (vec_ctf( (vSrcA), (uImmed) )) + +#define IntSetImmediateSIMD(x) (vec_splat_s32(x)) + + +FORCEINLINE u32x4 IntShiftLeftWordSIMD(u32x4 vSrcA, u32x4 vSrcB) +{ + return vec_sl(vSrcA, vSrcB); +} + + +FORCEINLINE float SubFloat(const fltx4& a, int idx) +{ +#if ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ == 1 ) && ( __GNUC_PATCHLEVEL__ == 1 ) + return(vec_extract(a, idx)); +#else + fltx4_union a_union; + vec_st(a, 0, &a_union.vmxf); + return a_union.m128_f32[idx]; +#endif +} + +FORCEINLINE float& SubFloat(fltx4& a, int idx) +{ + fltx4_union& a_union = (fltx4_union&)a; + return a_union.m128_f32[idx]; +} + +FORCEINLINE uint32 SubInt(const u32x4& a, int idx) +{ +#if ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ == 1 ) && ( __GNUC_PATCHLEVEL__ == 1 ) + return(vec_extract(a, idx)); +#else + fltx4_union a_union; + vec_st(a, 0, &a_union.vmxui); + return a_union.m128_u32[idx]; +#endif +} + +FORCEINLINE uint32 SubInt(const fltx4& a, int idx) +{ +#if ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ == 1 ) && ( __GNUC_PATCHLEVEL__ == 1 ) + return(vec_extract((u32x4)a, idx)); +#else + fltx4_union a_union; + vec_st(a, 0, &a_union.vmxf); + return a_union.m128_u32[idx]; +#endif +} + +FORCEINLINE uint32& SubInt(u32x4& a, int idx) +{ + fltx4_union& a_union = (fltx4_union&)a; + return a_union.m128_u32[idx]; +} + +FORCEINLINE uint32 SubFloatConvertToInt(const fltx4& a, int idx) +{ + +#if ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ == 1 ) && ( __GNUC_PATCHLEVEL__ == 1 ) + return(vec_extract(vec_ctu(a, 0), idx)); +#else + u32x4 t = vec_ctu(a, 0); + return SubInt(t, idx); +#endif + +} + +template< typename T, typename U > +FORCEINLINE T PermuteVMX(T a, T b, U swizzleMask) +{ + return vec_perm(a, b, (vec_uchar16)swizzleMask); +} + + +#if !defined(__SPU__) +#define fsel __fsel +#endif + +inline bool IsVector3LessThan(const fltx4& v1, const fltx4& v2) +{ + return vec_any_lt(v1, v2); +} + +inline bool IsVector3GreaterOrEqual(const fltx4& v1, const fltx4& v2) +{ + return !IsVector3LessThan(v1, v2); +} + +FORCEINLINE fltx4 ReciprocalSqrtEstSaturateSIMD(const fltx4& a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = 1.0 / sqrt(SubFloat(a, 0) != 0.0f ? SubFloat(a, 0) : FLT_EPSILON); + SubFloat(retVal, 1) = 1.0 / sqrt(SubFloat(a, 1) != 0.0f ? SubFloat(a, 1) : FLT_EPSILON); + SubFloat(retVal, 2) = 1.0 / sqrt(SubFloat(a, 2) != 0.0f ? SubFloat(a, 2) : FLT_EPSILON); + SubFloat(retVal, 3) = 1.0 / sqrt(SubFloat(a, 3) != 0.0f ? SubFloat(a, 3) : FLT_EPSILON); + return retVal; +} + +FORCEINLINE fltx4 FloorSIMD(const fltx4& a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = floor(SubFloat(a, 0)); + SubFloat(retVal, 1) = floor(SubFloat(a, 1)); + SubFloat(retVal, 2) = floor(SubFloat(a, 2)); + SubFloat(retVal, 3) = floor(SubFloat(a, 3)); + return retVal; +} + +#elif ( defined( _X360 ) ) + +inline bool IsVector3LessThan(const fltx4& v1, const fltx4& v2) +{ + return !XMVector3GreaterOrEqual(v1, v2); +} + +inline BOOL IsVector3GreaterOrEqual(const fltx4& v1, const fltx4& v2) +{ + return XMVector3GreaterOrEqual(v1, v2); +} + + +FORCEINLINE float& FloatSIMD(fltx4& a, int idx) +{ + fltx4_union& a_union = (fltx4_union&)a; + return a_union.m128_f32[idx]; +} + +FORCEINLINE unsigned int& UIntSIMD(fltx4& a, int idx) +{ + fltx4_union& a_union = (fltx4_union&)a; + return a_union.m128_u32[idx]; +} + +FORCEINLINE fltx4 AddSIMD(const fltx4& a, const fltx4& b) +{ + return __vaddfp(a, b); +} + +FORCEINLINE fltx4 SubSIMD(const fltx4& a, const fltx4& b) +{ + return __vsubfp(a, b); +} + +FORCEINLINE fltx4 MulSIMD(const fltx4& a, const fltx4& b) +{ + return __vmulfp(a, b); +} + +FORCEINLINE fltx4 MaddSIMD(const fltx4& a, const fltx4& b, const fltx4& c) +{ + return __vmaddfp(a, b, c); +} + +FORCEINLINE fltx4 MsubSIMD(const fltx4& a, const fltx4& b, const fltx4& c) +{ + return __vnmsubfp(a, b, c); +}; + +FORCEINLINE fltx4 Dot3SIMD(const fltx4& a, const fltx4& b) +{ + return __vmsum3fp(a, b); +} + +FORCEINLINE fltx4 Dot4SIMD(const fltx4& a, const fltx4& b) +{ + return __vmsum4fp(a, b); +} + +FORCEINLINE fltx4 SinSIMD(const fltx4& radians) +{ + return XMVectorSin(radians); +} + +FORCEINLINE void SinCos3SIMD(fltx4& sine, fltx4& cosine, const fltx4& radians) +{ + XMVectorSinCos(&sine, &cosine, radians); +} + +FORCEINLINE void SinCosSIMD(fltx4& sine, fltx4& cosine, const fltx4& radians) +{ + XMVectorSinCos(&sine, &cosine, radians); +} + +FORCEINLINE void CosSIMD(fltx4& cosine, const fltx4& radians) +{ + cosine = XMVectorCos(radians); +} + +FORCEINLINE fltx4 ArcSinSIMD(const fltx4& sine) +{ + return XMVectorASin(sine); +} + +FORCEINLINE fltx4 ArcCosSIMD(const fltx4& cs) +{ + return XMVectorACos(cs); +} + +FORCEINLINE fltx4 ArcTan2SIMD(const fltx4& a, const fltx4& b) +{ + return XMVectorATan2(a, b); +} + +FORCEINLINE fltx4 MaxSIMD(const fltx4& a, const fltx4& b) +{ + return __vmaxfp(a, b); +} + +FORCEINLINE fltx4 MinSIMD(const fltx4& a, const fltx4& b) +{ + return __vminfp(a, b); +} + +FORCEINLINE fltx4 AndSIMD(const fltx4& a, const fltx4& b) +{ + return __vand(a, b); +} + +FORCEINLINE fltx4 AndNotSIMD(const fltx4& a, const fltx4& b) +{ + return __vandc(b, a); +} + +FORCEINLINE fltx4 XorSIMD(const fltx4& a, const fltx4& b) +{ + return __vxor(a, b); +} + +FORCEINLINE fltx4 OrSIMD(const fltx4& a, const fltx4& b) +{ + return __vor(a, b); +} + +FORCEINLINE fltx4 NegSIMD(const fltx4& a) +{ + return XMVectorNegate(a); +} + +FORCEINLINE bool IsAllZeros(const fltx4& a) +{ + unsigned int equalFlags = 0; + __vcmpeqfpR(a, Four_Zeros, &equalFlags); + return XMComparisonAllTrue(equalFlags); +} + +FORCEINLINE bool IsAnyZeros(const fltx4& a) +{ + unsigned int conditionregister; + XMVectorEqualR(&conditionregister, a, XMVectorZero()); + return XMComparisonAnyTrue(conditionregister); +} + +FORCEINLINE bool IsAnyXYZZero(const fltx4& a) +{ + fltx4 temp = __vrlimi(a, a, 1, 1); + unsigned int conditionregister; + XMVectorEqualR(&conditionregister, temp, XMVectorZero()); + return XMComparisonAnyTrue(conditionregister); +} + +FORCEINLINE bool IsAllGreaterThan(const fltx4& a, const fltx4& b) +{ + unsigned int cr; + XMVectorGreaterR(&cr, a, b); + return XMComparisonAllTrue(cr); +} + +FORCEINLINE bool IsAllGreaterThanOrEq(const fltx4& a, const fltx4& b) +{ + unsigned int cr; + XMVectorGreaterOrEqualR(&cr, a, b); + return XMComparisonAllTrue(cr); +} + +FORCEINLINE bool IsAnyGreaterThan(const fltx4& a, const fltx4& b) +{ + unsigned int cr; + XMVectorGreaterR(&cr, a, b); + return XMComparisonAnyTrue(cr); +} + +FORCEINLINE bool IsAnyGreaterThanOrEq(const fltx4& a, const fltx4& b) +{ + unsigned int cr; + XMVectorGreaterOrEqualR(&cr, a, b); + return XMComparisonAnyTrue(cr); +} + +FORCEINLINE bool IsAllEqual(const fltx4& a, const fltx4& b) +{ + unsigned int cr; + XMVectorEqualR(&cr, a, b); + return XMComparisonAllTrue(cr); +} + + +FORCEINLINE int TestSignSIMD(const fltx4& a) +{ + int nRet = 0; + + const fltx4_union& a_union = (const fltx4_union&)a; + nRet |= (a_union.m128_u32[0] & 0x80000000) >> 31; + nRet |= (a_union.m128_u32[1] & 0x80000000) >> 30; + nRet |= (a_union.m128_u32[2] & 0x80000000) >> 29; + nRet |= (a_union.m128_u32[3] & 0x80000000) >> 28; + + return nRet; +} + +FORCEINLINE fltx4 SetWToZeroSIMD(const fltx4& a) +{ + return __vrlimi(a, __vzero(), 1, 0); +} + +FORCEINLINE bool IsAnyNegative(const fltx4& a) +{ + unsigned int equalFlags = 0; + fltx4 signMask = __vspltisw(-1); + signMask = __vslw(signMask, signMask); + __vcmpequwR(Four_Zeros, __vand(signMask, a), &equalFlags); + return !XMComparisonAllTrue(equalFlags); +} + +FORCEINLINE bool IsAnyTrue(const fltx4& a) +{ + unsigned int equalFlags = 0; + __vcmpequwR(Four_Zeros, a, &equalFlags); + return XMComparisonAnyFalse(equalFlags); +} + +FORCEINLINE fltx4 CmpEqSIMD(const fltx4& a, const fltx4& b) +{ + return __vcmpeqfp(a, b); +} + + +FORCEINLINE fltx4 CmpGtSIMD(const fltx4& a, const fltx4& b) +{ + return __vcmpgtfp(a, b); +} + +FORCEINLINE fltx4 CmpGeSIMD(const fltx4& a, const fltx4& b) +{ + return __vcmpgefp(a, b); +} + +FORCEINLINE fltx4 CmpLtSIMD(const fltx4& a, const fltx4& b) +{ + return __vcmpgtfp(b, a); +} + +FORCEINLINE fltx4 CmpLeSIMD(const fltx4& a, const fltx4& b) +{ + return __vcmpgefp(b, a); +} + +FORCEINLINE fltx4 CmpInBoundsSIMD(const fltx4& a, const fltx4& b) +{ + return XMVectorInBounds(a, b); +} + +FORCEINLINE fltx4 MaskedAssign(const fltx4& ReplacementMask, const fltx4& NewValue, const fltx4& OldValue) +{ + return __vsel(OldValue, NewValue, ReplacementMask); +} + + +template< typename T, typename U > +FORCEINLINE T PermuteVMX(T a, T b, U swizzleMask) +{ + return __vperm(a, b, swizzleMask); +} + +FORCEINLINE fltx4 ReplicateX4(float flValue) +{ + float* pValue = &flValue; + Assert(pValue); + Assert(((unsigned int)pValue & 3) == 0); + return __vspltw(__lvlx(pValue, 0), 0); +} + +FORCEINLINE fltx4 ReplicateX4(const float* pValue) +{ + Assert(pValue); + return __vspltw(__lvlx(pValue, 0), 0); +} + +FORCEINLINE fltx4 ReplicateIX4(int nValue) +{ + int* pValue = &nValue; + Assert(pValue); + Assert(((unsigned int)pValue & 3) == 0); + return __vspltw(__lvlx(pValue, 0), 0); +} + +FORCEINLINE fltx4 CeilSIMD(const fltx4& a) +{ + return __vrfip(a); +} + +FORCEINLINE fltx4 RoundSIMD(const fltx4& a) +{ + return __vrfin(a); +} + +FORCEINLINE fltx4 FloorSIMD(const fltx4& a) +{ + return __vrfim(a); +} + +FORCEINLINE fltx4 SqrtEstSIMD(const fltx4& a) +{ + return XMVectorSqrtEst(a); +} + +FORCEINLINE fltx4 SqrtSIMD(const fltx4& a) +{ + return XMVectorSqrt(a); +} + +FORCEINLINE fltx4 ReciprocalSqrtEstSIMD(const fltx4& a) +{ + return __vrsqrtefp(a); +} + +FORCEINLINE fltx4 ReciprocalSqrtEstSaturateSIMD(const fltx4& a) +{ + fltx4 zero_mask = CmpEqSIMD(a, Four_Zeros); + fltx4 a_safe = OrSIMD(a, AndSIMD(Four_Epsilons, zero_mask)); + return ReciprocalSqrtEstSIMD(a_safe); +} + +FORCEINLINE fltx4 ReciprocalSqrtSIMD(const fltx4& a) +{ + return XMVectorReciprocalSqrt(a); +} + +FORCEINLINE fltx4 ReciprocalEstSIMD(const fltx4& a) +{ + return __vrefp(a); +} + +FORCEINLINE fltx4 ReciprocalSIMD(const fltx4& a) +{ + return XMVectorReciprocal(a); +} + +FORCEINLINE fltx4 DivSIMD(const fltx4& a, const fltx4& b) +{ + return MulSIMD(ReciprocalSIMD(b), a); +} + +FORCEINLINE fltx4 DivEstSIMD(const fltx4& a, const fltx4& b) +{ + return MulSIMD(ReciprocalEstSIMD(b), a); +} + +FORCEINLINE fltx4 ReciprocalEstSaturateSIMD(const fltx4& a) +{ + fltx4 zero_mask = CmpEqSIMD(a, Four_Zeros); + fltx4 a_safe = OrSIMD(a, AndSIMD(Four_Epsilons, zero_mask)); + return ReciprocalEstSIMD(a_safe); +} + +FORCEINLINE fltx4 ReciprocalSaturateSIMD(const fltx4& a) +{ + fltx4 zero_mask = CmpEqSIMD(a, Four_Zeros); + fltx4 a_safe = OrSIMD(a, AndSIMD(Four_Epsilons, zero_mask)); + return ReciprocalSIMD(a_safe); + +} + +FORCEINLINE fltx4 ExpSIMD(const fltx4& toPower) +{ + return XMVectorExp(toPower); +} + +FORCEINLINE fltx4 Exp2EstSIMD(const fltx4& f) +{ + return XMVectorExpEst(f); +} + +FORCEINLINE fltx4 ClampVectorSIMD(FLTX4 in, FLTX4 min, FLTX4 max) +{ + return XMVectorClamp(in, min, max); +} + +FORCEINLINE fltx4 LoadUnalignedSIMD(const void* pSIMD) +{ + return XMLoadVector4(pSIMD); +} + +FORCEINLINE fltx4 LoadUnaligned3SIMD(const void* pSIMD) +{ + return XMLoadVector3(pSIMD); +} + +FORCEINLINE fltx4 LoadUnalignedFloatSIMD(const float* pFlt) +{ + return __lvlx(pFlt, 0); +} + +FORCEINLINE fltx4 LoadAlignedSIMD(const void* pSIMD) +{ + return *(reinterpret_cast (pSIMD)); +} + +FORCEINLINE fltx4 LoadAlignedSIMD(const VectorAligned& pSIMD) +{ + fltx4 out = XMLoadVector3A(pSIMD.Base()); + return __vrlimi(out, __vzero(), 1, 0); +} + +FORCEINLINE fltx4 LoadAlignedSIMD(const VectorAligned* RESTRICT pSIMD) +{ + fltx4 out = XMLoadVector3A(pSIMD); + return __vrlimi(out, __vzero(), 1, 0); +} + +FORCEINLINE void StoreAlignedSIMD(float* pSIMD, const fltx4& a) +{ + *(reinterpret_cast (pSIMD)) = a; +} + +FORCEINLINE void StoreUnalignedSIMD(float* pSIMD, const fltx4& a) +{ + XMStoreVector4(pSIMD, a); +} + +FORCEINLINE void StoreUnaligned3SIMD(float* pSIMD, const fltx4& a) +{ + XMStoreVector3(pSIMD, a); +} + +FORCEINLINE void StoreAligned3SIMD(VectorAligned* RESTRICT pSIMD, const fltx4& a) +{ + XMStoreVector3A(pSIMD->Base(), a); +} + +FORCEINLINE void StoreFourUnalignedVector3SIMD(fltx4 a, fltx4 b, fltx4 c, FLTX4 d, + Vector* const pDestination) +{ + b = __vrlimi(b, b, 15, 1); + c = __vrlimi(c, c, 15, 2); + + a = __vrlimi(a, b, 1, 0); + b = __vrlimi(b, c, 2 | 1, 0); + c = __vrlimi(c, d, 4 | 2 | 1, 3); + + float* RESTRICT pOut = pDestination->Base(); + StoreUnalignedSIMD(pOut + 0, a); + StoreUnalignedSIMD(pOut + 4, b); + StoreUnalignedSIMD(pOut + 8, c); +} + +FORCEINLINE void StoreFourAlignedVector3SIMD(fltx4 a, fltx4 b, fltx4 c, FLTX4 d, + Vector* const pDestination) +{ + b = __vrlimi(b, b, 15, 1); + c = __vrlimi(c, c, 15, 2); + + a = __vrlimi(a, b, 1, 0); + b = __vrlimi(b, c, 2 | 1, 0); + c = __vrlimi(c, d, 4 | 2 | 1, 3); + + float* RESTRICT pOut = pDestination->Base(); + StoreAlignedSIMD(pOut + 0, a); + StoreAlignedSIMD(pOut + 4, b); + StoreAlignedSIMD(pOut + 8, c); +} + +FORCEINLINE void ConvertStoreAsIntsSIMD(intx4* RESTRICT pDest, const fltx4& vSrc) +{ + fltx4 asInt = __vctsxs(vSrc, 0); + XMStoreVector4A(pDest->Base(), asInt); +} + +FORCEINLINE void TransposeSIMD(fltx4& x, fltx4& y, fltx4& z, fltx4& w) +{ + XMMATRIX xyzwMatrix = _XMMATRIX(x, y, z, w); + xyzwMatrix = XMMatrixTranspose(xyzwMatrix); + x = xyzwMatrix.r[0]; + y = xyzwMatrix.r[1]; + z = xyzwMatrix.r[2]; + w = xyzwMatrix.r[3]; +} + +FORCEINLINE fltx4 LoadZeroSIMD(void) +{ + return XMVectorZero(); +} + +FORCEINLINE fltx4 LoadOneSIMD(void) +{ + return XMVectorSplatOne(); +} + +FORCEINLINE fltx4 SplatXSIMD(fltx4 a) +{ + return XMVectorSplatX(a); +} + +FORCEINLINE fltx4 SplatYSIMD(fltx4 a) +{ + return XMVectorSplatY(a); +} + +FORCEINLINE fltx4 SplatZSIMD(fltx4 a) +{ + return XMVectorSplatZ(a); +} + +FORCEINLINE fltx4 SplatWSIMD(fltx4 a) +{ + return XMVectorSplatW(a); +} + +FORCEINLINE fltx4 SetXSIMD(const fltx4& a, const fltx4& x) +{ + fltx4 result = __vrlimi(a, x, 8, 0); + return result; +} + +FORCEINLINE fltx4 SetYSIMD(const fltx4& a, const fltx4& y) +{ + fltx4 result = __vrlimi(a, y, 4, 0); + return result; +} + +FORCEINLINE fltx4 SetZSIMD(const fltx4& a, const fltx4& z) +{ + fltx4 result = __vrlimi(a, z, 2, 0); + return result; +} + +FORCEINLINE fltx4 SetWSIMD(const fltx4& a, const fltx4& w) +{ + fltx4 result = __vrlimi(a, w, 1, 0); + return result; +} + +FORCEINLINE fltx4 SetComponentSIMD(const fltx4& a, int nComponent, float flValue) +{ + static int s_nVrlimiMask[4] = { 8, 4, 2, 1 }; + fltx4 val = ReplicateX4(flValue); + fltx4 result = __vrlimi(a, val, s_nVrlimiMask[nComponent], 0); + return result; +} + +FORCEINLINE fltx4 RotateLeft(const fltx4& a) +{ + fltx4 compareOne = a; + return __vrlimi(compareOne, a, 8 | 4 | 2 | 1, 1); +} + +FORCEINLINE fltx4 RotateLeft2(const fltx4& a) +{ + fltx4 compareOne = a; + return __vrlimi(compareOne, a, 8 | 4 | 2 | 1, 2); +} + +FORCEINLINE fltx4 RotateRight(const fltx4& a) +{ + fltx4 compareOne = a; + return __vrlimi(compareOne, a, 8 | 4 | 2 | 1, 3); +} + +FORCEINLINE fltx4 RotateRight2(const fltx4& a) +{ + fltx4 compareOne = a; + return __vrlimi(compareOne, a, 8 | 4 | 2 | 1, 2); +} + + +template < uint nBits > +FORCEINLINE fltx4 ShiftLeftByBits(const fltx4& a) +{ + if (nBits >= 128) + { + return LoadZeroSIMD(); + } + else if (nBits == 0) + { + return a; + } + else if ((nBits > 7)) + { + fltx4 t = __vsldoi(a, (LoadZeroSIMD()), (nBits >> 3)); + return ShiftLeftByBits< (nBits & 0x7) >(t); + } + else + { + u32x4 shifter = u32x4(__vspltisb(((signed char)(nBits & 0x7)))); + return __vsl(a, shifter); + } +} + +template < uint nBits > +FORCEINLINE fltx4 ShiftRightByBits(const fltx4& a) +{ + if (nBits >= 128) + { + return LoadZeroSIMD(); + } + else if (nBits == 0) + { + return a; + } + else if ((nBits > 7)) + { + fltx4 t = __vsldoi((LoadZeroSIMD()), a, 16 - (nBits >> 3)); + return ShiftRightByBits< (nBits & 0x7) >(t); + } + else + { + u32x4 shifter = u32x4(__vspltisb(((signed char)(nBits & 0x7)))); + return __vsr(a, shifter); + } +} + +FORCEINLINE fltx4 FindLowestSIMD3(const fltx4& a) +{ + fltx4 compareOne = a; + compareOne = __vrlimi(compareOne, a, 8 | 4, 1); + fltx4 retval = MinSIMD(a, compareOne); + compareOne = __vrlimi(compareOne, a, 8, 2); + retval = MinSIMD(retval, compareOne); + return SplatXSIMD(retval); +} + +FORCEINLINE fltx4 FindHighestSIMD3(const fltx4& a) +{ + fltx4 compareOne = a; + compareOne = __vrlimi(compareOne, a, 8 | 4, 1); + fltx4 retval = MaxSIMD(a, compareOne); + compareOne = __vrlimi(compareOne, a, 8, 2); + retval = MaxSIMD(retval, compareOne); + return SplatXSIMD(retval); +} + + +void TransformManyPointsBy(VectorAligned* RESTRICT pVectors, unsigned int numVectors, FLTX4 mRow1, FLTX4 mRow2, FLTX4 mRow3); + +FORCEINLINE void TransformManyPointsBy(VectorAligned* RESTRICT pVectors, unsigned int numVectors, const matrix3x4_t& pMatrix) +{ + return TransformManyPointsBy(pVectors, numVectors, + LoadUnalignedSIMD(pMatrix[0]), LoadUnalignedSIMD(pMatrix[1]), LoadUnalignedSIMD(pMatrix[2])); +} + +FORCEINLINE void TransformManyPointsByA(VectorAligned* RESTRICT pVectors, unsigned int numVectors, const matrix3x4_t& pMatrix) +{ + return TransformManyPointsBy(pVectors, numVectors, + LoadAlignedSIMD(pMatrix[0]), LoadAlignedSIMD(pMatrix[1]), LoadAlignedSIMD(pMatrix[2])); +} + +FORCEINLINE i32x4 LoadAlignedIntSIMD(const void* RESTRICT pSIMD) +{ + return XMLoadVector4A(pSIMD); +} + +FORCEINLINE i32x4 LoadUnalignedIntSIMD(const void* RESTRICT pSIMD) +{ + return XMLoadVector4(pSIMD); +} + +FORCEINLINE void StoreAlignedIntSIMD(int32* pSIMD, const fltx4& a) +{ + *(reinterpret_cast (pSIMD)) = a; +} + +FORCEINLINE void StoreAlignedIntSIMD(intx4& pSIMD, const fltx4& a) +{ + *(reinterpret_cast (pSIMD.Base())) = a; +} + +FORCEINLINE void StoreUnalignedIntSIMD(int32* pSIMD, const fltx4& a) +{ + XMStoreVector4(pSIMD, a); +} + +FORCEINLINE fltx4 LoadAndConvertUint16SIMD(const uint16* pInts) +{ + return XMLoadUShort4(reinterpret_cast(pInts)); +} + +FORCEINLINE fltx4 CompressSIMD(fltx4 const& a, fltx4 const& b) +{ + return XMVectorPermute(a, b, XMVectorPermuteControl(0, 2, 4, 6)); +} + +FORCEINLINE fltx4 Compress4SIMD(fltx4 const a, fltx4 const& b, fltx4 const& c, fltx4 const& d) +{ + fltx4 abcd = __vrlimi(a, b, 4, 3); + abcd = __vrlimi(abcd, c, 2, 2); + abcd = __vrlimi(abcd, d, 1, 1); + + return abcd; +} + + +FORCEINLINE fltx4 LoadGatherSIMD(const float& x, const float& y, const float& z, const float& w) +{ + fltx4 vx = __lvlx(&x, 0); + fltx4 vy = __lvlx(&y, 0); + fltx4 vz = __lvlx(&z, 0); + fltx4 vw = __lvlx(&w, 0); + return Compress4SIMD(vx, vy, vz, vw); +} + +FORCEINLINE fltx4 UnsignedIntConvertToFltSIMD(const i32x4& vSrcA) +{ + return __vcfux(vSrcA, 0); +} + +FORCEINLINE fltx4 SignedIntConvertToFltSIMD(const i32x4& vSrcA) +{ + return __vcfsx(vSrcA, 0); +} + +#define UnsignedFixedIntConvertToFltSIMD(vSrcA, uImmed) (__vcfux( (vSrcA), (uImmed) )) + +#define SignedFixedIntConvertToFltSIMD(vSrcA, uImmed) (__vcfsx( (vSrcA), (uImmed) )) + +#define IntSetImmediateSIMD(x) (__vspltisw(x)) + +FORCEINLINE fltx4 IntShiftLeftWordSIMD(fltx4 vSrcA, fltx4 vSrcB) +{ + return __vslw(vSrcA, vSrcB); +} + +FORCEINLINE float SubFloat(const fltx4& a, int idx) +{ + const fltx4_union& a_union = (const fltx4_union&)a; + return a_union.m128_f32[idx]; +} + +FORCEINLINE float& SubFloat(fltx4& a, int idx) +{ + fltx4_union& a_union = (fltx4_union&)a; + return a_union.m128_f32[idx]; +} + +FORCEINLINE uint32 SubFloatConvertToInt(const fltx4& a, int idx) +{ + fltx4 t = __vctuxs(a, 0); + const fltx4_union& a_union = (const fltx4_union&)t; + return a_union.m128_u32[idx]; +} + + +FORCEINLINE uint32 SubInt(const fltx4& a, int idx) +{ + const fltx4_union& a_union = (const fltx4_union&)a; + return a_union.m128_u32[idx]; +} + +FORCEINLINE uint32& SubInt(fltx4& a, int idx) +{ + fltx4_union& a_union = (fltx4_union&)a; + return a_union.m128_u32[idx]; +} + +#else + +FORCEINLINE void StoreAlignedSIMD(float* RESTRICT pSIMD, const fltx4& a) +{ + _mm_store_ps(pSIMD, a); +} + +FORCEINLINE void StoreAlignedSIMD(short* RESTRICT pSIMD, const shortx8& a) +{ + _mm_store_si128((shortx8*)pSIMD, a); +} +FORCEINLINE void StoreUnalignedSIMD(float* RESTRICT pSIMD, const fltx4& a) +{ + _mm_storeu_ps(pSIMD, a); +} + +FORCEINLINE void StoreUnalignedSIMD(short* RESTRICT pSIMD, const shortx8& a) +{ + _mm_storeu_si128((shortx8*)pSIMD, a); +} + +FORCEINLINE void StoreUnalignedFloat(float* pSingleFloat, const fltx4& a) +{ + _mm_store_ss(pSingleFloat, a); +} + + +FORCEINLINE fltx4 RotateLeft(const fltx4& a); +FORCEINLINE fltx4 RotateLeft2(const fltx4& a); + +FORCEINLINE void StoreUnaligned3SIMD(float* pSIMD, const fltx4& a) +{ + _mm_store_ss(pSIMD, a); + _mm_store_ss(pSIMD + 1, RotateLeft(a)); + _mm_store_ss(pSIMD + 2, RotateLeft2(a)); +} + + +FORCEINLINE void StoreAligned3SIMD(VectorAligned* RESTRICT pSIMD, const fltx4& a) +{ + StoreAlignedSIMD(pSIMD->Base(), a); +} + +FORCEINLINE void StoreFourUnalignedVector3SIMD(fltx4 a, fltx4 b, fltx4 c, FLTX4 d, + Vector* const pDestination) +{ + StoreUnaligned3SIMD(pDestination->Base(), a); + StoreUnaligned3SIMD((pDestination + 1)->Base(), b); + StoreUnaligned3SIMD((pDestination + 2)->Base(), c); + StoreUnaligned3SIMD((pDestination + 3)->Base(), d); +} + +FORCEINLINE void StoreFourAlignedVector3SIMD(fltx4 a, fltx4 b, fltx4 c, FLTX4 d, + Vector* const pDestination) +{ + StoreUnaligned3SIMD(pDestination->Base(), a); + StoreUnaligned3SIMD((pDestination + 1)->Base(), b); + StoreUnaligned3SIMD((pDestination + 2)->Base(), c); + StoreUnaligned3SIMD((pDestination + 3)->Base(), d); +} + +FORCEINLINE fltx4 LoadAlignedSIMD(const void* pSIMD) +{ + return _mm_load_ps(reinterpret_cast (pSIMD)); +} + +FORCEINLINE shortx8 LoadAlignedShortSIMD(const void* pSIMD) +{ + return _mm_load_si128(reinterpret_cast (pSIMD)); +} + +FORCEINLINE shortx8 LoadUnalignedShortSIMD(const void* pSIMD) +{ + return _mm_loadu_si128(reinterpret_cast (pSIMD)); +} + +FORCEINLINE fltx4 AndSIMD(const fltx4& a, const fltx4& b) +{ + return _mm_and_ps(a, b); +} + +FORCEINLINE fltx4 AndNotSIMD(const fltx4& a, const fltx4& b) +{ + return _mm_andnot_ps(a, b); +} + +FORCEINLINE fltx4 XorSIMD(const fltx4& a, const fltx4& b) +{ + return _mm_xor_ps(a, b); +} + +FORCEINLINE fltx4 OrSIMD(const fltx4& a, const fltx4& b) +{ + return _mm_or_ps(a, b); +} + +FORCEINLINE fltx4 SetWToZeroSIMD(const fltx4& a) +{ + return AndSIMD(a, LoadAlignedSIMD(g_SIMD_clear_wmask)); +} + +FORCEINLINE fltx4 LoadAlignedSIMD(const VectorAligned& pSIMD) +{ + return SetWToZeroSIMD(LoadAlignedSIMD(pSIMD.Base())); +} + +FORCEINLINE fltx4 LoadUnalignedSIMD(const void* pSIMD) +{ + return _mm_loadu_ps(reinterpret_cast(pSIMD)); +} + +FORCEINLINE fltx4 LoadUnaligned3SIMD(const void* pSIMD) +{ + return _mm_loadu_ps(reinterpret_cast(pSIMD)); +} + +FORCEINLINE fltx4 LoadUnalignedFloatSIMD(const float* pFlt) +{ + return _mm_load_ss(pFlt); +} + +FORCEINLINE fltx4 ReplicateIX4(int i) +{ + fltx4 value = _mm_set_ss(*((float*)&i));; + return _mm_shuffle_ps(value, value, 0); +} + + +FORCEINLINE fltx4 ReplicateX4(float flValue) +{ + __m128 value = _mm_set_ss(flValue); + return _mm_shuffle_ps(value, value, 0); +} + +FORCEINLINE fltx4 ReplicateX4(const float* flValue) +{ + __m128 value = _mm_set_ss(*flValue); + return _mm_shuffle_ps(value, value, 0); +} + +FORCEINLINE float SubFloat(const fltx4& a, int idx) +{ +#ifndef POSIX + return a.m128_f32[idx]; +#else + return (reinterpret_cast(&a))[idx]; +#endif +} + +FORCEINLINE float& SubFloat(fltx4& a, int idx) +{ +#ifndef POSIX + return a.m128_f32[idx]; +#else + return (reinterpret_cast(&a))[idx]; +#endif +} + +FORCEINLINE uint32 SubFloatConvertToInt(const fltx4& a, int idx) +{ + return (uint32)SubFloat(a, idx); +} + +FORCEINLINE uint32 SubInt(const fltx4& a, int idx) +{ +#ifndef POSIX + return a.m128_u32[idx]; +#else + return (reinterpret_cast(&a))[idx]; +#endif +} + +FORCEINLINE uint32& SubInt(fltx4& a, int idx) +{ +#ifndef POSIX + return a.m128_u32[idx]; +#else + return (reinterpret_cast(&a))[idx]; +#endif +} + +FORCEINLINE fltx4 LoadZeroSIMD(void) +{ + return Four_Zeros; +} + +FORCEINLINE fltx4 LoadOneSIMD(void) +{ + return Four_Ones; +} + +FORCEINLINE fltx4 MaskedAssign(const fltx4& ReplacementMask, const fltx4& NewValue, const fltx4& OldValue) +{ + return OrSIMD( + AndSIMD(ReplacementMask, NewValue), + AndNotSIMD(ReplacementMask, OldValue)); +} + +#define MM_SHUFFLE_REV(a,b,c,d) _MM_SHUFFLE(d,c,b,a) + +FORCEINLINE fltx4 SplatXSIMD(fltx4 const& a) +{ + return _mm_shuffle_ps(a, a, MM_SHUFFLE_REV(0, 0, 0, 0)); +} + +FORCEINLINE fltx4 SplatYSIMD(fltx4 const& a) +{ + return _mm_shuffle_ps(a, a, MM_SHUFFLE_REV(1, 1, 1, 1)); +} + +FORCEINLINE fltx4 SplatZSIMD(fltx4 const& a) +{ + return _mm_shuffle_ps(a, a, MM_SHUFFLE_REV(2, 2, 2, 2)); +} + +FORCEINLINE fltx4 SplatWSIMD(fltx4 const& a) +{ + return _mm_shuffle_ps(a, a, MM_SHUFFLE_REV(3, 3, 3, 3)); +} + +FORCEINLINE fltx4 ShuffleXXYY(const fltx4& a) +{ + return _mm_shuffle_ps(a, a, MM_SHUFFLE_REV(0, 0, 1, 1)); +} + +FORCEINLINE fltx4 ShuffleXYXY(const fltx4& a) +{ + return _mm_shuffle_ps(a, a, MM_SHUFFLE_REV(0, 1, 0, 1)); +} + +FORCEINLINE fltx4 ShuffleZZWW(const fltx4& a) +{ + return _mm_shuffle_ps(a, a, MM_SHUFFLE_REV(2, 2, 3, 3)); +} + + + + +FORCEINLINE fltx4 SetXSIMD(const fltx4& a, const fltx4& x) +{ + fltx4 result = MaskedAssign(LoadAlignedSIMD(g_SIMD_ComponentMask[0]), x, a); + return result; +} + +FORCEINLINE fltx4 SetYSIMD(const fltx4& a, const fltx4& y) +{ + fltx4 result = MaskedAssign(LoadAlignedSIMD(g_SIMD_ComponentMask[1]), y, a); + return result; +} + +FORCEINLINE fltx4 SetZSIMD(const fltx4& a, const fltx4& z) +{ + fltx4 result = MaskedAssign(LoadAlignedSIMD(g_SIMD_ComponentMask[2]), z, a); + return result; +} + +FORCEINLINE fltx4 SetWSIMD(const fltx4& a, const fltx4& w) +{ + fltx4 result = MaskedAssign(LoadAlignedSIMD(g_SIMD_ComponentMask[3]), w, a); + return result; +} + +FORCEINLINE fltx4 SetComponentSIMD(const fltx4& a, int nComponent, float flValue) +{ + fltx4 val = ReplicateX4(flValue); + fltx4 result = MaskedAssign(LoadAlignedSIMD(g_SIMD_ComponentMask[nComponent]), val, a); + return result; +} + +FORCEINLINE fltx4 RotateLeft(const fltx4& a) +{ + return _mm_shuffle_ps(a, a, MM_SHUFFLE_REV(1, 2, 3, 0)); +} + +FORCEINLINE fltx4 RotateLeft2(const fltx4& a) +{ + return _mm_shuffle_ps(a, a, MM_SHUFFLE_REV(2, 3, 0, 1)); +} + +FORCEINLINE fltx4 RotateRight(const fltx4& a) +{ + return _mm_shuffle_ps(a, a, MM_SHUFFLE_REV(3, 0, 1, 2)); +} + +FORCEINLINE fltx4 RotateRight2(const fltx4& a) +{ + return _mm_shuffle_ps(a, a, MM_SHUFFLE_REV(2, 3, 0, 1)); +} + +FORCEINLINE fltx4 AddSIMD(const fltx4& a, const fltx4& b) +{ + return _mm_add_ps(a, b); +} + +FORCEINLINE fltx4 SubSIMD(const fltx4& a, const fltx4& b) +{ + return _mm_sub_ps(a, b); +}; + +FORCEINLINE fltx4 MulSIMD(const fltx4& a, const fltx4& b) +{ + return _mm_mul_ps(a, b); +}; + +FORCEINLINE fltx4 DivSIMD(const fltx4& a, const fltx4& b) +{ + return _mm_div_ps(a, b); +}; + +fltx4 ReciprocalEstSIMD(const fltx4& a); +FORCEINLINE fltx4 DivEstSIMD(const fltx4& a, const fltx4& b) +{ + return MulSIMD(ReciprocalEstSIMD(b), a); +}; + +FORCEINLINE fltx4 MaddSIMD(const fltx4& a, const fltx4& b, const fltx4& c) +{ + return AddSIMD(MulSIMD(a, b), c); +} + +FORCEINLINE fltx4 MsubSIMD(const fltx4& a, const fltx4& b, const fltx4& c) +{ + return SubSIMD(c, MulSIMD(a, b)); +}; + +FORCEINLINE fltx4 Dot3SIMD(const fltx4& a, const fltx4& b) +{ + fltx4 m = MulSIMD(a, b); + return AddSIMD(AddSIMD(SplatXSIMD(m), SplatYSIMD(m)), SplatZSIMD(m)); +} + +FORCEINLINE fltx4 Dot4SIMD(const fltx4& a, const fltx4& b) +{ + fltx4 fl4Product = MulSIMD(a, b); + fltx4 fl4YXWZ = _mm_shuffle_ps(fl4Product, fl4Product, MM_SHUFFLE_REV(1, 0, 3, 2)); + fltx4 fl4UUVV = AddSIMD(fl4Product, fl4YXWZ); + fltx4 fl4VVUU = RotateLeft2(fl4UUVV); + return AddSIMD(fl4UUVV, fl4VVUU); +} + +FORCEINLINE fltx4 SinSIMD(const fltx4& radians) +{ + fltx4 result; + SubFloat(result, 0) = sin(SubFloat(radians, 0)); + SubFloat(result, 1) = sin(SubFloat(radians, 1)); + SubFloat(result, 2) = sin(SubFloat(radians, 2)); + SubFloat(result, 3) = sin(SubFloat(radians, 3)); + return result; +} + +FORCEINLINE void SinCos3SIMD(fltx4& sine, fltx4& cosine, const fltx4& radians) +{ + SinCos(SubFloat(radians, 0), &SubFloat(sine, 0), &SubFloat(cosine, 0)); + SinCos(SubFloat(radians, 1), &SubFloat(sine, 1), &SubFloat(cosine, 1)); + SinCos(SubFloat(radians, 2), &SubFloat(sine, 2), &SubFloat(cosine, 2)); +} + +FORCEINLINE void SinCosSIMD(fltx4& sine, fltx4& cosine, const fltx4& radians) +{ + SinCos(SubFloat(radians, 0), &SubFloat(sine, 0), &SubFloat(cosine, 0)); + SinCos(SubFloat(radians, 1), &SubFloat(sine, 1), &SubFloat(cosine, 1)); + SinCos(SubFloat(radians, 2), &SubFloat(sine, 2), &SubFloat(cosine, 2)); + SinCos(SubFloat(radians, 3), &SubFloat(sine, 3), &SubFloat(cosine, 3)); +} + +FORCEINLINE fltx4 ArcSinSIMD(const fltx4& sine) +{ + fltx4 result; + SubFloat(result, 0) = asin(SubFloat(sine, 0)); + SubFloat(result, 1) = asin(SubFloat(sine, 1)); + SubFloat(result, 2) = asin(SubFloat(sine, 2)); + SubFloat(result, 3) = asin(SubFloat(sine, 3)); + return result; +} + +FORCEINLINE fltx4 ArcCosSIMD(const fltx4& cs) +{ + fltx4 result; + SubFloat(result, 0) = acos(SubFloat(cs, 0)); + SubFloat(result, 1) = acos(SubFloat(cs, 1)); + SubFloat(result, 2) = acos(SubFloat(cs, 2)); + SubFloat(result, 3) = acos(SubFloat(cs, 3)); + return result; +} + +FORCEINLINE fltx4 ArcTan2SIMD(const fltx4& a, const fltx4& b) +{ + fltx4 result; + SubFloat(result, 0) = atan2(SubFloat(a, 0), SubFloat(b, 0)); + SubFloat(result, 1) = atan2(SubFloat(a, 1), SubFloat(b, 1)); + SubFloat(result, 2) = atan2(SubFloat(a, 2), SubFloat(b, 2)); + SubFloat(result, 3) = atan2(SubFloat(a, 3), SubFloat(b, 3)); + return result; +} + +FORCEINLINE fltx4 NegSIMD(const fltx4& a) +{ + return SubSIMD(LoadZeroSIMD(), a); +} + +FORCEINLINE int TestSignSIMD(const fltx4& a) +{ + return _mm_movemask_ps(a); +} + +FORCEINLINE bool IsAnyNegative(const fltx4& a) +{ + return (0 != TestSignSIMD(a)); +} + +FORCEINLINE bool IsAnyTrue(const fltx4& a) +{ + return (0 != TestSignSIMD(a)); +} + +FORCEINLINE fltx4 CmpEqSIMD(const fltx4& a, const fltx4& b) +{ + return _mm_cmpeq_ps(a, b); +} + +FORCEINLINE fltx4 CmpGtSIMD(const fltx4& a, const fltx4& b) +{ + return _mm_cmpgt_ps(a, b); +} + +FORCEINLINE fltx4 CmpGeSIMD(const fltx4& a, const fltx4& b) +{ + return _mm_cmpge_ps(a, b); +} + +FORCEINLINE fltx4 CmpLtSIMD(const fltx4& a, const fltx4& b) +{ + return _mm_cmplt_ps(a, b); +} + +FORCEINLINE fltx4 CmpLeSIMD(const fltx4& a, const fltx4& b) +{ + return _mm_cmple_ps(a, b); +} + +FORCEINLINE bool IsAllGreaterThan(const fltx4& a, const fltx4& b) +{ + return TestSignSIMD(CmpLeSIMD(a, b)) == 0; +} + +FORCEINLINE bool IsAllGreaterThanOrEq(const fltx4& a, const fltx4& b) +{ + return TestSignSIMD(CmpLtSIMD(a, b)) == 0; +} + +FORCEINLINE bool IsAllEqual(const fltx4& a, const fltx4& b) +{ + return TestSignSIMD(CmpEqSIMD(a, b)) == 0xf; +} + +FORCEINLINE fltx4 CmpInBoundsSIMD(const fltx4& a, const fltx4& b) +{ + return AndSIMD(CmpLeSIMD(a, b), CmpGeSIMD(a, NegSIMD(b))); +} + +FORCEINLINE fltx4 MinSIMD(const fltx4& a, const fltx4& b) +{ + return _mm_min_ps(a, b); +} + +FORCEINLINE fltx4 MaxSIMD(const fltx4& a, const fltx4& b) +{ + return _mm_max_ps(a, b); +} + + + +FORCEINLINE fltx4 CeilSIMD(const fltx4& a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = ceil(SubFloat(a, 0)); + SubFloat(retVal, 1) = ceil(SubFloat(a, 1)); + SubFloat(retVal, 2) = ceil(SubFloat(a, 2)); + SubFloat(retVal, 3) = ceil(SubFloat(a, 3)); + return retVal; + +} + +fltx4 AbsSIMD(const fltx4& x); +fltx4 fabs(const fltx4& x); + +FORCEINLINE fltx4 FloorSIMD(const fltx4& val) +{ + fltx4 fl4Abs = fabs(val); + fltx4 ival = SubSIMD(AddSIMD(fl4Abs, Four_2ToThe23s), Four_2ToThe23s); + ival = MaskedAssign(CmpGtSIMD(ival, fl4Abs), SubSIMD(ival, Four_Ones), ival); + return XorSIMD(ival, XorSIMD(val, fl4Abs)); +} + + + +FORCEINLINE bool IsAnyZeros(const fltx4& a) +{ + return TestSignSIMD(CmpEqSIMD(a, Four_Zeros)) != 0; +} + +inline bool IsAllZeros(const fltx4& var) +{ + return TestSignSIMD(CmpEqSIMD(var, Four_Zeros)) == 0xF; +} + +FORCEINLINE fltx4 SqrtEstSIMD(const fltx4& a) +{ + return _mm_sqrt_ps(a); +} + +FORCEINLINE fltx4 SqrtSIMD(const fltx4& a) +{ + return _mm_sqrt_ps(a); +} + +FORCEINLINE fltx4 ReciprocalSqrtEstSIMD(const fltx4& a) +{ + return _mm_rsqrt_ps(a); +} + +FORCEINLINE fltx4 ReciprocalSqrtEstSaturateSIMD(const fltx4& a) +{ + fltx4 zero_mask = CmpEqSIMD(a, Four_Zeros); + fltx4 ret = OrSIMD(a, AndSIMD(Four_Epsilons, zero_mask)); + ret = ReciprocalSqrtEstSIMD(ret); + return ret; +} + +FORCEINLINE fltx4 ReciprocalSqrtSIMD(const fltx4& a) +{ + fltx4 guess = ReciprocalSqrtEstSIMD(a); + guess = MulSIMD(guess, SubSIMD(Four_Threes, MulSIMD(a, MulSIMD(guess, guess)))); + guess = MulSIMD(Four_PointFives, guess); + return guess; +} + +FORCEINLINE fltx4 ReciprocalEstSIMD(const fltx4& a) +{ + return _mm_rcp_ps(a); +} + +FORCEINLINE fltx4 ReciprocalEstSaturateSIMD(const fltx4& a) +{ + fltx4 zero_mask = CmpEqSIMD(a, Four_Zeros); + fltx4 ret = OrSIMD(a, AndSIMD(Four_Epsilons, zero_mask)); + ret = ReciprocalEstSIMD(ret); + return ret; +} + +FORCEINLINE fltx4 ReciprocalSIMD(const fltx4& a) +{ + fltx4 ret = ReciprocalEstSIMD(a); + ret = SubSIMD(AddSIMD(ret, ret), MulSIMD(a, MulSIMD(ret, ret))); + return ret; +} + +FORCEINLINE fltx4 ReciprocalSaturateSIMD(const fltx4& a) +{ + fltx4 zero_mask = CmpEqSIMD(a, Four_Zeros); + fltx4 ret = OrSIMD(a, AndSIMD(Four_Epsilons, zero_mask)); + ret = ReciprocalSIMD(ret); + return ret; +} + +FORCEINLINE fltx4 ExpSIMD(const fltx4& toPower) +{ + fltx4 retval; + SubFloat(retval, 0) = powf(2, SubFloat(toPower, 0)); + SubFloat(retval, 1) = powf(2, SubFloat(toPower, 1)); + SubFloat(retval, 2) = powf(2, SubFloat(toPower, 2)); + SubFloat(retval, 3) = powf(2, SubFloat(toPower, 3)); + + return retval; +} + +FORCEINLINE fltx4 ClampVectorSIMD(FLTX4 in, FLTX4 min, FLTX4 max) +{ + return MaxSIMD(min, MinSIMD(max, in)); +} + +FORCEINLINE void TransposeSIMD(fltx4& x, fltx4& y, fltx4& z, fltx4& w) +{ + _MM_TRANSPOSE4_PS(x, y, z, w); +} + +FORCEINLINE fltx4 FindLowestSIMD3(const fltx4& a) +{ + fltx4 compareOne = RotateLeft(a); + fltx4 retval = MinSIMD(a, compareOne); + compareOne = RotateLeft2(a); + retval = MinSIMD(retval, compareOne); + return SplatXSIMD(retval); + +} + +FORCEINLINE fltx4 FindHighestSIMD3(const fltx4& a) +{ + fltx4 compareOne = RotateLeft(a); + fltx4 retval = MaxSIMD(a, compareOne); + compareOne = RotateLeft2(a); + retval = MaxSIMD(retval, compareOne); + return SplatXSIMD(retval); + +} + + +inline bool IsVector3LessThan(const fltx4& v1, const fltx4& v2) +{ + bi32x4 isOut = CmpLtSIMD(v1, v2); + return IsAnyNegative(isOut); +} + +inline bool IsVector4LessThan(const fltx4& v1, const fltx4& v2) +{ + bi32x4 isOut = CmpLtSIMD(v1, v2); + return IsAnyNegative(isOut); +} + + + +#if 0 +FORCEINLINE fltx4 IntSetImmediateSIMD(int to) +{ + fltx4 retval; + SubInt(retval, 0) = to; + SubInt(retval, 1) = to; + SubInt(retval, 2) = to; + SubInt(retval, 3) = to; + return retval; +} +#endif + +FORCEINLINE i32x4 LoadAlignedIntSIMD(const void* RESTRICT pSIMD) +{ + return _mm_load_ps(reinterpret_cast(pSIMD)); +} + +FORCEINLINE i32x4 LoadUnalignedIntSIMD(const void* RESTRICT pSIMD) +{ + return _mm_loadu_ps(reinterpret_cast(pSIMD)); +} + +FORCEINLINE void StoreAlignedIntSIMD(int32* RESTRICT pSIMD, const fltx4& a) +{ + _mm_store_ps(reinterpret_cast(pSIMD), a); +} + +FORCEINLINE void StoreAlignedIntSIMD(intx4& pSIMD, const fltx4& a) +{ + _mm_store_ps(reinterpret_cast(pSIMD.Base()), a); +} + +FORCEINLINE void StoreUnalignedIntSIMD(int32* RESTRICT pSIMD, const fltx4& a) +{ + _mm_storeu_ps(reinterpret_cast(pSIMD), a); +} + +FORCEINLINE fltx4 CompressSIMD(fltx4 const& a, fltx4 const& b) +{ + return _mm_shuffle_ps(a, b, MM_SHUFFLE_REV(0, 2, 0, 2)); +} + +FORCEINLINE fltx4 LoadAndConvertUint16SIMD(const uint16* pInts) +{ +#ifdef POSIX + fltx4 retval; + SubFloat(retval, 0) = pInts[0]; + SubFloat(retval, 1) = pInts[1]; + SubFloat(retval, 2) = pInts[2]; + SubFloat(retval, 3) = pInts[3]; + return retval; +#else + __m128i inA = _mm_loadl_epi64((__m128i const*) pInts); + inA = _mm_unpacklo_epi16(inA, _mm_setzero_si128()); + return _mm_cvtepi32_ps(inA); +#endif +} + + +FORCEINLINE fltx4 Compress4SIMD(fltx4 const a, fltx4 const& b, fltx4 const& c, fltx4 const& d) +{ + fltx4 aacc = _mm_shuffle_ps(a, c, MM_SHUFFLE_REV(0, 0, 0, 0)); + fltx4 bbdd = _mm_shuffle_ps(b, d, MM_SHUFFLE_REV(0, 0, 0, 0)); + return MaskedAssign(LoadAlignedSIMD(g_SIMD_EveryOtherMask), bbdd, aacc); +} + +FORCEINLINE void ExpandSIMD(fltx4 const& a, fltx4& fl4OutA, fltx4& fl4OutB) +{ + fl4OutA = _mm_shuffle_ps(a, a, MM_SHUFFLE_REV(0, 0, 1, 1)); + fl4OutB = _mm_shuffle_ps(a, a, MM_SHUFFLE_REV(2, 2, 3, 3)); + +} + + +FORCEINLINE fltx4 LoadGatherSIMD(const float& x, const float& y, const float& z, const float& w) +{ + fltx4 vx = _mm_load_ss(&x); + fltx4 vy = _mm_load_ss(&y); + fltx4 vz = _mm_load_ss(&z); + fltx4 vw = _mm_load_ss(&w); + return Compress4SIMD(vx, vy, vz, vw); +} + +FORCEINLINE fltx4 UnsignedIntConvertToFltSIMD(const u32x4& vSrcA) +{ + fltx4 retval; + SubFloat(retval, 0) = ((float)SubInt(retval, 0)); + SubFloat(retval, 1) = ((float)SubInt(retval, 1)); + SubFloat(retval, 2) = ((float)SubInt(retval, 2)); + SubFloat(retval, 3) = ((float)SubInt(retval, 3)); + return retval; +} + +FORCEINLINE fltx4 SignedIntConvertToFltSIMD(const i32x4& vSrcA) +{ + return _mm_cvtepi32_ps((const __m128i&)vSrcA); +} + +FORCEINLINE fltx4 SignedIntConvertToFltSIMD(const shortx8& vSrcA) +{ + return _mm_cvtepi32_ps(vSrcA); +} + +#if 0 +FORCEINLINE fltx4 SignedIntConvertToFltSIMD(const i32x4& vSrcA) +{ + fltx4 retval; + SubFloat(retval, 0) = ((float)(reinterpret_cast(&vSrcA)[0])); + SubFloat(retval, 1) = ((float)(reinterpret_cast(&vSrcA)[1])); + SubFloat(retval, 2) = ((float)(reinterpret_cast(&vSrcA)[2])); + SubFloat(retval, 3) = ((float)(reinterpret_cast(&vSrcA)[3])); + return retval; +} + +#endif + +FORCEINLINE i32x4 IntShiftLeftWordSIMD(const i32x4& vSrcA, const i32x4& vSrcB) +{ + i32x4 retval; + SubInt(retval, 0) = SubInt(vSrcA, 0) << SubInt(vSrcB, 0); + SubInt(retval, 1) = SubInt(vSrcA, 1) << SubInt(vSrcB, 1); + SubInt(retval, 2) = SubInt(vSrcA, 2) << SubInt(vSrcB, 2); + SubInt(retval, 3) = SubInt(vSrcA, 3) << SubInt(vSrcB, 3); + + + return retval; +} + + +FORCEINLINE void ConvertStoreAsIntsSIMD(intx4* RESTRICT pDest, const fltx4& vSrc) +{ +#if defined(_MSC_VER) && _MSC_VER >= 1900 && defined(COMPILER_MSVC64) + (*pDest)[0] = (int)SubFloat(vSrc, 0); + (*pDest)[1] = (int)SubFloat(vSrc, 1); + (*pDest)[2] = (int)SubFloat(vSrc, 2); + (*pDest)[3] = (int)SubFloat(vSrc, 3); +#else + __m64 bottom = _mm_cvttps_pi32(vSrc); + __m64 top = _mm_cvttps_pi32(_mm_movehl_ps(vSrc, vSrc)); + + *reinterpret_cast<__m64*>(&(*pDest)[0]) = bottom; + *reinterpret_cast<__m64*>(&(*pDest)[2]) = top; + + _mm_empty(); +#endif +} + + + +#endif + +FORCEINLINE void RotateLeftDoubleSIMD(fltx4& a, fltx4& b) +{ + a = SetWSIMD(RotateLeft(a), SplatXSIMD(b)); + b = RotateLeft(b); +} + + +#if !defined(PLATFORM_PPC) && !defined( POSIX ) && !defined(SPU) +#if 1 +FORCEINLINE fltx4 operator+(FLTX4 a, FLTX4 b) +{ + return AddSIMD(a, b); +} + +FORCEINLINE fltx4 operator-(FLTX4 a, FLTX4 b) +{ + return SubSIMD(a, b); +} + +FORCEINLINE fltx4 operator*(FLTX4 a, FLTX4 b) +{ + return MulSIMD(a, b); +} + +FORCEINLINE fltx4 operator&(FLTX4 a, FLTX4 b) +{ + return AndSIMD(a, b); +} + +FORCEINLINE fltx4 operator|(FLTX4 a, FLTX4 b) +{ + return OrSIMD(a, b); +} + +FORCEINLINE fltx4 operator^(FLTX4 a, FLTX4 b) +{ + return XorSIMD(a, b); +} + +FORCEINLINE fltx4 operator-(FLTX4 a) +{ + return NegSIMD(a); +} +#endif +#endif + +#if defined(_X360) || defined(_PS3) +FORCEINLINE fltx4 VectorMergeHighSIMD(fltx4 fl4SrcA, fltx4 fl4SrcB) +{ +#if defined( _X360 ) + return __vmrghw(fl4SrcA, fl4SrcB); +#else + return vec_mergeh(fl4SrcA, fl4SrcB); +#endif +} + +FORCEINLINE fltx4 VectorMergeLowSIMD(fltx4 fl4SrcA, fltx4 fl4SrcB) +{ +#if defined( _X360 ) + return __vmrglw(fl4SrcA, fl4SrcB); +#else + return vec_mergel(fl4SrcA, fl4SrcB); +#endif +} +#endif + +#ifndef SPU +struct ALIGN16 fourplanes_t +{ + fltx4 nX; + fltx4 nY; + fltx4 nZ; + fltx4 dist; + bi32x4 xSign; + bi32x4 ySign; + bi32x4 zSign; + fltx4 nXAbs; + fltx4 nYAbs; + fltx4 nZAbs; + + void ComputeSignbits(); + + void Set4Planes(const VPlane* pPlanes); + void Set2Planes(const VPlane* pPlanes); + void Get4Planes(VPlane* pPlanesOut) const; + void Get2Planes(VPlane* pPlanesOut) const; + void GetPlane(int index, Vector* pNormal, float* pDist) const; + void SetPlane(int index, const Vector& vecNormal, float planeDist); +}; + +class ALIGN16 Frustum_t +{ +public: + Frustum_t(); + void SetPlane(int i, const Vector& vecNormal, float dist); + void GetPlane(int i, Vector* pNormalOut, float* pDistOut) const; + void SetPlanes(const VPlane* pPlanes); + void GetPlanes(VPlane* pPlanesOut) const; + bool CullBox(const Vector& mins, const Vector& maxs) const; + bool CullBoxCenterExtents(const Vector& center, const Vector& extents) const; + + bool CullBox(const fltx4& fl4Mins, const fltx4& fl4Maxs) const; + bool CullBoxCenterExtents(const fltx4& fl4Center, const fltx4& fl4Extents) const; + + + bool Contains(const Vector& mins, const Vector& maxs) const; + + bool Intersects(Frustum_t& otherFrustum) const; + + bool Intersects(const Vector& mins, const Vector& maxs) const; + bool IntersectsCenterExtents(const Vector& center, const Vector& extents) const; + + bool Intersects(const fltx4& fl4Mins, const fltx4& fl4Maxs) const; + bool IntersectsCenterExtents(const fltx4& fl4Center, const fltx4& fl4Extents) const; + + + void CreatePerspectiveFrustum(const Vector& origin, const Vector& forward, + const Vector& right, const Vector& up, float flZNear, float flZFar, + float flFovX, float flAspect); + + void CreatePerspectiveFrustumFLU(const Vector& vOrigin, const Vector& vForward, + const Vector& vLeft, const Vector& vUp, float flZNear, float flZFar, + float flFovX, float flAspect); + + void CreatePerspectiveFrustum(const Vector& origin, const QAngle& angles, float flZNear, + float flZFar, float flFovX, float flAspectRatio); + + void CreateOrthoFrustum(const Vector& origin, const Vector& forward, const Vector& right, const Vector& up, + float flLeft, float flRight, float flBottom, float flTop, float flZNear, float flZFar); + + void CreateOrthoFrustumFLU(const Vector& vOrigin, const Vector& vForward, const Vector& vLeft, const Vector& vUp, + float flLeft, float flRight, float flBottom, float flTop, float flZNear, float flZFar); + + bool GetCorners(Vector* pPoints) const; + + fourplanes_t planes[2]; +}; + +#endif + +class FourQuaternions; +class ALIGN16 FourVectors +{ +public: + fltx4 x, y, z; + + FourVectors(void) + { + } + + FourVectors(FourVectors const& src) + { + x = src.x; + y = src.y; + z = src.z; + } + + explicit FORCEINLINE FourVectors(float a) + { + fltx4 aReplicated = ReplicateX4(a); + x = y = z = aReplicated; + } + + FORCEINLINE void Init(void) + { + x = Four_Zeros; + y = Four_Zeros; + z = Four_Zeros; + } + + FORCEINLINE void Init(float flX, float flY, float flZ) + { + x = ReplicateX4(flX); + y = ReplicateX4(flY); + z = ReplicateX4(flZ); + } + + FORCEINLINE FourVectors(float flX, float flY, float flZ) + { + Init(flX, flY, flZ); + } + + FORCEINLINE void Init(fltx4 const& fl4X, fltx4 const& fl4Y, fltx4 const& fl4Z) + { + x = fl4X; + y = fl4Y; + z = fl4Z; + } + + FORCEINLINE FourVectors(fltx4 const& fl4X, fltx4 const& fl4Y, fltx4 const& fl4Z) + { + Init(fl4X, fl4Y, fl4Z); + } + + + + FORCEINLINE FourVectors(Vector const& a, Vector const& b, Vector const& c, Vector const& d) + { + LoadAndSwizzle(a, b, c, d); + } + + FORCEINLINE FourVectors(VectorAligned const& a, VectorAligned const& b, VectorAligned const& c, VectorAligned const& d) + { + LoadAndSwizzleAligned(a, b, c, d); + } + + FORCEINLINE FourVectors(const float* xs, const float* ys, const float* zs) : + x(LoadAlignedSIMD(xs)), y(LoadAlignedSIMD(ys)), z(LoadAlignedSIMD(zs)) + {}; + + FORCEINLINE void DuplicateVector(Vector const& v) + { + x = ReplicateX4(v.x); + y = ReplicateX4(v.y); + z = ReplicateX4(v.z); + } + + FORCEINLINE fltx4 const& operator[](int idx) const + { + return *((&x) + idx); + } + + FORCEINLINE fltx4& operator[](int idx) + { + return *((&x) + idx); + } + + FORCEINLINE void operator+=(FourVectors const& b) + { + x = AddSIMD(x, b.x); + y = AddSIMD(y, b.y); + z = AddSIMD(z, b.z); + } + + FORCEINLINE void operator-=(FourVectors const& b) + { + x = SubSIMD(x, b.x); + y = SubSIMD(y, b.y); + z = SubSIMD(z, b.z); + } + + FORCEINLINE void operator*=(FourVectors const& b) + { + x = MulSIMD(x, b.x); + y = MulSIMD(y, b.y); + z = MulSIMD(z, b.z); + } + + FORCEINLINE void operator*=(const fltx4& scale) + { + x = MulSIMD(x, scale); + y = MulSIMD(y, scale); + z = MulSIMD(z, scale); + } + + FORCEINLINE void operator*=(float scale) + { + fltx4 scalepacked = ReplicateX4(scale); + *this *= scalepacked; + } + + FORCEINLINE fltx4 operator*(FourVectors const& b) const + { + fltx4 dot = MulSIMD(x, b.x); + dot = MaddSIMD(y, b.y, dot); + dot = MaddSIMD(z, b.z, dot); + return dot; + } + + FORCEINLINE fltx4 operator*(Vector const& b) const + { + fltx4 dot = MulSIMD(x, ReplicateX4(b.x)); + dot = MaddSIMD(y, ReplicateX4(b.y), dot); + dot = MaddSIMD(z, ReplicateX4(b.z), dot); + return dot; + } + + FORCEINLINE FourVectors operator*(float b) const + { + fltx4 scalepacked = ReplicateX4(b); + FourVectors res; + res.x = MulSIMD(x, scalepacked); + res.y = MulSIMD(y, scalepacked); + res.z = MulSIMD(z, scalepacked); + return res; + } + + FORCEINLINE FourVectors operator*(FLTX4 fl4Scale) const + { + FourVectors res; + res.x = MulSIMD(x, fl4Scale); + res.y = MulSIMD(y, fl4Scale); + res.z = MulSIMD(z, fl4Scale); + return res; + } + + FORCEINLINE void VProduct(FourVectors const& b) + { + x = MulSIMD(x, b.x); + y = MulSIMD(y, b.y); + z = MulSIMD(z, b.z); + } + FORCEINLINE void MakeReciprocal(void) + { + x = ReciprocalSIMD(x); + y = ReciprocalSIMD(y); + z = ReciprocalSIMD(z); + } + + FORCEINLINE void MakeReciprocalSaturate(void) + { + x = ReciprocalSaturateSIMD(x); + y = ReciprocalSaturateSIMD(y); + z = ReciprocalSaturateSIMD(z); + } + + inline void RotateBy(const matrix3x4_t& matrix); + static void RotateManyBy(FourVectors* RESTRICT pVectors, unsigned int numVectors, const matrix3x4_t& rotationMatrix); + + static void RotateManyBy(FourVectors* RESTRICT pVectors, unsigned int numVectors, const matrix3x4_t& rotationMatrix, FourVectors* RESTRICT pOut); + + inline void TransformBy(const matrix3x4_t& matrix); + + static void TransformManyBy(FourVectors* RESTRICT pVectors, unsigned int numVectors, const matrix3x4_t& rotationMatrix, FourVectors* RESTRICT pOut); + + static void TransformManyBy(FourVectors* RESTRICT pVectors, unsigned int numVectors, const matrix3x4_t& rotationMatrix); + + static void CalcClosestPointOnLineSIMD(const FourVectors& P, const FourVectors& vLineA, const FourVectors& vLineB, FourVectors& vClosest, fltx4* outT = 0); + static fltx4 CalcClosestPointToLineTSIMD(const FourVectors& P, const FourVectors& vLineA, const FourVectors& vLineB, FourVectors& vDir); + + FORCEINLINE const float& X(int idx) const + { + return SubFloat((fltx4&)x, idx); + } + + FORCEINLINE const float& Y(int idx) const + { + return SubFloat((fltx4&)y, idx); + } + + FORCEINLINE const float& Z(int idx) const + { + return SubFloat((fltx4&)z, idx); + } + + FORCEINLINE float& X(int idx) + { + return SubFloat(x, idx); + } + + FORCEINLINE float& Y(int idx) + { + return SubFloat(y, idx); + } + + FORCEINLINE float& Z(int idx) + { + return SubFloat(z, idx); + } + + FORCEINLINE Vector Vec(int idx) const + { + return Vector(X(idx), Y(idx), Z(idx)); + } + + FORCEINLINE void operator=(FourVectors const& src) + { + x = src.x; + y = src.y; + z = src.z; + } + + FORCEINLINE void LoadAndSwizzle(Vector const& a, Vector const& b, Vector const& c, Vector const& d) + { +#if defined( _X360 ) || defined(_PS3) + fltx4 tx = LoadUnalignedSIMD(&a.x); + fltx4 ty = LoadUnalignedSIMD(&b.x); + fltx4 tz = LoadUnalignedSIMD(&c.x); + fltx4 tw = LoadUnalignedSIMD(&d.x); + fltx4 r0 = VectorMergeHighSIMD(tx, tz); + fltx4 r1 = VectorMergeHighSIMD(ty, tw); + fltx4 r2 = VectorMergeLowSIMD(tx, tz); + fltx4 r3 = VectorMergeLowSIMD(ty, tw); + + x = VectorMergeHighSIMD(r0, r1); + y = VectorMergeLowSIMD(r0, r1); + z = VectorMergeHighSIMD(r2, r3); +#else + x = LoadUnalignedSIMD(&(a.x)); + y = LoadUnalignedSIMD(&(b.x)); + z = LoadUnalignedSIMD(&(c.x)); + fltx4 w = LoadUnalignedSIMD(&(d.x)); + TransposeSIMD(x, y, z, w); +#endif + } + + FORCEINLINE void LoadAndSwizzle(Vector const& a) + { + LoadAndSwizzle(a, a, a, a); + } + + FORCEINLINE void Load(const float& a, const float& b, const float& c, const float& d) + { +#if defined( _X360 ) || defined( _PS3 ) + fltx4 temp[4]; + temp[0] = LoadUnalignedFloatSIMD(&a); + temp[1] = LoadUnalignedFloatSIMD(&b); + temp[2] = LoadUnalignedFloatSIMD(&c); + temp[3] = LoadUnalignedFloatSIMD(&d); + y = VectorMergeHighSIMD(temp[0], temp[2]); + z = VectorMergeHighSIMD(temp[1], temp[3]); + + x = VectorMergeHighSIMD(y, z); + y = x; + z = x; +#else + ALIGN16 float temp[4]; + temp[0] = a; temp[1] = b; temp[2] = c; temp[3] = d; + fltx4 v = LoadAlignedSIMD(temp); + x = v; + y = v; + z = v; +#endif + } + + FORCEINLINE void LoadAndSwizzle(FLTX4 a, FLTX4 b, FLTX4 c, FLTX4 d) + { +#if defined( _X360 ) || defined( _PS3 ) + fltx4 tx = a; + fltx4 ty = b; + fltx4 tz = c; + fltx4 tw = d; + fltx4 r0 = VectorMergeHighSIMD(tx, tz); + fltx4 r1 = VectorMergeHighSIMD(ty, tw); + fltx4 r2 = VectorMergeLowSIMD(tx, tz); + fltx4 r3 = VectorMergeLowSIMD(ty, tw); + + x = VectorMergeHighSIMD(r0, r1); + y = VectorMergeLowSIMD(r0, r1); + z = VectorMergeHighSIMD(r2, r3); +#else + x = a; + y = b; + z = c; + fltx4 w = d; + TransposeSIMD(x, y, z, w); +#endif + } + + FORCEINLINE void LoadAndSwizzleAligned(const float* RESTRICT a, const float* RESTRICT b, const float* RESTRICT c, const float* RESTRICT d) + { +#if defined( _X360 ) || defined( _PS3 ) + fltx4 tx = LoadAlignedSIMD(a); + fltx4 ty = LoadAlignedSIMD(b); + fltx4 tz = LoadAlignedSIMD(c); + fltx4 tw = LoadAlignedSIMD(d); + fltx4 r0 = VectorMergeHighSIMD(tx, tz); + fltx4 r1 = VectorMergeHighSIMD(ty, tw); + fltx4 r2 = VectorMergeLowSIMD(tx, tz); + fltx4 r3 = VectorMergeLowSIMD(ty, tw); + + x = VectorMergeHighSIMD(r0, r1); + y = VectorMergeLowSIMD(r0, r1); + z = VectorMergeHighSIMD(r2, r3); +#else + x = LoadAlignedSIMD(a); + y = LoadAlignedSIMD(b); + z = LoadAlignedSIMD(c); + fltx4 w = LoadAlignedSIMD(d); + TransposeSIMD(x, y, z, w); +#endif + } + + FORCEINLINE void LoadAndSwizzleAligned(Vector const& a, Vector const& b, Vector const& c, Vector const& d) + { + LoadAndSwizzleAligned(&a.x, &b.x, &c.x, &d.x); + } + + FORCEINLINE void TransposeOnto(fltx4& out0, fltx4& out1, fltx4& out2, fltx4& out3, FLTX4 w = Four_Zeros) const + { +#if defined( _X360 ) || defined(_PS3) + fltx4 r0 = VectorMergeHighSIMD(x, z); + fltx4 r1 = VectorMergeHighSIMD(y, w); + fltx4 r2 = VectorMergeLowSIMD(x, z); + fltx4 r3 = VectorMergeLowSIMD(y, w); + + out0 = VectorMergeHighSIMD(r0, r1); + out1 = VectorMergeLowSIMD(r0, r1); + out2 = VectorMergeHighSIMD(r2, r3); + out3 = VectorMergeLowSIMD(r2, r3); +#else + out0 = x; + out1 = y; + out2 = z; + out3 = w; + + TransposeSIMD(out0, out1, out2, out3); +#endif + } + +#if !defined(__SPU__) + FORCEINLINE void StoreUnalignedVector3SIMD(Vector* RESTRICT out0, Vector* RESTRICT out1, Vector* RESTRICT out2, Vector* RESTRICT out3) const; +#endif + + FORCEINLINE void StoreAlignedVectorSIMD(VectorAligned* RESTRICT out0, VectorAligned* RESTRICT out1, VectorAligned* RESTRICT out2, VectorAligned* RESTRICT out3) const; + +#if !defined(__SPU__) + FORCEINLINE void StoreUnalignedContigVector3SIMD(Vector* RESTRICT pDestination) + { + fltx4 a, b, c, d; + TransposeOnto(a, b, c, d); + StoreFourUnalignedVector3SIMD(a, b, c, d, pDestination); + } +#endif + +#if !defined(__SPU__) + FORCEINLINE void StoreAlignedContigVector3SIMD(Vector* RESTRICT pDestination) + { + fltx4 a, b, c, d; + TransposeOnto(a, b, c, d); + StoreFourAlignedVector3SIMD(a, b, c, d, pDestination); + } + + FORCEINLINE void StoreAlignedContigVectorASIMD(VectorAligned* RESTRICT pDestination) + { + StoreAlignedVectorSIMD(pDestination, pDestination + 1, pDestination + 2, pDestination + 3); + } +#endif + + FORCEINLINE fltx4 LengthSqr(void) const + { + const FourVectors& a = *this; + return a * a; + } + + FORCEINLINE fltx4 length2(void) const + { + return (*this) * (*this); + } + + FORCEINLINE fltx4 length(void) const + { + return SqrtEstSIMD(length2()); + } + + FORCEINLINE fltx4 Length(void) const + { + return SqrtSIMD(length2()); + } + + + FORCEINLINE void VectorNormalizeFast(void) + { + fltx4 mag_sq = (*this) * (*this); + (*this) *= ReciprocalSqrtEstSIMD(mag_sq); + } + + FORCEINLINE void VectorNormalize(void) + { + fltx4 mag_sq = (*this) * (*this); + (*this) *= ReciprocalSqrtSIMD(mag_sq); + } + + FORCEINLINE fltx4 DistToSqr(FourVectors const& pnt) + { + fltx4 fl4dX = SubSIMD(pnt.x, x); + fltx4 fl4dY = SubSIMD(pnt.y, y); + fltx4 fl4dZ = SubSIMD(pnt.z, z); + return AddSIMD(MulSIMD(fl4dX, fl4dX), AddSIMD(MulSIMD(fl4dY, fl4dY), MulSIMD(fl4dZ, fl4dZ))); + + } + + FORCEINLINE fltx4 TValueOfClosestPointOnLine(FourVectors const& p0, FourVectors const& p1) const + { + FourVectors lineDelta = p1; + lineDelta -= p0; + fltx4 OOlineDirDotlineDir = ReciprocalSIMD(p1 * p1); + FourVectors v4OurPnt = *this; + v4OurPnt -= p0; + return MulSIMD(OOlineDirDotlineDir, v4OurPnt * lineDelta); + } + + FORCEINLINE fltx4 DistSqrToLineSegment(FourVectors const& p0, FourVectors const& p1) const + { + FourVectors lineDelta = p1; + FourVectors v4OurPnt = *this; + v4OurPnt -= p0; + lineDelta -= p0; + + fltx4 OOlineDirDotlineDir = ReciprocalSIMD(lineDelta * lineDelta); + + fltx4 fl4T = MulSIMD(OOlineDirDotlineDir, v4OurPnt * lineDelta); + + fl4T = MinSIMD(fl4T, Four_Ones); + fl4T = MaxSIMD(fl4T, Four_Zeros); + lineDelta *= fl4T; + return v4OurPnt.DistToSqr(lineDelta); + } + FORCEINLINE FourVectors Normalized()const + { + fltx4 fl4LengthInv = ReciprocalSqrtSIMD(LengthSqr()); + FourVectors out; + out.x = x * fl4LengthInv; + out.y = y * fl4LengthInv; + out.z = z * fl4LengthInv; + return out; + } + + FORCEINLINE FourVectors NormalizedSafeX() const + { + fltx4 f4LenSqr = LengthSqr(); + fltx4 isBigEnough = CmpGeSIMD(f4LenSqr, Four_Epsilons); + fltx4 fl4LengthInv = ReciprocalSqrtSIMD(f4LenSqr); + FourVectors out; + out.x = MaskedAssign(isBigEnough, x * fl4LengthInv, Four_Ones); + out.y = AndSIMD(y * fl4LengthInv, isBigEnough); + out.z = AndSIMD(z * fl4LengthInv, isBigEnough); + return out; + } + FORCEINLINE FourVectors NormalizedSafeY() const + { + fltx4 f4LenSqr = LengthSqr(); + fltx4 isBigEnough = CmpGeSIMD(f4LenSqr, Four_Epsilons); + fltx4 fl4LengthInv = ReciprocalSqrtSIMD(f4LenSqr); + FourVectors out; + out.x = AndSIMD(x * fl4LengthInv, isBigEnough); + out.y = MaskedAssign(isBigEnough, y * fl4LengthInv, Four_Ones); + out.z = AndSIMD(z * fl4LengthInv, isBigEnough); + return out; + } + + FORCEINLINE FourVectors NormalizedSafeZ() const + { + fltx4 f4LenSqr = LengthSqr(); + fltx4 isBigEnough = CmpGeSIMD(f4LenSqr, Four_Epsilons); + fltx4 fl4LengthInv = ReciprocalSqrtSIMD(f4LenSqr); + FourVectors out; + out.x = AndSIMD(x * fl4LengthInv, isBigEnough); + out.y = AndSIMD(y * fl4LengthInv, isBigEnough); + out.z = MaskedAssign(isBigEnough, z * fl4LengthInv, Four_Ones); + return out; + } +}; + + +inline FourVectors CrossProduct(const FourVectors& a, const FourVectors& b) +{ + return FourVectors(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x); +} + +inline fltx4 DotProduct(const FourVectors& a, const FourVectors& b) +{ + return a.x * b.x + a.y * b.y + a.z * b.z; +} + +inline FourVectors operator * (fltx4 left, const FourVectors& right) +{ + return right * left; +} + + +inline FourVectors Mul(const FourVectors& a, const fltx4& b) +{ + FourVectors ret; + ret.x = MulSIMD(a.x, b); + ret.y = MulSIMD(a.y, b); + ret.z = MulSIMD(a.z, b); + return ret; +} + +inline FourVectors Mul(const FourVectors& a, const FourVectors& b) +{ + FourVectors ret; + ret.x = MulSIMD(a.x, b.x); + ret.y = MulSIMD(a.y, b.y); + ret.z = MulSIMD(a.z, b.z); + return ret; +} + +inline FourVectors Madd(const FourVectors& a, const fltx4& b, const FourVectors& c) +{ + FourVectors ret; + ret.x = MaddSIMD(a.x, b, c.x); + ret.y = MaddSIMD(a.y, b, c.y); + ret.z = MaddSIMD(a.z, b, c.z); + return ret; +} + +inline FourVectors operator ^(const FourVectors& a, const FourVectors& b) +{ + FourVectors ret; + ret.x = SubSIMD(MulSIMD(a.y, b.z), MulSIMD(a.z, b.y)); + ret.y = SubSIMD(MulSIMD(a.z, b.x), MulSIMD(a.x, b.z)); + ret.z = SubSIMD(MulSIMD(a.x, b.y), MulSIMD(a.y, b.x)); + return ret; +} + +inline FourVectors operator-(const FourVectors& a, const FourVectors& b) +{ + FourVectors ret; + ret.x = SubSIMD(a.x, b.x); + ret.y = SubSIMD(a.y, b.y); + ret.z = SubSIMD(a.z, b.z); + return ret; +} + +inline FourVectors operator+(const FourVectors& a, const FourVectors& b) +{ + FourVectors ret; + ret.x = AddSIMD(a.x, b.x); + ret.y = AddSIMD(a.y, b.y); + ret.z = AddSIMD(a.z, b.z); + return ret; +} + +inline FourVectors maximum(const FourVectors& a, const FourVectors& b) +{ + FourVectors ret; + ret.x = MaxSIMD(a.x, b.x); + ret.y = MaxSIMD(a.y, b.y); + ret.z = MaxSIMD(a.z, b.z); + return ret; +} + +inline FourVectors minimum(const FourVectors& a, const FourVectors& b) +{ + FourVectors ret; + ret.x = MinSIMD(a.x, b.x); + ret.y = MinSIMD(a.y, b.y); + ret.z = MinSIMD(a.z, b.z); + return ret; +} + +FORCEINLINE FourVectors RotateLeft(const FourVectors& src) +{ + FourVectors ret; + ret.x = RotateLeft(src.x); + ret.y = RotateLeft(src.y); + ret.z = RotateLeft(src.z); + return ret; +} + +FORCEINLINE FourVectors RotateRight(const FourVectors& src) +{ + FourVectors ret; + ret.x = RotateRight(src.x); + ret.y = RotateRight(src.y); + ret.z = RotateRight(src.z); + return ret; +} +FORCEINLINE FourVectors MaskedAssign(const bi32x4& ReplacementMask, const FourVectors& NewValue, const FourVectors& OldValue) +{ + FourVectors ret; + ret.x = MaskedAssign(ReplacementMask, NewValue.x, OldValue.x); + ret.y = MaskedAssign(ReplacementMask, NewValue.y, OldValue.y); + ret.z = MaskedAssign(ReplacementMask, NewValue.z, OldValue.z); + return ret; +} + +FORCEINLINE FourVectors VectorReflect(const FourVectors& incident, const FourVectors& normal) +{ + FourVectors ret = incident; + fltx4 iDotNx2 = incident * normal; + iDotNx2 = AddSIMD(iDotNx2, iDotNx2); + FourVectors nPart = normal; + nPart *= iDotNx2; + ret -= nPart; + return ret; +} + +FORCEINLINE FourVectors VectorSlide(const FourVectors& incident, const FourVectors& normal) +{ + FourVectors ret = incident; + fltx4 iDotN = incident * normal; + FourVectors nPart = normal; + nPart *= iDotN; + ret -= nPart; + return ret; +} + +FORCEINLINE FourVectors VectorNormalizeFast(const FourVectors& src) +{ + fltx4 mag_sq = ReciprocalSqrtEstSIMD(src * src); + FourVectors result; + result.x = MulSIMD(src.x, mag_sq); + result.y = MulSIMD(src.y, mag_sq); + result.z = MulSIMD(src.z, mag_sq); + return result; +} + +#if !defined(__SPU__) +FORCEINLINE void FourVectors::StoreUnalignedVector3SIMD(Vector* RESTRICT out0, Vector* RESTRICT out1, Vector* RESTRICT out2, Vector* RESTRICT out3) const +{ +#ifdef _X360 + fltx4 x0, x1, x2, x3, y0, y1, y2, y3, z0, z1, z2, z3; + x0 = SplatXSIMD(x); + x1 = SplatYSIMD(x); + x2 = SplatZSIMD(x); + x3 = SplatWSIMD(x); + + y0 = SplatXSIMD(y); + y1 = SplatYSIMD(y); + y2 = SplatZSIMD(y); + y3 = SplatWSIMD(y); + + z0 = SplatXSIMD(z); + z1 = SplatYSIMD(z); + z2 = SplatZSIMD(z); + z3 = SplatWSIMD(z); + + __stvewx(x0, out0->Base(), 0); + __stvewx(y0, out0->Base(), 4); + __stvewx(z0, out0->Base(), 8); + + __stvewx(x1, out1->Base(), 0); + __stvewx(y1, out1->Base(), 4); + __stvewx(z1, out1->Base(), 8); + + __stvewx(x2, out2->Base(), 0); + __stvewx(y2, out2->Base(), 4); + __stvewx(z2, out2->Base(), 8); + + __stvewx(x3, out3->Base(), 0); + __stvewx(y3, out3->Base(), 4); + __stvewx(z3, out3->Base(), 8); +#else + fltx4 a, b, c, d; + TransposeOnto(a, b, c, d); + StoreUnaligned3SIMD(out0->Base(), a); + StoreUnaligned3SIMD(out1->Base(), b); + StoreUnaligned3SIMD(out2->Base(), c); + StoreUnaligned3SIMD(out3->Base(), d); +#endif +} + +FORCEINLINE void FourVectors::StoreAlignedVectorSIMD(VectorAligned* RESTRICT out0, VectorAligned* RESTRICT out1, VectorAligned* RESTRICT out2, VectorAligned* RESTRICT out3) const +{ + fltx4 a, b, c, d; + TransposeOnto(a, b, c, d); + StoreAligned3SIMD(out0, a); + StoreAligned3SIMD(out1, b); + StoreAligned3SIMD(out2, c); + StoreAligned3SIMD(out3, d); + +} +#endif + +#if !defined(__SPU__) +void FourVectors::RotateBy(const matrix3x4_t& matrix) +{ + fltx4 matSplat00, matSplat01, matSplat02, + matSplat10, matSplat11, matSplat12, + matSplat20, matSplat21, matSplat22; + + fltx4 matCol0 = LoadUnalignedSIMD(matrix[0]); + fltx4 matCol1 = LoadUnalignedSIMD(matrix[1]); + fltx4 matCol2 = LoadUnalignedSIMD(matrix[2]); + + matSplat00 = SplatXSIMD(matCol0); + matSplat01 = SplatYSIMD(matCol0); + matSplat02 = SplatZSIMD(matCol0); + + matSplat10 = SplatXSIMD(matCol1); + matSplat11 = SplatYSIMD(matCol1); + matSplat12 = SplatZSIMD(matCol1); + + matSplat20 = SplatXSIMD(matCol2); + matSplat21 = SplatYSIMD(matCol2); + matSplat22 = SplatZSIMD(matCol2); + + fltx4 outX, outY, outZ; + outX = AddSIMD(AddSIMD(MulSIMD(x, matSplat00), MulSIMD(y, matSplat01)), MulSIMD(z, matSplat02)); + outY = AddSIMD(AddSIMD(MulSIMD(x, matSplat10), MulSIMD(y, matSplat11)), MulSIMD(z, matSplat12)); + outZ = AddSIMD(AddSIMD(MulSIMD(x, matSplat20), MulSIMD(y, matSplat21)), MulSIMD(z, matSplat22)); + + x = outX; + y = outY; + z = outZ; +} + + +void FourVectors::TransformBy(const matrix3x4_t& matrix) +{ + fltx4 matSplat00, matSplat01, matSplat02, + matSplat10, matSplat11, matSplat12, + matSplat20, matSplat21, matSplat22; + + fltx4 matCol0 = LoadUnalignedSIMD(matrix[0]); + fltx4 matCol1 = LoadUnalignedSIMD(matrix[1]); + fltx4 matCol2 = LoadUnalignedSIMD(matrix[2]); + + matSplat00 = SplatXSIMD(matCol0); + matSplat01 = SplatYSIMD(matCol0); + matSplat02 = SplatZSIMD(matCol0); + + matSplat10 = SplatXSIMD(matCol1); + matSplat11 = SplatYSIMD(matCol1); + matSplat12 = SplatZSIMD(matCol1); + + matSplat20 = SplatXSIMD(matCol2); + matSplat21 = SplatYSIMD(matCol2); + matSplat22 = SplatZSIMD(matCol2); + + fltx4 outX, outY, outZ; + + outX = MaddSIMD(z, matSplat02, AddSIMD(MulSIMD(x, matSplat00), MulSIMD(y, matSplat01))); + outY = MaddSIMD(z, matSplat12, AddSIMD(MulSIMD(x, matSplat10), MulSIMD(y, matSplat11))); + outZ = MaddSIMD(z, matSplat22, AddSIMD(MulSIMD(x, matSplat20), MulSIMD(y, matSplat21))); + + x = AddSIMD(outX, ReplicateX4(matrix[0][3])); + y = AddSIMD(outY, ReplicateX4(matrix[1][3])); + z = AddSIMD(outZ, ReplicateX4(matrix[2][3])); +} +#endif + +fltx4 NoiseSIMD(FourVectors const& v); + +FourVectors DNoiseSIMD(FourVectors const& v); + +FourVectors CurlNoiseSIMD(FourVectors const& v); + + +fltx4 NoiseSIMD(const fltx4& x, const fltx4& y, const fltx4& z); + + +inline fltx4 fabs(const fltx4& x) +{ + return AndSIMD(x, LoadAlignedSIMD(g_SIMD_clear_signmask)); +} + +inline fltx4 AbsSIMD(const fltx4& x) +{ + return fabs(x); +} + +inline fltx4 fnegate(const fltx4& x) +{ + return XorSIMD(x, LoadAlignedSIMD(g_SIMD_signmask)); +} + +fltx4 Pow_FixedPoint_Exponent_SIMD(const fltx4& x, int exponent); + +inline fltx4 PowSIMD(const fltx4& x, float exponent) +{ + return Pow_FixedPoint_Exponent_SIMD(x, (int)(4.0 * exponent)); +} + +inline fltx4 LinearToGammaSIMD(fltx4 x) +{ + x = MaxSIMD(MinSIMD(Four_Ones, x), Four_Zeros); + return AddSIMD(Four_LinearToGammaCoefficients_E, + MulSIMD(x, AddSIMD(Four_LinearToGammaCoefficients_D, + MulSIMD(x, AddSIMD(Four_LinearToGammaCoefficients_C, + MulSIMD(x, AddSIMD(Four_LinearToGammaCoefficients_B, + MulSIMD(x, Four_LinearToGammaCoefficients_A)))))))); +} + + +inline fltx4 GammaToLinearSIMD(fltx4 x) +{ + x = MaxSIMD(x, Four_Zeros); + x = AddSIMD(Four_GammaToLinearCoefficients_D, + MulSIMD(x, AddSIMD(Four_GammaToLinearCoefficients_C, + MulSIMD(x, AddSIMD(Four_GammaToLinearCoefficients_B, + MulSIMD(x, Four_GammaToLinearCoefficients_A)))))); + return MinSIMD(x, Four_Ones); +} + +inline fltx4 GammaToLinearExtendedSIMD(fltx4 x) +{ + x = MaxSIMD(x, Four_Zeros); + fltx4 fl4Ret = AddSIMD(Four_GammaToLinearCoefficients_D, + MulSIMD(x, AddSIMD(Four_GammaToLinearCoefficients_C, + MulSIMD(x, AddSIMD(Four_GammaToLinearCoefficients_B, + MulSIMD(x, Four_GammaToLinearCoefficients_A)))))); + return MaskedAssign(CmpGeSIMD(x, Four_Ones), x, fl4Ret); +} + +void SeedRandSIMD(uint32 seed); +fltx4 RandSIMD(int nContext = 0); + +int GetSIMDRandContext(void); +void ReleaseSIMDRandContext(int nContext); + +FORCEINLINE fltx4 RandSignedSIMD(void) +{ + return SubSIMD(MulSIMD(Four_Twos, RandSIMD()), Four_Ones); +} + + +FORCEINLINE fltx4 LerpSIMD(const fltx4& percent, const fltx4& a, const fltx4& b) +{ + return AddSIMD(a, MulSIMD(SubSIMD(b, a), percent)); +} + +FORCEINLINE fltx4 RemapValClampedSIMD(const fltx4& val, const fltx4& a, const fltx4& b, const fltx4& c, const fltx4& d) +{ + fltx4 range = MaskedAssign(CmpEqSIMD(a, b), Four_Ones, SubSIMD(b, a)); + fltx4 cVal = MaxSIMD(Four_Zeros, MinSIMD(Four_Ones, DivSIMD(SubSIMD(val, a), range))); + return LerpSIMD(cVal, c, d); +} + +inline fltx4 SimpleSpline(const fltx4& value) +{ + fltx4 valueDoubled = MulSIMD(value, Four_Twos); + fltx4 valueSquared = MulSIMD(value, value); + + return SubSIMD( + MulSIMD(Four_Threes, valueSquared), + MulSIMD(valueDoubled, valueSquared)); +} + +inline fltx4 SimpleSplineRemapValWithDeltas(const fltx4& val, + const fltx4& A, const fltx4& BMinusA, + const fltx4& OneOverBMinusA, const fltx4& C, + const fltx4& DMinusC) +{ + fltx4 cVal = MulSIMD(SubSIMD(val, A), OneOverBMinusA); + return AddSIMD(C, MulSIMD(DMinusC, SimpleSpline(cVal))); +} + +inline fltx4 SimpleSplineRemapValWithDeltasClamped(const fltx4& val, + const fltx4& A, const fltx4& BMinusA, + const fltx4& OneOverBMinusA, const fltx4& C, + const fltx4& DMinusC) +{ + fltx4 cVal = MulSIMD(SubSIMD(val, A), OneOverBMinusA); + cVal = MinSIMD(Four_Ones, MaxSIMD(Four_Zeros, cVal)); + return AddSIMD(C, MulSIMD(DMinusC, SimpleSpline(cVal))); +} + +FORCEINLINE fltx4 FracSIMD(const fltx4& val) +{ + fltx4 fl4Abs = fabs(val); + fltx4 ival = SubSIMD(AddSIMD(fl4Abs, Four_2ToThe23s), Four_2ToThe23s); + ival = MaskedAssign(CmpGtSIMD(ival, fl4Abs), SubSIMD(ival, Four_Ones), ival); + return XorSIMD(SubSIMD(fl4Abs, ival), XorSIMD(val, fl4Abs)); +} + +#ifndef SPU +FORCEINLINE fltx4 Mod2SIMD(const fltx4& val) +{ + fltx4 fl4Abs = fabs(val); + fltx4 ival = SubSIMD(AndSIMD(LoadAlignedSIMD((float*)g_SIMD_lsbmask), AddSIMD(fl4Abs, Four_2ToThe23s)), Four_2ToThe23s); + ival = MaskedAssign(CmpGtSIMD(ival, fl4Abs), SubSIMD(ival, Four_Twos), ival); + return XorSIMD(SubSIMD(fl4Abs, ival), XorSIMD(val, fl4Abs)); +} +#endif + +FORCEINLINE fltx4 Mod2SIMDPositiveInput(const fltx4& val) +{ + fltx4 ival = SubSIMD(AndSIMD(LoadAlignedSIMD(g_SIMD_lsbmask), AddSIMD(val, Four_2ToThe23s)), Four_2ToThe23s); + ival = MaskedAssign(CmpGtSIMD(ival, val), SubSIMD(ival, Four_Twos), ival); + return SubSIMD(val, ival); +} + + +FORCEINLINE fltx4 _SinEst01SIMD(const fltx4& val) +{ + return MulSIMD(val, SubSIMD(Four_Fours, MulSIMD(val, Four_Fours))); +} + +FORCEINLINE fltx4 _Sin01SIMD(const fltx4& val) +{ + fltx4 fl4BadEst = MulSIMD(val, SubSIMD(Four_Fours, MulSIMD(val, Four_Fours))); + return AddSIMD(MulSIMD(Four_Point225s, SubSIMD(MulSIMD(fl4BadEst, fl4BadEst), fl4BadEst)), fl4BadEst); +} + +FORCEINLINE fltx4 SinEst01SIMD(const fltx4& val) +{ + fltx4 fl4Abs = fabs(val); + fltx4 fl4Reduced2 = Mod2SIMDPositiveInput(fl4Abs); + bi32x4 fl4OddMask = CmpGeSIMD(fl4Reduced2, Four_Ones); + fltx4 fl4val = SubSIMD(fl4Reduced2, AndSIMD(Four_Ones, fl4OddMask)); + fltx4 fl4Sin = _SinEst01SIMD(fl4val); + fl4Sin = XorSIMD(fl4Sin, AndSIMD(LoadAlignedSIMD(g_SIMD_signmask), XorSIMD(val, fl4OddMask))); + return fl4Sin; + +} + +FORCEINLINE fltx4 Sin01SIMD(const fltx4& val) +{ + fltx4 fl4Abs = fabs(val); + fltx4 fl4Reduced2 = Mod2SIMDPositiveInput(fl4Abs); + bi32x4 fl4OddMask = CmpGeSIMD(fl4Reduced2, Four_Ones); + fltx4 fl4val = SubSIMD(fl4Reduced2, AndSIMD(Four_Ones, fl4OddMask)); + fltx4 fl4Sin = _Sin01SIMD(fl4val); + fl4Sin = XorSIMD(fl4Sin, AndSIMD(LoadAlignedSIMD(g_SIMD_signmask), XorSIMD(val, fl4OddMask))); + return fl4Sin; + +} + +FORCEINLINE fltx4 NatExpSIMD(const fltx4& val) +{ + fltx4 fl4Result; + SubFloat(fl4Result, 0) = exp(SubFloat(val, 0)); + SubFloat(fl4Result, 1) = exp(SubFloat(val, 1)); + SubFloat(fl4Result, 2) = exp(SubFloat(val, 2)); + SubFloat(fl4Result, 3) = exp(SubFloat(val, 3)); + return fl4Result; +} + +FORCEINLINE fltx4 PreCalcBiasParameter(const fltx4& bias_parameter) +{ + return SubSIMD(ReciprocalSIMD(bias_parameter), Four_Twos); +} + +FORCEINLINE fltx4 BiasSIMD(const fltx4& val, const fltx4& precalc_param) +{ + return DivSIMD(val, AddSIMD(MulSIMD(precalc_param, SubSIMD(Four_Ones, val)), Four_Ones)); +} + +#ifndef SPU +FORCEINLINE int BoxOnPlaneSideSIMD(const fltx4& emins, const fltx4& emaxs, const cplane_t* p, float tolerance = 0.f) +{ + fltx4 corners[2]; + fltx4 normal = LoadUnalignedSIMD(p->normal.Base()); + fltx4 dist = ReplicateX4(-p->dist); + normal = SetWSIMD(normal, dist); + fltx4 t4 = ReplicateX4(tolerance); + fltx4 negt4 = ReplicateX4(-tolerance); + bi32x4 cmp = CmpGeSIMD(normal, Four_Zeros); + corners[0] = MaskedAssign(cmp, emaxs, emins); + corners[1] = MaskedAssign(cmp, emins, emaxs); + fltx4 dot1 = Dot4SIMD(normal, corners[0]); + fltx4 dot2 = Dot4SIMD(normal, corners[1]); + cmp = CmpGeSIMD(dot1, t4); + bi32x4 cmp2 = CmpGtSIMD(negt4, dot2); + fltx4 result = MaskedAssign(cmp, Four_Ones, Four_Zeros); + fltx4 result2 = MaskedAssign(cmp2, Four_Twos, Four_Zeros); + result = AddSIMD(result, result2); + intx4 sides; + ConvertStoreAsIntsSIMD(&sides, result); + return sides[0]; +} + + +class KDop32_t +{ +public: + fltx4 m_Mins[4]; + fltx4 m_Maxes[4]; + + FORCEINLINE bool Intersects(KDop32_t const& other) const; + + FORCEINLINE void operator|=(KDop32_t const& other); + + FORCEINLINE bool IsEmpty(void) const; + + FORCEINLINE void Init(void) + { + for (int i = 0; i < ARRAYSIZE(m_Mins); i++) + { + m_Mins[i] = Four_FLT_MAX; + m_Maxes[i] = Four_Negative_FLT_MAX; + } + } + + void AddPointSet(Vector const* pPoints, int nPnts); + + void CreateFromPointSet(Vector const* pPoints, int nPnts); +}; + +FORCEINLINE void KDop32_t::operator|=(KDop32_t const& other) +{ + m_Mins[0] = MinSIMD(m_Mins[0], other.m_Mins[0]); + m_Mins[1] = MinSIMD(m_Mins[1], other.m_Mins[1]); + m_Mins[2] = MinSIMD(m_Mins[2], other.m_Mins[2]); + m_Mins[3] = MinSIMD(m_Mins[3], other.m_Mins[3]); + + m_Maxes[0] = MaxSIMD(m_Maxes[0], other.m_Maxes[0]); + m_Maxes[1] = MaxSIMD(m_Maxes[1], other.m_Maxes[1]); + m_Maxes[2] = MaxSIMD(m_Maxes[2], other.m_Maxes[2]); + m_Maxes[3] = MaxSIMD(m_Maxes[3], other.m_Maxes[3]); + + +} + +FORCEINLINE bool KDop32_t::Intersects(KDop32_t const& other) const +{ + bi32x4 c00 = CmpLeSIMD(m_Mins[0], other.m_Maxes[0]); + bi32x4 c01 = CmpLeSIMD(m_Mins[1], other.m_Maxes[1]); + bi32x4 c02 = CmpLeSIMD(m_Mins[2], other.m_Maxes[2]); + bi32x4 c03 = CmpLeSIMD(m_Mins[3], other.m_Maxes[3]); + + bi32x4 c10 = CmpGeSIMD(m_Maxes[0], other.m_Mins[0]); + bi32x4 c11 = CmpGeSIMD(m_Maxes[1], other.m_Mins[1]); + bi32x4 c12 = CmpGeSIMD(m_Maxes[2], other.m_Mins[2]); + bi32x4 c13 = CmpGeSIMD(m_Maxes[3], other.m_Mins[3]); + + bi32x4 a0 = AndSIMD(AndSIMD(c00, c01), AndSIMD(c02, c03)); + bi32x4 a1 = AndSIMD(AndSIMD(c10, c11), AndSIMD(c12, c13)); + + return !(IsAnyZeros(AndSIMD(a1, a0))); +} + + +FORCEINLINE bool KDop32_t::IsEmpty(void) const +{ + bi32x4 c00 = CmpLtSIMD(m_Maxes[0], m_Mins[0]); + bi32x4 c01 = CmpLtSIMD(m_Maxes[1], m_Mins[1]); + bi32x4 c02 = CmpLtSIMD(m_Maxes[2], m_Mins[2]); + bi32x4 c03 = CmpLtSIMD(m_Maxes[3], m_Mins[3]); + + return IsAnyTrue(OrSIMD(OrSIMD(c00, c01), OrSIMD(c02, c03))); +} + + +extern const fltx4 g_KDop32XDirs[4]; +extern const fltx4 g_KDop32YDirs[4]; +extern const fltx4 g_KDop32ZDirs[4]; +#endif + +#if 0 + +#define _VEC_SWIZZLE_QUAT48_UNPACK (__vector unsigned char) { 16, 17, 0, 1, 16, 17, 2, 3, 16, 17, 4, 5, 16, 17, 6, 7 } +#define _VEC_SWIZZLE_QUAT48_UNPACK_SHIFT (__vector unsigned int ) { 0, 0, 1, 0 } + +FORCEINLINE fltx4 UnpackQuaternion48SIMD(const Quaternion48* RESTRICT pVec) +{ + fltx4 q16s = LoadUnaligned3SIMD((const float*)pVec); + + bool wneg = pVec->wneg; + + q16s = vec_perm(q16s, Four_Threes, _VEC_SWIZZLE_QUAT48_UNPACK); + + u32x4 tmp = IntShiftLeftWordSIMD(*(u32x4*)&q16s, _VEC_SWIZZLE_QUAT48_UNPACK_SHIFT); + q16s = *(fltx4*)&tmp; + + const fltx4 vUpkMul = SplatXSIMD(g_SIMD_Quat48_Unpack_Magic_Constants); + const fltx4 vUpkAdd = SplatYSIMD(g_SIMD_Quat48_Unpack_Magic_Constants); + + fltx4 ret = vec_madd(q16s, vUpkMul, vUpkAdd); + + fltx4 dotxyz = Dot3SIMD(ret, ret); + dotxyz = ClampVectorSIMD(dotxyz, Four_Zeros, Four_Ones); + + fltx4 ww = SubSIMD(Four_Ones, dotxyz); + ww = SqrtSIMD(ww); + if (wneg) + { + ret = SetWSIMD(ret, NegSIMD(ww)); + } + else + { + ret = SetWSIMD(ret, ww); + } + return ret; +} + +#endif + +FORCEINLINE fltx4 SetWFromXSIMD(const fltx4& a, const fltx4& x) +{ + fltx4 value = SplatXSIMD(x); + return SetWSIMD(a, value); +} + +FORCEINLINE fltx4 SetWFromYSIMD(const fltx4& a, const fltx4& y) +{ + fltx4 value = SplatYSIMD(y); + return SetWSIMD(a, value); +} + +FORCEINLINE fltx4 SetWFromZSIMD(const fltx4& a, const fltx4& z) +{ + fltx4 value = SplatZSIMD(z); + return SetWSIMD(a, value); +} + +FORCEINLINE fltx4 CrossProductSIMD(const fltx4& A, const fltx4& B) +{ +#if defined( _X360 ) + return XMVector3Cross(A, B); +#elif defined( _WIN32 ) + fltx4 A1 = _mm_shuffle_ps(A, A, MM_SHUFFLE_REV(1, 2, 0, 3)); + fltx4 B1 = _mm_shuffle_ps(B, B, MM_SHUFFLE_REV(2, 0, 1, 3)); + fltx4 Result1 = MulSIMD(A1, B1); + fltx4 A2 = _mm_shuffle_ps(A, A, MM_SHUFFLE_REV(2, 0, 1, 3)); + fltx4 B2 = _mm_shuffle_ps(B, B, MM_SHUFFLE_REV(1, 2, 0, 3)); + fltx4 Result2 = MulSIMD(A2, B2); + return SubSIMD(Result1, Result2); + +#elif defined(_PS3) + return _vmathVfCross(A, B); +#else + fltx4 CrossVal; + SubFloat(CrossVal, 0) = SubFloat(A, 1) * SubFloat(B, 2) - SubFloat(A, 2) * SubFloat(B, 1); + SubFloat(CrossVal, 1) = SubFloat(A, 2) * SubFloat(B, 0) - SubFloat(A, 0) * SubFloat(B, 2); + SubFloat(CrossVal, 2) = SubFloat(A, 0) * SubFloat(B, 1) - SubFloat(A, 1) * SubFloat(B, 0); + SubFloat(CrossVal, 3) = 0; + return CrossVal; +#endif +} + +inline const fltx4 Length3SIMD(const fltx4 vec) +{ + fltx4 scLengthSqr = Dot3SIMD(vec, vec); + bi32x4 isSignificant = CmpGtSIMD(scLengthSqr, Four_Epsilons); + fltx4 scLengthInv = ReciprocalSqrtSIMD(scLengthSqr); + return AndSIMD(isSignificant, MulSIMD(scLengthInv, scLengthSqr)); +} + +inline const fltx4 Normalized3SIMD(const fltx4 vec) +{ + fltx4 scLengthSqr = Dot3SIMD(vec, vec); + bi32x4 isSignificant = CmpGtSIMD(scLengthSqr, Four_Epsilons); + fltx4 scLengthInv = ReciprocalSqrtSIMD(scLengthSqr); + return AndSIMD(isSignificant, MulSIMD(vec, scLengthInv)); +} + + +#ifndef COMPILER_GCC + +FORCEINLINE fltx4 operator+=(fltx4& a, FLTX4 b) +{ + a = AddSIMD(a, b); + return a; +} + +FORCEINLINE fltx4 operator-=(fltx4& a, FLTX4 b) +{ + a = SubSIMD(a, b); + return a; +} + + +FORCEINLINE fltx4 operator*=(fltx4& a, FLTX4 b) +{ + a = MulSIMD(a, b); + return a; +} + +#endif +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/sendproxy.h b/SpyCustom/sdk/sendproxy.h new file mode 100644 index 0000000..819f980 --- /dev/null +++ b/SpyCustom/sdk/sendproxy.h @@ -0,0 +1,52 @@ +#ifndef SENDPROXY_H +#define SENDPROXY_H + + +#include "dt_send.h" + + +class DVariant; + +void SendProxy_Color32ToInt(const SendProp* pProp, const void* pStruct, const void* pData, DVariant* pOut, int iElement, int objectID); +void SendProxy_EHandleToInt(const SendProp* pProp, const void* pStruct, const void* pVarData, DVariant* pOut, int iElement, int objectID); +void SendProxy_IntAddOne(const SendProp* pProp, const void* pStruct, const void* pVarData, DVariant* pOut, int iElement, int objectID); +void SendProxy_ShortAddOne(const SendProp* pProp, const void* pStruct, const void* pVarData, DVariant* pOut, int iElement, int objectID); + +SendProp SendPropBool( + const char* pVarName, + int offset, + int sizeofVar); + +SendProp SendPropEHandle( + const char* pVarName, + int offset, + int sizeofVar = SIZEOF_IGNORE, + int flags = 0, + SendVarProxyFn proxyFn = SendProxy_EHandleToInt); + +SendProp SendPropTime( + const char* pVarName, + int offset, + int sizeofVar = SIZEOF_IGNORE); + +#if !defined( NO_ENTITY_PREDICTION ) +SendProp SendPropPredictableId( + const char* pVarName, + int offset, + int sizeofVar = SIZEOF_IGNORE); +#endif + +SendProp SendPropIntWithMinusOneFlag( + const char* pVarName, + int offset, + int sizeofVar = SIZEOF_IGNORE, + int bits = -1, + SendVarProxyFn proxyFn = SendProxy_IntAddOne); + + +SendProp SendPropStringT(const char* pVarName, int offset, int sizeofVar); + +void* SendProxy_OnlyToTeam(const SendProp* pProp, const void* pStruct, const void* pVarData, CSendProxyRecipients* pRecipients, int objectID); + + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/sequence_Transitioner.h b/SpyCustom/sdk/sequence_Transitioner.h new file mode 100644 index 0000000..2140d78 --- /dev/null +++ b/SpyCustom/sdk/sequence_Transitioner.h @@ -0,0 +1,34 @@ +#ifndef SEQUENCE_TRANSITIONER_H +#define SEQUENCE_TRANSITIONER_H +#ifdef _WIN32 +#pragma once +#endif + + +class CSequenceTransitioner +{ +public: + void CheckForSequenceChange( + CStudioHdr* hdr, + int nCurSequence, + + bool bForceNewSequence, + + bool bInterpolate + ); + + void UpdateCurrent( + CStudioHdr* hdr, + int nCurSequence, + float flCurCycle, + float flCurPlaybackRate, + float flCurTime + ); + + void RemoveAll(void) { m_animationQueue.RemoveAll(); }; + +public: + CUtlVector< CAnimationLayer > m_animationQueue; +}; + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/shake.h b/SpyCustom/sdk/shake.h new file mode 100644 index 0000000..a82bf40 --- /dev/null +++ b/SpyCustom/sdk/shake.h @@ -0,0 +1,47 @@ +#ifndef SHAKE_H +#define SHAKE_H +#ifdef _WIN32 +#pragma once +#endif + + +struct ScreenShake_t +{ + int command; + float amplitude; + float frequency; + float duration; +}; + +enum ShakeCommand_t +{ + SHAKE_START = 0, + SHAKE_STOP, + SHAKE_AMPLITUDE, + SHAKE_FREQUENCY, + SHAKE_START_RUMBLEONLY, + SHAKE_START_NORUMBLE, +}; + + +extern int gmsgShake; + +extern int gmsgFade; + +#define FFADE_IN 0x0001 +#define FFADE_OUT 0x0002 +#define FFADE_MODULATE 0x0004 +#define FFADE_STAYOUT 0x0008 +#define FFADE_PURGE 0x0010 + +#define SCREENFADE_FRACBITS 9 +struct ScreenFade_t +{ + unsigned short duration; + unsigned short holdTime; + short fadeFlags; + byte r, g, b, a; +}; + + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/shared_classnames.h b/SpyCustom/sdk/shared_classnames.h new file mode 100644 index 0000000..c77784a --- /dev/null +++ b/SpyCustom/sdk/shared_classnames.h @@ -0,0 +1,17 @@ +#ifndef SHARED_CLASSNAMES_H +#define SHARED_CLASSNAMES_H +#ifdef _WIN32 +#pragma once +#endif + +#if defined( CLIENT_DLL ) + +#define CBaseEntity C_BaseEntity +#define CBaseCombatCharacter C_BaseCombatCharacter +#define CBaseAnimating C_BaseAnimating +#define CBasePlayer C_BasePlayer + +#endif + + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/shareddefs.h b/SpyCustom/sdk/shareddefs.h new file mode 100644 index 0000000..d3ec72c --- /dev/null +++ b/SpyCustom/sdk/shareddefs.h @@ -0,0 +1,838 @@ +#ifndef SHADERAPI_SHAREDDEFS_H +#define SHADERAPI_SHAREDDEFS_H + +#ifdef _WIN32 +#pragma once +#endif + + +enum ShaderShadeMode_t +{ + SHADER_FLAT = 0, + SHADER_SMOOTH +}; + +enum ShaderTexCoordComponent_t +{ + SHADER_TEXCOORD_S = 0, + SHADER_TEXCOORD_T, + SHADER_TEXCOORD_U +}; + +enum ShaderTexFilterMode_t +{ + SHADER_TEXFILTERMODE_NEAREST, + SHADER_TEXFILTERMODE_LINEAR, + SHADER_TEXFILTERMODE_NEAREST_MIPMAP_NEAREST, + SHADER_TEXFILTERMODE_LINEAR_MIPMAP_NEAREST, + SHADER_TEXFILTERMODE_NEAREST_MIPMAP_LINEAR, + SHADER_TEXFILTERMODE_LINEAR_MIPMAP_LINEAR, + SHADER_TEXFILTERMODE_ANISOTROPIC +}; + +enum ShaderTexWrapMode_t +{ + SHADER_TEXWRAPMODE_CLAMP, + SHADER_TEXWRAPMODE_REPEAT, + SHADER_TEXWRAPMODE_BORDER +}; + + +enum TextureStage_t +{ + SHADER_TEXTURE_STAGE0 = 0, + SHADER_TEXTURE_STAGE1, +}; + +enum Sampler_t +{ + SHADER_SAMPLER0 = 0, + SHADER_SAMPLER1, + SHADER_SAMPLER2, + SHADER_SAMPLER3, + SHADER_SAMPLER4, + SHADER_SAMPLER5, + SHADER_SAMPLER6, + SHADER_SAMPLER7, + SHADER_SAMPLER8, + SHADER_SAMPLER9, + SHADER_SAMPLER10, + SHADER_SAMPLER11, + SHADER_SAMPLER12, + SHADER_SAMPLER13, + SHADER_SAMPLER14, + SHADER_SAMPLER15, +}; + +enum VertexTextureSampler_t +{ + SHADER_VERTEXTEXTURE_SAMPLER0 = 0, + SHADER_VERTEXTEXTURE_SAMPLER1, + SHADER_VERTEXTEXTURE_SAMPLER2, + SHADER_VERTEXTEXTURE_SAMPLER3, +}; + + +#if defined( _X360 ) +#define REVERSE_DEPTH_ON_X360 +#endif + +#if defined( REVERSE_DEPTH_ON_X360 ) +#define ReverseDepthOnX360() true +#else +#define ReverseDepthOnX360() false +#endif + + + + + + +#include "bittools.h" + +#define TICK_INTERVAL (gpGlobals->interval_per_tick) + + +#define TIME_TO_TICKS( dt ) ( (int)( 0.5f + (float)(dt) / TICK_INTERVAL ) ) +#define TICKS_TO_TIME( t ) ( TICK_INTERVAL *( t ) ) +#define ROUND_TO_TICKS( t ) ( TICK_INTERVAL * TIME_TO_TICKS( t ) ) +#define TICK_NEVER_THINK (-1) + + +#define ANIMATION_CYCLE_BITS 15 + +#define ANIMATION_CYCLE_MINFRAC (1.0f / (1<GetViewVectors()->m_vView +#define VEC_HULL_MIN g_pGameRules->GetViewVectors()->m_vHullMin +#define VEC_HULL_MAX g_pGameRules->GetViewVectors()->m_vHullMax + +#define VEC_DUCK_HULL_MIN g_pGameRules->GetViewVectors()->m_vDuckHullMin +#define VEC_DUCK_HULL_MAX g_pGameRules->GetViewVectors()->m_vDuckHullMax +#define VEC_DUCK_VIEW g_pGameRules->GetViewVectors()->m_vDuckView + +#define VEC_OBS_HULL_MIN g_pGameRules->GetViewVectors()->m_vObsHullMin +#define VEC_OBS_HULL_MAX g_pGameRules->GetViewVectors()->m_vObsHullMax + +#define VEC_DEAD_VIEWHEIGHT g_pGameRules->GetViewVectors()->m_vDeadViewHeight + + +#define WATERJUMP_HEIGHT 8 + +#define MAX_CLIMB_SPEED 200 + + +#define TIME_TO_DUCK_MSECS 400 + +#define TIME_TO_UNDUCK_MSECS 200 + +inline float FractionDucked(int msecs) +{ + return clamp((float)msecs / (float)TIME_TO_DUCK_MSECS, 0.0f, 1.0f); +} + +inline float FractionUnDucked(int msecs) +{ + return clamp((float)msecs / (float)TIME_TO_UNDUCK_MSECS, 0.0f, 1.0f); +} + +#define MAX_WEAPON_SLOTS 6 +#define MAX_WEAPON_POSITIONS 20 +#define MAX_ITEM_TYPES 6 +#define MAX_WEAPONS 48 + +#define MAX_ITEMS 5 + +#define WEAPON_NOCLIP -1 + +#define MAX_AMMO_TYPES 32 +#define MAX_AMMO_SLOTS 32 + +#define HUD_PRINTNOTIFY 1 +#define HUD_PRINTCONSOLE 2 +#define HUD_PRINTTALK 3 +#define HUD_PRINTCENTER 4 + + +#define CLOSE_CAPTION_WARNIFMISSING ( 1<<0 ) +#define CLOSE_CAPTION_FROMPLAYER ( 1<<1 ) +#define CLOSE_CAPTION_GENDER_MALE ( 1<<2 ) +#define CLOSE_CAPTION_GENDER_FEMALE ( 1<<3 ) + +#define HIDEHUD_WEAPONSELECTION ( 1<<0 ) +#define HIDEHUD_FLASHLIGHT ( 1<<1 ) +#define HIDEHUD_ALL ( 1<<2 ) +#define HIDEHUD_HEALTH ( 1<<3 ) +#define HIDEHUD_PLAYERDEAD ( 1<<4 ) +#define HIDEHUD_NEEDSUIT ( 1<<5 ) +#define HIDEHUD_MISCSTATUS ( 1<<6 ) +#define HIDEHUD_CHAT ( 1<<7 ) +#define HIDEHUD_CROSSHAIR ( 1<<8 ) +#define HIDEHUD_VEHICLE_CROSSHAIR ( 1<<9 ) +#define HIDEHUD_INVEHICLE ( 1<<10 ) +#define HIDEHUD_BONUS_PROGRESS ( 1<<11 ) +#define HIDEHUD_RADAR ( 1<<12 ) + +#define HIDEHUD_BITCOUNT 13 + +#define bits_SUIT_DEVICE_SPRINT 0x00000001 +#define bits_SUIT_DEVICE_FLASHLIGHT 0x00000002 +#define bits_SUIT_DEVICE_BREATHER 0x00000004 + +#define MAX_SUIT_DEVICES 3 + + +#define MAX_PLAYERS 33 + + +#define MAX_PLACE_NAME_LENGTH 18 + +#define TEAM_ANY -1 +#define TEAM_INVALID -1 +#define TEAM_UNASSIGNED 0 +#define TEAM_SPECTATOR 1 +#define LAST_SHARED_TEAM TEAM_SPECTATOR + +#define FIRST_GAME_TEAM (LAST_SHARED_TEAM+1) + +#define MAX_TEAMS 32 +#define MAX_TEAM_NAME_LENGTH 32 + +#define WEAPON_NOT_CARRIED 0 +#define WEAPON_IS_CARRIED_BY_PLAYER 1 +#define WEAPON_IS_ACTIVE 2 + +#define SKILL_EASY 1 +#define SKILL_MEDIUM 2 +#define SKILL_HARD 3 + + +#define ITEM_FLAG_SELECTONEMPTY (1<<0) +#define ITEM_FLAG_NOAUTORELOAD (1<<1) +#define ITEM_FLAG_NOAUTOSWITCHEMPTY (1<<2) +#define ITEM_FLAG_LIMITINWORLD (1<<3) +#define ITEM_FLAG_EXHAUSTIBLE (1<<4) +#define ITEM_FLAG_DOHITLOCATIONDMG (1<<5) +#define ITEM_FLAG_NOAMMOPICKUPS (1<<6) +#define ITEM_FLAG_NOITEMPICKUP (1<<7) + +#define MAX_VIEWMODELS 2 + +#define MAX_BEAM_ENTS 10 + +#define TRACER_TYPE_DEFAULT 0x00000001 +#define TRACER_TYPE_GUNSHIP 0x00000002 +#define TRACER_TYPE_STRIDER 0x00000004 +#define TRACER_TYPE_GAUSS 0x00000008 +#define TRACER_TYPE_WATERBULLET 0x00000010 + +#define MUZZLEFLASH_TYPE_DEFAULT 0x00000001 +#define MUZZLEFLASH_TYPE_GUNSHIP 0x00000002 +#define MUZZLEFLASH_TYPE_STRIDER 0x00000004 + +enum +{ + MUZZLEFLASH_AR2 = 0, + MUZZLEFLASH_SHOTGUN, + MUZZLEFLASH_SMG1, + MUZZLEFLASH_SMG2, + MUZZLEFLASH_PISTOL, + MUZZLEFLASH_COMBINE, + MUZZLEFLASH_357, + MUZZLEFLASH_RPG, + MUZZLEFLASH_COMBINE_TURRET, + + MUZZLEFLASH_FIRSTPERSON = 0x100, +}; + +#define TRACER_FLAG_WHIZ 0x0001 +#define TRACER_FLAG_USEATTACHMENT 0x0002 + +#define TRACER_DONT_USE_ATTACHMENT -1 + +enum +{ + ENTITY_DISSOLVE_NORMAL = 0, + ENTITY_DISSOLVE_ELECTRICAL, + ENTITY_DISSOLVE_ELECTRICAL_LIGHT, + ENTITY_DISSOLVE_CORE, + + ENTITY_DISSOLVE_BITS = 3 +}; + +#define HITGROUP_GENERIC 0 +#define HITGROUP_HEAD 1 +#define HITGROUP_CHEST 2 +#define HITGROUP_STOMACH 3 +#define HITGROUP_LEFTARM 4 +#define HITGROUP_RIGHTARM 5 +#define HITGROUP_LEFTLEG 6 +#define HITGROUP_RIGHTLEG 7 +#define HITGROUP_GEAR 10 + +enum PLAYER_ANIM +{ + PLAYER_IDLE, + PLAYER_WALK, + PLAYER_JUMP, + PLAYER_SUPERJUMP, + PLAYER_DIE, + PLAYER_ATTACK1, + PLAYER_IN_VEHICLE, + + PLAYER_RELOAD, + PLAYER_START_AIMING, + PLAYER_LEAVE_AIMING, +}; + +#ifdef HL2_DLL +#define PLAYER_FATAL_FALL_SPEED 922.5f +#define PLAYER_MAX_SAFE_FALL_SPEED 526.5f +#define PLAYER_LAND_ON_FLOATING_OBJECT 173 +#define PLAYER_MIN_BOUNCE_SPEED 173 +#define PLAYER_FALL_PUNCH_THRESHOLD 303.0f +#else +#define PLAYER_FATAL_FALL_SPEED 1024 +#define PLAYER_MAX_SAFE_FALL_SPEED 580 +#define PLAYER_LAND_ON_FLOATING_OBJECT 200 +#define PLAYER_MIN_BOUNCE_SPEED 200 +#define PLAYER_FALL_PUNCH_THRESHOLD (float)350 +#endif +#define DAMAGE_FOR_FALL_SPEED 100.0f / ( PLAYER_FATAL_FALL_SPEED - PLAYER_MAX_SAFE_FALL_SPEED ) + + +#define AUTOAIM_2DEGREES 0.0348994967025 +#define AUTOAIM_5DEGREES 0.08715574274766 +#define AUTOAIM_8DEGREES 0.1391731009601 +#define AUTOAIM_10DEGREES 0.1736481776669 +#define AUTOAIM_20DEGREES 0.3490658503989 + +#define AUTOAIM_SCALE_DEFAULT 1.0f +#define AUTOAIM_SCALE_DIRECT_ONLY 0.0f + +#define DMG_GENERIC 0 +#define DMG_CRUSH (1 << 0) +#define DMG_BULLET (1 << 1) +#define DMG_SLASH (1 << 2) +#define DMG_BURN (1 << 3) +#define DMG_VEHICLE (1 << 4) +#define DMG_FALL (1 << 5) +#define DMG_BLAST (1 << 6) +#define DMG_CLUB (1 << 7) +#define DMG_SHOCK (1 << 8) +#define DMG_SONIC (1 << 9) +#define DMG_ENERGYBEAM (1 << 10) +#define DMG_PREVENT_PHYSICS_FORCE (1 << 11) +#define DMG_NEVERGIB (1 << 12) +#define DMG_ALWAYSGIB (1 << 13) +#define DMG_DROWN (1 << 14) + + +#define DMG_PARALYZE (1 << 15) +#define DMG_NERVEGAS (1 << 16) +#define DMG_POISON (1 << 17) +#define DMG_RADIATION (1 << 18) +#define DMG_DROWNRECOVER (1 << 19) +#define DMG_ACID (1 << 20) +#define DMG_SLOWBURN (1 << 21) + +#define DMG_REMOVENORAGDOLL (1<<22) +#define DMG_PHYSGUN (1<<23) +#define DMG_PLASMA (1<<24) +#define DMG_AIRBOAT (1<<25) + +#define DMG_DISSOLVE (1<<26) +#define DMG_BLAST_SURFACE (1<<27) +#define DMG_DIRECT (1<<28) +#define DMG_BUCKSHOT (1<<29) + +#define DMG_LASTGENERICFLAG DMG_BUCKSHOT + + + +#define DAMAGE_NO 0 +#define DAMAGE_EVENTS_ONLY 1 +#define DAMAGE_YES 2 +#define DAMAGE_AIM 3 + +enum +{ + OBS_MODE_NONE = 0, + OBS_MODE_DEATHCAM, + OBS_MODE_FREEZECAM, + OBS_MODE_FIXED, + OBS_MODE_IN_EYE, + OBS_MODE_CHASE, + OBS_MODE_ROAMING, + + NUM_OBSERVER_MODES, +}; + +#define LAST_PLAYER_OBSERVERMODE OBS_MODE_ROAMING + +enum { + OBS_ALLOW_ALL = 0, + OBS_ALLOW_TEAM, + OBS_ALLOW_NONE, + + OBS_ALLOW_NUM_MODES, +}; + +enum +{ + TYPE_TEXT = 0, + TYPE_INDEX, + TYPE_URL, + TYPE_FILE, +}; + +enum +{ + VGUI_SCREEN_ACTIVE = 0x1, + VGUI_SCREEN_VISIBLE_TO_TEAMMATES = 0x2, + VGUI_SCREEN_ATTACHED_TO_VIEWMODEL = 0x4, + VGUI_SCREEN_TRANSPARENT = 0x8, + VGUI_SCREEN_ONLY_USABLE_BY_OWNER = 0x10, + + VGUI_SCREEN_MAX_BITS = 5 +}; + +typedef enum +{ + USE_OFF = 0, + USE_ON = 1, + USE_SET = 2, + USE_TOGGLE = 3 +} USE_TYPE; + +#define COLOR_RED Color(255, 64, 64, 255) +#define COLOR_BLUE Color(153, 204, 255, 255) +#define COLOR_YELLOW Color(255, 178, 0, 255) +#define COLOR_GREEN Color(153, 255, 153, 255) +#define COLOR_GREY Color(204, 204, 204, 255) + +enum +{ + DONT_BLEED = -1, + + BLOOD_COLOR_RED = 0, + BLOOD_COLOR_YELLOW, + BLOOD_COLOR_GREEN, + BLOOD_COLOR_MECH, + +#if defined( HL2_EPISODIC ) + BLOOD_COLOR_ANTLION, + BLOOD_COLOR_ZOMBIE, + BLOOD_COLOR_ANTLION_WORKER, + BLOOD_COLOR_BLOB, + BLOOD_COLOR_BLOB_FROZEN, +#endif + +#if defined( INFESTED_DLL ) + BLOOD_COLOR_BLOB, + BLOOD_COLOR_BLOB_FROZEN, +#endif + + BLOOD_COLOR_BRIGHTGREEN, +}; + +enum PassengerRole_t +{ + VEHICLE_ROLE_NONE = -1, + + VEHICLE_ROLE_DRIVER = 0, + + LAST_SHARED_VEHICLE_ROLE, +}; + +enum +{ + FX_WATER_IN_SLIME = 0x1, +}; + + +#define MAX_CONTEXT_LENGTH 32 +#define NO_THINK_CONTEXT -1 + +enum +{ + EFL_KILLME = (1 << 0), + EFL_DORMANT = (1 << 1), + EFL_NOCLIP_ACTIVE = (1 << 2), + EFL_SETTING_UP_BONES = (1 << 3), + EFL_KEEP_ON_RECREATE_ENTITIES = (1 << 4), + + EFL_DIRTY_SHADOWUPDATE = (1 << 5), + EFL_NOTIFY = (1 << 6), + + EFL_FORCE_CHECK_TRANSMIT = (1 << 7), + + EFL_BOT_FROZEN = (1 << 8), + EFL_SERVER_ONLY = (1 << 9), + EFL_NO_AUTO_EDICT_ATTACH = (1 << 10), + + EFL_DIRTY_ABSTRANSFORM = (1 << 11), + EFL_DIRTY_ABSVELOCITY = (1 << 12), + EFL_DIRTY_ABSANGVELOCITY = (1 << 13), + EFL_DIRTY_SURROUNDING_COLLISION_BOUNDS = (1 << 14), + EFL_DIRTY_SPATIAL_PARTITION = (1 << 15), + EFL_HAS_PLAYER_CHILD = (1 << 16), + + EFL_IN_SKYBOX = (1 << 17), + EFL_USE_PARTITION_WHEN_NOT_SOLID = (1 << 18), + EFL_TOUCHING_FLUID = (1 << 19), + + EFL_IS_BEING_LIFTED_BY_BARNACLE = (1 << 20), + EFL_NO_ROTORWASH_PUSH = (1 << 21), + EFL_NO_THINK_FUNCTION = (1 << 22), + EFL_NO_GAME_PHYSICS_SIMULATION = (1 << 23), + + EFL_CHECK_UNTOUCH = (1 << 24), + EFL_DONTBLOCKLOS = (1 << 25), + EFL_DONTWALKON = (1 << 26), + EFL_NO_DISSOLVE = (1 << 27), + EFL_NO_MEGAPHYSCANNON_RAGDOLL = (1 << 28), + EFL_NO_WATER_VELOCITY_CHANGE = (1 << 29), + EFL_NO_PHYSCANNON_INTERACTION = (1 << 30), + EFL_NO_DAMAGE_FORCES = (1 << 31), +}; + +const int FX_BLOODSPRAY_DROPS = 0x01; +const int FX_BLOODSPRAY_GORE = 0x02; +const int FX_BLOODSPRAY_CLOUD = 0x04; +const int FX_BLOODSPRAY_ALL = 0xFF; + +#define MAX_SCREEN_OVERLAYS 10 + +enum +{ + GROUNDLINK = 0, + TOUCHLINK, + STEPSIMULATION, + MODELSCALE, + POSITIONWATCHER, + PHYSICSPUSHLIST, + VPHYSICSUPDATEAI, + VPHYSICSWATCHER, + + NUM_DATAOBJECT_TYPES, +}; + +class CBaseEntity; + +class CBaseEntity; + +enum FireBulletsFlags_t +{ + FIRE_BULLETS_FIRST_SHOT_ACCURATE = 0x1, + FIRE_BULLETS_DONT_HIT_UNDERWATER = 0x2, + FIRE_BULLETS_ALLOW_WATER_SURFACE_IMPACTS = 0x4, + FIRE_BULLETS_TEMPORARY_DANGER_SOUND = 0x8, + + FIRE_BULLETS_NO_PIERCING_SPARK = 0x16, + FIRE_BULLETS_HULL = 0x32, + FIRE_BULLETS_ANGULAR_SPREAD = 0x64, +}; + + +struct FireBulletsInfo_t +{ + FireBulletsInfo_t() + { + m_iShots = 1; + m_vecSpread.Init(0, 0, 0); + m_flDistance = 8192; + m_iTracerFreq = 4; + m_flDamage = 0.0f; + m_flPlayerDamage = 0.0f; + m_pAttacker = NULL; + m_nFlags = 0; + m_pAdditionalIgnoreEnt = NULL; + m_flDamageForceScale = 1.0f; + +#ifdef _DEBUG + m_iAmmoType = -1; + m_vecSrc.Init(VEC_T_NAN, VEC_T_NAN, VEC_T_NAN); + m_vecDirShooting.Init(VEC_T_NAN, VEC_T_NAN, VEC_T_NAN); +#endif + m_bPrimaryAttack = true; + } + + FireBulletsInfo_t(int nShots, const Vector& vecSrc, const Vector& vecDir, const Vector& vecSpread, float flDistance, int nAmmoType, bool bPrimaryAttack = true) + { + m_iShots = nShots; + m_vecSrc = vecSrc; + m_vecDirShooting = vecDir; + m_vecSpread = vecSpread; + m_flDistance = flDistance; + m_iAmmoType = nAmmoType; + m_iTracerFreq = 4; + m_flDamage = 0; + m_flPlayerDamage = 0; + m_pAttacker = NULL; + m_nFlags = 0; + m_pAdditionalIgnoreEnt = NULL; + m_flDamageForceScale = 1.0f; + m_bPrimaryAttack = bPrimaryAttack; + } + + int m_iShots; + Vector m_vecSrc; + Vector m_vecDirShooting; + Vector m_vecSpread; + float m_flDistance; + int m_iAmmoType; + int m_iTracerFreq; + float m_flDamage; + float m_flPlayerDamage; + int m_nFlags; + float m_flDamageForceScale; + CBaseEntity* m_pAttacker; + CBaseEntity* m_pAdditionalIgnoreEnt; + bool m_bPrimaryAttack; +}; + +struct StepSimulationStep +{ + int nTickCount; + Vector vecOrigin; + Quaternion qRotation; +}; + +struct StepSimulationData +{ + bool m_bOriginActive; + bool m_bAnglesActive; + + StepSimulationStep m_Previous2; + + StepSimulationStep m_Previous; + + StepSimulationStep m_Discontinuity; + + StepSimulationStep m_Next; + QAngle m_angNextRotation; + + int m_nLastProcessTickCount; + Vector m_vecNetworkOrigin; + int m_networkCell[3]; + QAngle m_angNetworkAngles; +}; + +struct ModelScale +{ + float m_flModelScaleStart; + float m_flModelScaleGoal; + float m_flModelScaleFinishTime; + float m_flModelScaleStartTime; +}; + +#include "soundflags.h" + +struct CSoundParameters; +typedef short HSOUNDSCRIPTHANDLE; +struct EmitSound_t +{ + EmitSound_t() : + m_nChannel(0), + m_pSoundName(0), + m_flVolume(VOL_NORM), + m_SoundLevel(SNDLVL_NONE), + m_nFlags(0), + m_nPitch(PITCH_NORM), + m_pOrigin(0), + m_flSoundTime(0.0f), + m_pflSoundDuration(0), + m_bEmitCloseCaption(true), + m_bWarnOnMissingCloseCaption(false), + m_bWarnOnDirectWaveReference(false), + m_nSpeakerEntity(-1), + m_UtlVecSoundOrigin(), + m_hSoundScriptHandle(-1) + { + } + + EmitSound_t(const CSoundParameters& src); + + int m_nChannel; + char const* m_pSoundName; + float m_flVolume; + soundlevel_t m_SoundLevel; + int m_nFlags; + int m_nPitch; + const Vector* m_pOrigin; + float m_flSoundTime; + float* m_pflSoundDuration; + bool m_bEmitCloseCaption; + bool m_bWarnOnMissingCloseCaption; + bool m_bWarnOnDirectWaveReference; + int m_nSpeakerEntity; + mutable CUtlVector< Vector > m_UtlVecSoundOrigin; + mutable HSOUNDSCRIPTHANDLE m_hSoundScriptHandle; +}; + +#define MAX_ACTORS_IN_SCENE 16 + +#define MAX_CONTROL_POINTS 8 +#define MAX_CONTROL_POINT_GROUPS 8 + +#define MAX_PREVIOUS_POINTS 3 + +#define MAX_CONTROL_POINT_TEAMS 8 + +#define MAX_CAPLAYOUT_LENGTH 32 + +#define MAX_ROUND_NAME 32 + +#define MAX_ROUND_IMAGE_NAME 64 + +#define TEAMPLAY_ROUND_WIN_SCORE 1 + +enum +{ + CP_WARN_NORMAL = 0, + CP_WARN_FINALCAP, + CP_WARN_NO_ANNOUNCEMENTS +}; + +#define PREDICTION_ERROR_CHECK_LEVEL 0 + +#define PREDICTION_ERROR_CHECK_STACKS_FOR_MISSING 0 + +enum +{ + RT_STATE_SETUP, + RT_STATE_NORMAL, +}; + +enum +{ + SIMULATION_TIME_WINDOW_BITS = 8, +}; + + +#define CELL_COUNT( bits ) ( (MAX_COORD_INTEGER*2) / (1 << (bits)) ) +#define CELL_COUNT_BITS( bits ) MINIMUM_BITS_NEEDED( CELL_COUNT( bits ) ) +#define CELL_BASEENTITY_ORIGIN_CELL_BITS 5 + + +#ifdef GAME_HAS_NO_USE_KEY +#define COMMENTARY_BUTTONS (IN_ATTACK | IN_ATTACK2 | IN_USE) +#else +#define COMMENTARY_BUTTONS (IN_USE) +#endif + +bool IsHeadTrackingEnabled(); + + +#define MAX_SPLITSCREEN_PLAYERS 1 + + +inline bool IsSplitScreenSupported() +{ + return (MAX_SPLITSCREEN_PLAYERS > 1) ? true : false; +} + +enum InvalidatePhysicsBits_t +{ + POSITION_CHANGED = 0x1, + ANGLES_CHANGED = 0x2, + VELOCITY_CHANGED = 0x4, + ANIMATION_CHANGED = 0x8, + BOUNDS_CHANGED = 0x10, + SEQUENCE_CHANGED = 0x20, +}; + +enum Class_T +{ + CLASS_NONE = 0, + CLASS_PLAYER, + CLASS_PLAYER_ALLY, + CLASS_PLAYER_ALLY_VITAL, + CLASS_ANTLION, + CLASS_BARNACLE, + CLASS_BLOB, + CLASS_BULLSEYE, + CLASS_CITIZEN_PASSIVE, + CLASS_CITIZEN_REBEL, + CLASS_COMBINE, + CLASS_COMBINE_GUNSHIP, + CLASS_CONSCRIPT, + CLASS_HEADCRAB, + CLASS_MANHACK, + CLASS_METROPOLICE, + CLASS_MILITARY, + CLASS_SCANNER, + CLASS_STALKER, + CLASS_VORTIGAUNT, + CLASS_ZOMBIE, + CLASS_PROTOSNIPER, + CLASS_MISSILE, + CLASS_FLARE, + CLASS_EARTH_FAUNA, + CLASS_HACKED_ROLLERMINE, + CLASS_COMBINE_HUNTER, + + LAST_SHARED_ENTITY_CLASS, +}; + +#define FACTION_NONE 0 +#define LAST_SHARED_FACTION (FACTION_NONE) +#define NUM_SHARED_FACTIONS (FACTION_NONE + 1) + + + + + + + + + + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/shattersurfacetypes.h b/SpyCustom/sdk/shattersurfacetypes.h new file mode 100644 index 0000000..88ed8ba --- /dev/null +++ b/SpyCustom/sdk/shattersurfacetypes.h @@ -0,0 +1,13 @@ +#if !defined ( SHATTERSURFACETYPES_H ) +#define SHATTERSURFACETYPES_H +#ifdef _WIN32 +#pragma once +#endif + +enum ShatterSurface_t +{ + SHATTERSURFACE_GLASS = 0, + SHATTERSURFACE_TILE = 1, +}; + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/smartptr.h b/SpyCustom/sdk/smartptr.h new file mode 100644 index 0000000..5b005ec --- /dev/null +++ b/SpyCustom/sdk/smartptr.h @@ -0,0 +1,227 @@ +#ifndef SMARTPTR_H +#define SMARTPTR_H +#ifdef _WIN32 +#pragma once +#endif + + +class CRefCountAccessor +{ +public: + template< class T > + static void AddRef(T* pObj) + { + pObj->AddRef(); + } + + template< class T > + static void Release(T* pObj) + { + pObj->Release(); + } +}; + +class CRefCountAccessorLongName +{ +public: + template< class T > + static void AddRef(T* pObj) + { + pObj->AddReference(); + } + + template< class T > + static void Release(T* pObj) + { + pObj->ReleaseReference(); + } +}; + + +template < typename T > +class CPlainAutoPtr +{ +public: + explicit CPlainAutoPtr(T* p = NULL) : m_p(p) {} + ~CPlainAutoPtr(void) { Delete(); } + +public: + void Delete(void) { delete Detach(); } + +private: + CPlainAutoPtr(CPlainAutoPtr const& x); + CPlainAutoPtr& operator = (CPlainAutoPtr const& x); + +public: + void Attach(T* p) { m_p = p; } + T* Detach(void) { T* p(m_p); m_p = NULL; return p; } + +public: + bool IsValid(void) const { return m_p != NULL; } + T* Get(void) const { return m_p; } + T* operator -> (void) const { return Get(); } + T& operator * (void) const { return *Get(); } + +private: + T* m_p; +}; + +template < typename T > +class CArrayAutoPtr : public CPlainAutoPtr < T > +{ +public: + explicit CArrayAutoPtr(T* p = NULL) { this->Attach(p); } + ~CArrayAutoPtr(void) { this->Delete(); } + +public: + void Delete(void) { delete[] CPlainAutoPtr < T >::Detach(); } + +public: + T& operator [] (int k) const { return CPlainAutoPtr < T >::Get()[k]; } +}; + + +template +class CSmartPtr +{ +public: + CSmartPtr(); + CSmartPtr(T* pObj); + CSmartPtr(const CSmartPtr& other); + ~CSmartPtr(); + + T* operator=(T* pObj); + void operator=(const CSmartPtr& other); + const T* operator->() const; + T* operator->(); + bool operator!() const; + bool operator==(const T* pOther) const; + bool IsValid() const; + T* GetObject() const; + void MarkDeleted(); + +private: + T* m_pObj; +}; + + +template< class T, class RefCountAccessor > +inline CSmartPtr::CSmartPtr() +{ + m_pObj = NULL; +} + +template< class T, class RefCountAccessor > +inline CSmartPtr::CSmartPtr(T* pObj) +{ + m_pObj = NULL; + *this = pObj; +} + +template< class T, class RefCountAccessor > +inline CSmartPtr::CSmartPtr(const CSmartPtr& other) +{ + m_pObj = NULL; + *this = other; +} + +template< class T, class RefCountAccessor > +inline CSmartPtr::~CSmartPtr() +{ + if (m_pObj) + { + RefCountAccessor::Release(m_pObj); + } +} + +template< class T, class RefCountAccessor > +inline T* CSmartPtr::operator=(T* pObj) +{ + if (pObj == m_pObj) + return pObj; + + if (pObj) + { + RefCountAccessor::AddRef(pObj); + } + if (m_pObj) + { + RefCountAccessor::Release(m_pObj); + } + m_pObj = pObj; + return pObj; +} + +template< class T, class RefCountAccessor > +inline void CSmartPtr::MarkDeleted() +{ + m_pObj = NULL; +} + +template< class T, class RefCountAccessor > +inline void CSmartPtr::operator=(const CSmartPtr& other) +{ + *this = other.m_pObj; +} + +template< class T, class RefCountAccessor > +inline const T* CSmartPtr::operator->() const +{ + return m_pObj; +} + +template< class T, class RefCountAccessor > +inline T* CSmartPtr::operator->() +{ + return m_pObj; +} + +template< class T, class RefCountAccessor > +inline bool CSmartPtr::operator!() const +{ + return !m_pObj; +} + +template< class T, class RefCountAccessor > +inline bool CSmartPtr::operator==(const T* pOther) const +{ + return m_pObj == pOther; +} + +template< class T, class RefCountAccessor > +inline bool CSmartPtr::IsValid() const +{ + return m_pObj != NULL; +} + +template< class T, class RefCountAccessor > +inline T* CSmartPtr::GetObject() const +{ + return m_pObj; +} + + +template < typename T > +class CAutoPushPop +{ +public: + explicit CAutoPushPop(T& var) : m_rVar(var), m_valPop(var) {} + CAutoPushPop(T& var, T const& valPush) : m_rVar(var), m_valPop(var) { m_rVar = valPush; } + CAutoPushPop(T& var, T const& valPush, T const& valPop) : m_rVar(var), m_valPop(var) { m_rVar = valPush; } + + ~CAutoPushPop() { m_rVar = m_valPop; } + +private: + CAutoPushPop(CAutoPushPop const& x); + CAutoPushPop& operator = (CAutoPushPop const& x); + +public: + T& Get() { return m_rVar; } + +private: + T& m_rVar; + T m_valPop; +}; + + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/soundflags.h b/SpyCustom/sdk/soundflags.h new file mode 100644 index 0000000..c24ce8f --- /dev/null +++ b/SpyCustom/sdk/soundflags.h @@ -0,0 +1,161 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef SOUNDFLAGS_H +#define SOUNDFLAGS_H + +#if defined( _WIN32 ) +#pragma once +#endif + + +//----------------------------------------------------------------------------- +// channels +//----------------------------------------------------------------------------- +enum +{ + CHAN_REPLACE = -1, + CHAN_AUTO = 0, + CHAN_WEAPON = 1, + CHAN_VOICE = 2, + CHAN_ITEM = 3, + CHAN_BODY = 4, + CHAN_STREAM = 5, // allocate stream channel from the static or dynamic area + CHAN_STATIC = 6, // allocate channel from the static area + CHAN_VOICE2 = 7, + CHAN_VOICE_BASE = 8, // allocate channel for network voice data + CHAN_USER_BASE = (CHAN_VOICE_BASE + 128) // Anything >= this number is allocated to game code. +}; + +//----------------------------------------------------------------------------- +// common volume values +//----------------------------------------------------------------------------- +#define VOL_NORM 1.0f + + +//----------------------------------------------------------------------------- +// common attenuation values +//----------------------------------------------------------------------------- +#define ATTN_NONE 0.0f +#define ATTN_NORM 0.8f +#define ATTN_IDLE 2.0f +#define ATTN_STATIC 1.25f +#define ATTN_RICOCHET 1.5f + +// HL2 world is 8x bigger now! We want to hear gunfire from farther. +// Don't change this without consulting Kelly or Wedge (sjb). +#define ATTN_GUNFIRE 0.27f + +enum soundlevel_t +{ + SNDLVL_NONE = 0, + + SNDLVL_20dB = 20, // rustling leaves + SNDLVL_25dB = 25, // whispering + SNDLVL_30dB = 30, // library + SNDLVL_35dB = 35, + SNDLVL_40dB = 40, + SNDLVL_45dB = 45, // refrigerator + + SNDLVL_50dB = 50, // 3.9 // average home + SNDLVL_55dB = 55, // 3.0 + + SNDLVL_IDLE = 60, // 2.0 + SNDLVL_60dB = 60, // 2.0 // normal conversation, clothes dryer + + SNDLVL_65dB = 65, // 1.5 // washing machine, dishwasher + SNDLVL_STATIC = 66, // 1.25 + + SNDLVL_70dB = 70, // 1.0 // car, vacuum cleaner, mixer, electric sewing machine + + SNDLVL_NORM = 75, + SNDLVL_75dB = 75, // 0.8 // busy traffic + + SNDLVL_80dB = 80, // 0.7 // mini-bike, alarm clock, noisy restaurant, office tabulator, outboard motor, passing snowmobile + SNDLVL_TALKING = 80, // 0.7 + SNDLVL_85dB = 85, // 0.6 // average factory, electric shaver + SNDLVL_90dB = 90, // 0.5 // screaming child, passing motorcycle, convertible ride on frw + SNDLVL_95dB = 95, + SNDLVL_100dB = 100, // 0.4 // subway train, diesel truck, woodworking shop, pneumatic drill, boiler shop, jackhammer + SNDLVL_105dB = 105, // helicopter, power mower + SNDLVL_110dB = 110, // snowmobile drvrs seat, inboard motorboat, sandblasting + SNDLVL_120dB = 120, // auto horn, propeller aircraft + SNDLVL_130dB = 130, // air raid siren + + SNDLVL_GUNFIRE = 140, // 0.27 // THRESHOLD OF PAIN, gunshot, jet engine + SNDLVL_140dB = 140, // 0.2 + + SNDLVL_150dB = 150, // 0.2 + + SNDLVL_180dB = 180, // rocket launching + + // NOTE: Valid soundlevel_t values are 0-255. + // 256-511 are reserved for sounds using goldsrc compatibility attenuation. +}; + +#define MAX_SNDLVL_BITS 9 // Used to encode 0-255 for regular soundlevel_t's and 256-511 for goldsrc-compatible ones. +#define MIN_SNDLVL_VALUE 0 +#define MAX_SNDLVL_VALUE ((1< 50) ? (20.0f / (float)(a - 50)) : 4.0 ) + +// This is a limit due to network encoding. +// It encodes attenuation * 64 in 8 bits, so the maximum is (255 / 64) +#define MAX_ATTENUATION 3.98f + +//----------------------------------------------------------------------------- +// Flags to be or-ed together for the iFlags field +//----------------------------------------------------------------------------- +enum SoundFlags_t +{ + SND_NOFLAGS = 0, // to keep the compiler happy + SND_CHANGE_VOL = (1 << 0), // change sound vol + SND_CHANGE_PITCH = (1 << 1), // change sound pitch + SND_STOP = (1 << 2), // stop the sound + SND_SPAWNING = (1 << 3), // we're spawning, used in some cases for ambients + // not sent over net, only a param between dll and server. + SND_DELAY = (1 << 4), // sound has an initial delay + SND_STOP_LOOPING = (1 << 5), // stop all looping sounds on the entity. + SND_SPEAKER = (1 << 6), // being played again by a microphone through a speaker + + SND_SHOULDPAUSE = (1 << 7), // this sound should be paused if the game is paused + SND_IGNORE_PHONEMES = (1 << 8), + SND_IGNORE_NAME = (1 << 9), // used to change all sounds emitted by an entity, regardless of scriptname + + SND_DO_NOT_OVERWRITE_EXISTING_ON_CHANNEL = (1 << 10), +}; + +#define SND_FLAG_BITS_ENCODE 11 + +#define MAX_SOUND_INDEX_BITS 14 +#define MAX_SOUNDS (1< +#elif defined ( _PS3 ) +#include +#include +#else +#include +#ifndef _LINUX +#include +#endif +#endif + +#ifndef SPU +#include "vector.h" +#include "mathlib.h" +#else +#include "mathlib/math_pfns.h" +#endif + +#include "fltx4.h" + +#ifdef _X360 +typedef __vector4 FLTX4; +#elif defined( _PS3 ) +typedef vec_float4 FLTX4; +#else +typedef const fltx4& FLTX4; +#endif + +struct ALIGN16 intx4 +{ + int32 m_i32[4]; + + inline int& operator[](int which) + { + return m_i32[which]; + } + + inline const int& operator[](int which) const + { + return m_i32[which]; + } + + inline int32* Base() { + return m_i32; + } + + inline const int32* Base() const + { + return m_i32; + } + + inline bool operator==(const intx4& other) const + { + return m_i32[0] == other.m_i32[0] && + m_i32[1] == other.m_i32[1] && + m_i32[2] == other.m_i32[2] && + m_i32[3] == other.m_i32[3]; + } +} ALIGN16_POST; + + +#if defined( _DEBUG ) && defined( _X360 ) +FORCEINLINE void TestVPUFlags() +{ + __vector4 a; + __asm + { + mfvscr a; + } + unsigned int* flags = (unsigned int*)&a; + unsigned int controlWord = flags[3]; + Assert(controlWord == 0); +} +#else +FORCEINLINE void TestVPUFlags() {} +#endif + + +#ifdef _X360 +#define Four_Zeros XMVectorZero() +#define Four_Ones XMVectorSplatOne() +extern const fltx4 Four_Twos; +extern const fltx4 Four_Threes; +extern const fltx4 Four_Fours; +extern const fltx4 Four_Point225s; +extern const fltx4 Four_PointFives; +extern const fltx4 Four_Thirds; +extern const fltx4 Four_TwoThirds; +extern const fltx4 Four_NegativeOnes; +extern const fltx4 Four_DegToRad; +#elif defined(SPU) +#define Four_Zeros spu_splats( 0.0f ) +#define Four_Ones spu_splats( 1.0f ) +#define Four_Twos spu_splats( 2.0f ) +#define Four_Threes spu_splats( 3.0f ) +#define Four_Fours spu_splats( 4.0f ) +#define Four_Point225s spu_splats( 0.225f ) +#define Four_PointFives spu_splats( 0.5f ) +#define Four_Thirds spu_splats( 0.33333333 ); +#define Four_TwoThirds spu_splats( 0.66666666 ); +#define Four_NegativeOnes spu_splats( -1.0f ) +#define Four_DegToRad spu_splats((float)(M_PI_F / 180.f)) +#else +extern const fltx4 Four_Zeros; +extern const fltx4 Four_Ones; +extern const fltx4 Four_Twos; +extern const fltx4 Four_Threes; +extern const fltx4 Four_Fours; +extern const fltx4 Four_Point225s; +extern const fltx4 Four_PointFives; +extern const fltx4 Four_Thirds; +extern const fltx4 Four_TwoThirds; +extern const fltx4 Four_NegativeOnes; +extern const fltx4 Four_DegToRad; +#endif +extern const fltx4 Four_Epsilons; +extern const fltx4 Four_2ToThe21s; +extern const fltx4 Four_2ToThe22s; +extern const fltx4 Four_2ToThe23s; +extern const fltx4 Four_2ToThe24s; +extern const fltx4 Four_Origin; +extern const fltx4 Four_FLT_MAX; +extern const fltx4 Four_Negative_FLT_MAX; +extern const fltx4 g_SIMD_0123; + + +extern const fltx4 Four_LinearToGammaCoefficients_A; +extern const fltx4 Four_LinearToGammaCoefficients_B; +extern const fltx4 Four_LinearToGammaCoefficients_C; +extern const fltx4 Four_LinearToGammaCoefficients_D; +extern const fltx4 Four_LinearToGammaCoefficients_E; + +extern const fltx4 Four_GammaToLinearCoefficients_A; +extern const fltx4 Four_GammaToLinearCoefficients_B; +extern const fltx4 Four_GammaToLinearCoefficients_C; +extern const fltx4 Four_GammaToLinearCoefficients_D; + + +#ifndef ALIGN16_POST +#define ALIGN16_POST +#endif +extern const ALIGN16 int32 g_SIMD_clear_signmask[] ALIGN16_POST; +extern const ALIGN16 int32 g_SIMD_signmask[] ALIGN16_POST; +extern const ALIGN16 int32 g_SIMD_lsbmask[] ALIGN16_POST; +extern const ALIGN16 int32 g_SIMD_clear_wmask[] ALIGN16_POST; +extern const ALIGN16 int32 g_SIMD_ComponentMask[4][4] ALIGN16_POST; +extern const ALIGN16 int32 g_SIMD_AllOnesMask[] ALIGN16_POST; +extern const fltx4 g_SIMD_Identity[4]; +extern const ALIGN16 int32 g_SIMD_Low16BitsMask[] ALIGN16_POST; + +extern const int32 ALIGN16 g_SIMD_SkipTailMask[4][4] ALIGN16_POST; + +extern const int32 ALIGN16 g_SIMD_EveryOtherMask[]; +#ifdef PLATFORM_PPC +#if defined(_X360) +#define PREFETCH360(address, offset) __dcbt(offset,address) +#elif defined(_PS3) +#define PREFETCH360(address, offset) __dcbt( reinterpret_cast< const char * >(address) + offset ) +#else +#error Prefetch not defined for this platform! +#endif +#else +#define PREFETCH360(x,y) +#endif + +template +inline T* AlignPointer(void* ptr) +{ +#if defined( __clang__ ) + uintp temp = (uintp)ptr; +#else + unsigned temp = ptr; +#endif + temp = ALIGN_VALUE(temp, sizeof(T)); + return (T*)temp; +} + +#ifdef _PS3 + +#define _VEC_CLEAR_SIGNMASK (__vector unsigned int) {0x7fffffff,0x7fffffff,0x7fffffff,0x7fffffff} +#define _VEC_SIGNMASK (__vector unsigned int) { 0x80000000, 0x80000000, 0x80000000, 0x80000000 } +#define _VEC_LSBMASK (__vector unsigned int) { 0xfffffffe, 0xfffffffe, 0xfffffffe, 0xfffffffe } +#define _VEC_CLEAR_WMASK (__vector unsigned int) {0xffffffff, 0xffffffff, 0xffffffff, 0} +#define _VEC_COMPONENT_MASK_0 (__vector unsigned int) {0xffffffff, 0, 0, 0} +#define _VEC_COMPONENT_MASK_1 (__vector unsigned int) {0, 0xffffffff, 0, 0} +#define _VEC_COMPONENT_MASK_2 (__vector unsigned int) {0, 0, 0xffffffff, 0} +#define _VEC_COMPONENT_MASK_3 (__vector unsigned int) {0, 0, 0, 0xffffffff} + +#define _VEC_SWIZZLE_WZYX (__vector unsigned char) { 0x0c,0x0d,0x0e,0x0f, 0x08,0x09,0x0a,0x0b, 0x04,0x05,0x06,0x07, 0x00,0x01,0x02,0x03 } +#define _VEC_SWIZZLE_ZWXY (__vector unsigned char) { 0x08,0x09,0x0a,0x0b, 0x0c,0x0d,0x0e,0x0f, 0x00,0x01,0x02,0x03, 0x04,0x05,0x06,0x07 } +#define _VEC_SWIZZLE_YXWZ (__vector unsigned char) { 0x04,0x05,0x06,0x07, 0x00,0x01,0x02,0x03, 0x0c,0x0d,0x0e,0x0f, 0x08,0x09,0x0a,0x0b } + +#define _VEC_ZERO (__vector unsigned int) {0,0,0,0} + +#define _VEC_FLTMAX (__vector float) {FLT_MAX,FLT_MAX,FLT_MAX,FLT_MAX} +#define _VEC_FLTMIN (__vector float) {FLT_MIN,FLT_MIN,FLT_MIN,FLT_MIN} + +#define _VEC_ORIGIN (__vector unsigned int) { 0x00000000, 0x00000000, 0x00000000, 0xffffffff } + +#endif + +#if USE_STDC_FOR_SIMD + +FORCEINLINE float SubFloat(const fltx4& a, int idx) +{ + return a.m128_f32[idx]; +} + +FORCEINLINE float& SubFloat(fltx4& a, int idx) +{ + return a.m128_f32[idx]; +} + +FORCEINLINE uint32 SubInt(const fltx4& a, int idx) +{ + return a.m128_u32[idx]; +} + +FORCEINLINE uint32& SubInt(fltx4& a, int idx) +{ + return a.m128_u32[idx]; +} + +FORCEINLINE fltx4 LoadZeroSIMD(void) +{ + return Four_Zeros; +} + +FORCEINLINE fltx4 LoadOneSIMD(void) +{ + return Four_Ones; +} + +FORCEINLINE fltx4 SplatXSIMD(const fltx4& a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = SubFloat(a, 0); + SubFloat(retVal, 1) = SubFloat(a, 0); + SubFloat(retVal, 2) = SubFloat(a, 0); + SubFloat(retVal, 3) = SubFloat(a, 0); + return retVal; +} + +FORCEINLINE fltx4 SplatYSIMD(fltx4 a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = SubFloat(a, 1); + SubFloat(retVal, 1) = SubFloat(a, 1); + SubFloat(retVal, 2) = SubFloat(a, 1); + SubFloat(retVal, 3) = SubFloat(a, 1); + return retVal; +} + +FORCEINLINE fltx4 SplatZSIMD(fltx4 a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = SubFloat(a, 2); + SubFloat(retVal, 1) = SubFloat(a, 2); + SubFloat(retVal, 2) = SubFloat(a, 2); + SubFloat(retVal, 3) = SubFloat(a, 2); + return retVal; +} + +FORCEINLINE fltx4 SplatWSIMD(fltx4 a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = SubFloat(a, 3); + SubFloat(retVal, 1) = SubFloat(a, 3); + SubFloat(retVal, 2) = SubFloat(a, 3); + SubFloat(retVal, 3) = SubFloat(a, 3); + return retVal; +} + +FORCEINLINE fltx4 SetXSIMD(const fltx4& a, const fltx4& x) +{ + fltx4 result = a; + SubFloat(result, 0) = SubFloat(x, 0); + return result; +} + +FORCEINLINE fltx4 SetYSIMD(const fltx4& a, const fltx4& y) +{ + fltx4 result = a; + SubFloat(result, 1) = SubFloat(y, 1); + return result; +} + +FORCEINLINE fltx4 SetZSIMD(const fltx4& a, const fltx4& z) +{ + fltx4 result = a; + SubFloat(result, 2) = SubFloat(z, 2); + return result; +} + +FORCEINLINE fltx4 SetWSIMD(const fltx4& a, const fltx4& w) +{ + fltx4 result = a; + SubFloat(result, 3) = SubFloat(w, 3); + return result; +} + +FORCEINLINE fltx4 SetComponentSIMD(const fltx4& a, int nComponent, float flValue) +{ + fltx4 result = a; + SubFloat(result, nComponent) = flValue; + return result; +} + + +FORCEINLINE fltx4 RotateLeft(const fltx4& a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = SubFloat(a, 1); + SubFloat(retVal, 1) = SubFloat(a, 2); + SubFloat(retVal, 2) = SubFloat(a, 3); + SubFloat(retVal, 3) = SubFloat(a, 0); + return retVal; +} + +FORCEINLINE fltx4 RotateLeft2(const fltx4& a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = SubFloat(a, 2); + SubFloat(retVal, 1) = SubFloat(a, 3); + SubFloat(retVal, 2) = SubFloat(a, 0); + SubFloat(retVal, 3) = SubFloat(a, 1); + return retVal; +} + +#define BINOP(op) \ + fltx4 retVal; \ + SubFloat( retVal, 0 ) = ( SubFloat( a, 0 ) op SubFloat( b, 0 ) ); \ + SubFloat( retVal, 1 ) = ( SubFloat( a, 1 ) op SubFloat( b, 1 ) ); \ + SubFloat( retVal, 2 ) = ( SubFloat( a, 2 ) op SubFloat( b, 2 ) ); \ + SubFloat( retVal, 3 ) = ( SubFloat( a, 3 ) op SubFloat( b, 3 ) ); \ + return retVal; + +#define IBINOP(op) \ + fltx4 retVal; \ + SubInt( retVal, 0 ) = ( SubInt( a, 0 ) op SubInt ( b, 0 ) ); \ + SubInt( retVal, 1 ) = ( SubInt( a, 1 ) op SubInt ( b, 1 ) ); \ + SubInt( retVal, 2 ) = ( SubInt( a, 2 ) op SubInt ( b, 2 ) ); \ + SubInt( retVal, 3 ) = ( SubInt( a, 3 ) op SubInt ( b, 3 ) ); \ + return retVal; + +FORCEINLINE fltx4 AddSIMD(const fltx4& a, const fltx4& b) +{ + BINOP(+); +} + +FORCEINLINE fltx4 SubSIMD(const fltx4& a, const fltx4& b) +{ + BINOP(-); +}; + +FORCEINLINE fltx4 MulSIMD(const fltx4& a, const fltx4& b) +{ + BINOP(*); +} + +FORCEINLINE fltx4 DivSIMD(const fltx4& a, const fltx4& b) +{ + BINOP(/ ); +} + +FORCEINLINE fltx4 DivEstSIMD(const fltx4& a, const fltx4& b) +{ + BINOP(/ ); +} + +FORCEINLINE fltx4 MaddSIMD(const fltx4& a, const fltx4& b, const fltx4& c) +{ + return AddSIMD(MulSIMD(a, b), c); +} + +FORCEINLINE fltx4 MsubSIMD(const fltx4& a, const fltx4& b, const fltx4& c) +{ + return SubSIMD(c, MulSIMD(a, b)); +}; + + +FORCEINLINE fltx4 SinSIMD(const fltx4& radians) +{ + fltx4 result; + SubFloat(result, 0) = sin(SubFloat(radians, 0)); + SubFloat(result, 1) = sin(SubFloat(radians, 1)); + SubFloat(result, 2) = sin(SubFloat(radians, 2)); + SubFloat(result, 3) = sin(SubFloat(radians, 3)); + return result; +} + +FORCEINLINE void SinCos3SIMD(fltx4& sine, fltx4& cosine, const fltx4& radians) +{ + SinCos(SubFloat(radians, 0), &SubFloat(sine, 0), &SubFloat(cosine, 0)); + SinCos(SubFloat(radians, 1), &SubFloat(sine, 1), &SubFloat(cosine, 1)); + SinCos(SubFloat(radians, 2), &SubFloat(sine, 2), &SubFloat(cosine, 2)); +} + +FORCEINLINE void SinCosSIMD(fltx4& sine, fltx4& cosine, const fltx4& radians) +{ + SinCos(SubFloat(radians, 0), &SubFloat(sine, 0), &SubFloat(cosine, 0)); + SinCos(SubFloat(radians, 1), &SubFloat(sine, 1), &SubFloat(cosine, 1)); + SinCos(SubFloat(radians, 2), &SubFloat(sine, 2), &SubFloat(cosine, 2)); + SinCos(SubFloat(radians, 3), &SubFloat(sine, 3), &SubFloat(cosine, 3)); +} + +FORCEINLINE fltx4 ArcSinSIMD(const fltx4& sine) +{ + fltx4 result; + SubFloat(result, 0) = asin(SubFloat(sine, 0)); + SubFloat(result, 1) = asin(SubFloat(sine, 1)); + SubFloat(result, 2) = asin(SubFloat(sine, 2)); + SubFloat(result, 3) = asin(SubFloat(sine, 3)); + return result; +} + +FORCEINLINE fltx4 ArcCosSIMD(const fltx4& cs) +{ + fltx4 result; + SubFloat(result, 0) = acos(SubFloat(cs, 0)); + SubFloat(result, 1) = acos(SubFloat(cs, 1)); + SubFloat(result, 2) = acos(SubFloat(cs, 2)); + SubFloat(result, 3) = acos(SubFloat(cs, 3)); + return result; +} + +FORCEINLINE fltx4 ArcTan2SIMD(const fltx4& a, const fltx4& b) +{ + fltx4 result; + SubFloat(result, 0) = atan2(SubFloat(a, 0), SubFloat(b, 0)); + SubFloat(result, 1) = atan2(SubFloat(a, 1), SubFloat(b, 1)); + SubFloat(result, 2) = atan2(SubFloat(a, 2), SubFloat(b, 2)); + SubFloat(result, 3) = atan2(SubFloat(a, 3), SubFloat(b, 3)); + return result; +} + +FORCEINLINE fltx4 MaxSIMD(const fltx4& a, const fltx4& b) +{ + fltx4 retVal; + SubFloat(retVal, 0) = max(SubFloat(a, 0), SubFloat(b, 0)); + SubFloat(retVal, 1) = max(SubFloat(a, 1), SubFloat(b, 1)); + SubFloat(retVal, 2) = max(SubFloat(a, 2), SubFloat(b, 2)); + SubFloat(retVal, 3) = max(SubFloat(a, 3), SubFloat(b, 3)); + return retVal; +} + +FORCEINLINE fltx4 MinSIMD(const fltx4& a, const fltx4& b) +{ + fltx4 retVal; + SubFloat(retVal, 0) = min(SubFloat(a, 0), SubFloat(b, 0)); + SubFloat(retVal, 1) = min(SubFloat(a, 1), SubFloat(b, 1)); + SubFloat(retVal, 2) = min(SubFloat(a, 2), SubFloat(b, 2)); + SubFloat(retVal, 3) = min(SubFloat(a, 3), SubFloat(b, 3)); + return retVal; +} + +FORCEINLINE fltx4 AndSIMD(const fltx4& a, const fltx4& b) +{ + IBINOP(&); +} + +FORCEINLINE fltx4 AndNotSIMD(const fltx4& a, const fltx4& b) +{ + fltx4 retVal; + SubInt(retVal, 0) = ~SubInt(a, 0) & SubInt(b, 0); + SubInt(retVal, 1) = ~SubInt(a, 1) & SubInt(b, 1); + SubInt(retVal, 2) = ~SubInt(a, 2) & SubInt(b, 2); + SubInt(retVal, 3) = ~SubInt(a, 3) & SubInt(b, 3); + return retVal; +} + +FORCEINLINE fltx4 XorSIMD(const fltx4& a, const fltx4& b) +{ + IBINOP(^); +} + +FORCEINLINE fltx4 OrSIMD(const fltx4& a, const fltx4& b) +{ + IBINOP(| ); +} + +FORCEINLINE fltx4 NegSIMD(const fltx4& a) +{ + fltx4 retval; + SubFloat(retval, 0) = -SubFloat(a, 0); + SubFloat(retval, 1) = -SubFloat(a, 1); + SubFloat(retval, 2) = -SubFloat(a, 2); + SubFloat(retval, 3) = -SubFloat(a, 3); + + return retval; +} + +FORCEINLINE bool IsAllZeros(const fltx4& a) +{ + return (SubFloat(a, 0) == 0.0) && + (SubFloat(a, 1) == 0.0) && + (SubFloat(a, 2) == 0.0) && + (SubFloat(a, 3) == 0.0); +} + + +FORCEINLINE bool IsAllGreaterThan(const fltx4& a, const fltx4& b) +{ + return SubFloat(a, 0) > SubFloat(b, 0) && + SubFloat(a, 1) > SubFloat(b, 1) && + SubFloat(a, 2) > SubFloat(b, 2) && + SubFloat(a, 3) > SubFloat(b, 3); +} + +FORCEINLINE bool IsAllGreaterThanOrEq(const fltx4& a, const fltx4& b) +{ + return SubFloat(a, 0) >= SubFloat(b, 0) && + SubFloat(a, 1) >= SubFloat(b, 1) && + SubFloat(a, 2) >= SubFloat(b, 2) && + SubFloat(a, 3) >= SubFloat(b, 3); +} + +FORCEINLINE bool IsAllEqual(const fltx4& a, const fltx4& b) +{ + return SubFloat(a, 0) == SubFloat(b, 0) && + SubFloat(a, 1) == SubFloat(b, 1) && + SubFloat(a, 2) == SubFloat(b, 2) && + SubFloat(a, 3) == SubFloat(b, 3); +} + +FORCEINLINE bool IsAnyEqual(const fltx4& a, const fltx4& b) +{ + return SubFloat(a, 0) == SubFloat(b, 0) || + SubFloat(a, 1) == SubFloat(b, 1) || + SubFloat(a, 2) == SubFloat(b, 2) || + SubFloat(a, 3) == SubFloat(b, 3); +} + +FORCEINLINE int TestSignSIMD(const fltx4& a) +{ + int nRet = 0; + + nRet |= (SubInt(a, 0) & 0x80000000) >> 31; + nRet |= (SubInt(a, 1) & 0x80000000) >> 30; + nRet |= (SubInt(a, 2) & 0x80000000) >> 29; + nRet |= (SubInt(a, 3) & 0x80000000) >> 28; + + return nRet; +} + +FORCEINLINE bool IsAnyNegative(const fltx4& a) +{ + return (0 != TestSignSIMD(a)); +} + +FORCEINLINE bool IsAnyTrue(const fltx4& a) +{ + return (0 != TestSignSIMD(a)); +} + +FORCEINLINE fltx4 CmpEqSIMD(const fltx4& a, const fltx4& b) +{ + fltx4 retVal; + SubInt(retVal, 0) = (SubFloat(a, 0) == SubFloat(b, 0)) ? ~0 : 0; + SubInt(retVal, 1) = (SubFloat(a, 1) == SubFloat(b, 1)) ? ~0 : 0; + SubInt(retVal, 2) = (SubFloat(a, 2) == SubFloat(b, 2)) ? ~0 : 0; + SubInt(retVal, 3) = (SubFloat(a, 3) == SubFloat(b, 3)) ? ~0 : 0; + return retVal; +} + +FORCEINLINE fltx4 CmpGtSIMD(const fltx4& a, const fltx4& b) +{ + fltx4 retVal; + SubInt(retVal, 0) = (SubFloat(a, 0) > SubFloat(b, 0)) ? ~0 : 0; + SubInt(retVal, 1) = (SubFloat(a, 1) > SubFloat(b, 1)) ? ~0 : 0; + SubInt(retVal, 2) = (SubFloat(a, 2) > SubFloat(b, 2)) ? ~0 : 0; + SubInt(retVal, 3) = (SubFloat(a, 3) > SubFloat(b, 3)) ? ~0 : 0; + return retVal; +} + +FORCEINLINE fltx4 CmpGeSIMD(const fltx4& a, const fltx4& b) +{ + fltx4 retVal; + SubInt(retVal, 0) = (SubFloat(a, 0) >= SubFloat(b, 0)) ? ~0 : 0; + SubInt(retVal, 1) = (SubFloat(a, 1) >= SubFloat(b, 1)) ? ~0 : 0; + SubInt(retVal, 2) = (SubFloat(a, 2) >= SubFloat(b, 2)) ? ~0 : 0; + SubInt(retVal, 3) = (SubFloat(a, 3) >= SubFloat(b, 3)) ? ~0 : 0; + return retVal; +} + +FORCEINLINE fltx4 CmpLtSIMD(const fltx4& a, const fltx4& b) +{ + fltx4 retVal; + SubInt(retVal, 0) = (SubFloat(a, 0) < SubFloat(b, 0)) ? ~0 : 0; + SubInt(retVal, 1) = (SubFloat(a, 1) < SubFloat(b, 1)) ? ~0 : 0; + SubInt(retVal, 2) = (SubFloat(a, 2) < SubFloat(b, 2)) ? ~0 : 0; + SubInt(retVal, 3) = (SubFloat(a, 3) < SubFloat(b, 3)) ? ~0 : 0; + return retVal; +} + +FORCEINLINE fltx4 CmpLeSIMD(const fltx4& a, const fltx4& b) +{ + fltx4 retVal; + SubInt(retVal, 0) = (SubFloat(a, 0) <= SubFloat(b, 0)) ? ~0 : 0; + SubInt(retVal, 1) = (SubFloat(a, 1) <= SubFloat(b, 1)) ? ~0 : 0; + SubInt(retVal, 2) = (SubFloat(a, 2) <= SubFloat(b, 2)) ? ~0 : 0; + SubInt(retVal, 3) = (SubFloat(a, 3) <= SubFloat(b, 3)) ? ~0 : 0; + return retVal; +} + +FORCEINLINE fltx4 CmpInBoundsSIMD(const fltx4& a, const fltx4& b) +{ + fltx4 retVal; + SubInt(retVal, 0) = (SubFloat(a, 0) <= SubFloat(b, 0) && SubFloat(a, 0) >= -SubFloat(b, 0)) ? ~0 : 0; + SubInt(retVal, 1) = (SubFloat(a, 1) <= SubFloat(b, 1) && SubFloat(a, 1) >= -SubFloat(b, 1)) ? ~0 : 0; + SubInt(retVal, 2) = (SubFloat(a, 2) <= SubFloat(b, 2) && SubFloat(a, 2) >= -SubFloat(b, 2)) ? ~0 : 0; + SubInt(retVal, 3) = (SubFloat(a, 3) <= SubFloat(b, 3) && SubFloat(a, 3) >= -SubFloat(b, 3)) ? ~0 : 0; + return retVal; +} + + +FORCEINLINE fltx4 MaskedAssign(const fltx4& ReplacementMask, const fltx4& NewValue, const fltx4& OldValue) +{ + return OrSIMD( + AndSIMD(ReplacementMask, NewValue), + AndNotSIMD(ReplacementMask, OldValue)); +} + +FORCEINLINE fltx4 ReplicateX4(float flValue) +{ + fltx4 retVal; + SubFloat(retVal, 0) = flValue; + SubFloat(retVal, 1) = flValue; + SubFloat(retVal, 2) = flValue; + SubFloat(retVal, 3) = flValue; + return retVal; +} + +FORCEINLINE fltx4 ReplicateIX4(int nValue) +{ + fltx4 retVal; + SubInt(retVal, 0) = nValue; + SubInt(retVal, 1) = nValue; + SubInt(retVal, 2) = nValue; + SubInt(retVal, 3) = nValue; + return retVal; + +} + +FORCEINLINE fltx4 CeilSIMD(const fltx4& a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = ceil(SubFloat(a, 0)); + SubFloat(retVal, 1) = ceil(SubFloat(a, 1)); + SubFloat(retVal, 2) = ceil(SubFloat(a, 2)); + SubFloat(retVal, 3) = ceil(SubFloat(a, 3)); + return retVal; + +} + +FORCEINLINE fltx4 FloorSIMD(const fltx4& a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = floor(SubFloat(a, 0)); + SubFloat(retVal, 1) = floor(SubFloat(a, 1)); + SubFloat(retVal, 2) = floor(SubFloat(a, 2)); + SubFloat(retVal, 3) = floor(SubFloat(a, 3)); + return retVal; + +} + +FORCEINLINE fltx4 SqrtEstSIMD(const fltx4& a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = sqrt(SubFloat(a, 0)); + SubFloat(retVal, 1) = sqrt(SubFloat(a, 1)); + SubFloat(retVal, 2) = sqrt(SubFloat(a, 2)); + SubFloat(retVal, 3) = sqrt(SubFloat(a, 3)); + return retVal; +} + +FORCEINLINE fltx4 SqrtSIMD(const fltx4& a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = sqrt(SubFloat(a, 0)); + SubFloat(retVal, 1) = sqrt(SubFloat(a, 1)); + SubFloat(retVal, 2) = sqrt(SubFloat(a, 2)); + SubFloat(retVal, 3) = sqrt(SubFloat(a, 3)); + return retVal; +} + +FORCEINLINE fltx4 ReciprocalSqrtEstSIMD(const fltx4& a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = 1.0 / sqrt(SubFloat(a, 0)); + SubFloat(retVal, 1) = 1.0 / sqrt(SubFloat(a, 1)); + SubFloat(retVal, 2) = 1.0 / sqrt(SubFloat(a, 2)); + SubFloat(retVal, 3) = 1.0 / sqrt(SubFloat(a, 3)); + return retVal; +} + +FORCEINLINE fltx4 ReciprocalSqrtEstSaturateSIMD(const fltx4& a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = 1.0 / sqrt(SubFloat(a, 0) != 0.0f ? SubFloat(a, 0) : FLT_EPSILON); + SubFloat(retVal, 1) = 1.0 / sqrt(SubFloat(a, 1) != 0.0f ? SubFloat(a, 1) : FLT_EPSILON); + SubFloat(retVal, 2) = 1.0 / sqrt(SubFloat(a, 2) != 0.0f ? SubFloat(a, 2) : FLT_EPSILON); + SubFloat(retVal, 3) = 1.0 / sqrt(SubFloat(a, 3) != 0.0f ? SubFloat(a, 3) : FLT_EPSILON); + return retVal; +} + +FORCEINLINE fltx4 ReciprocalSqrtSIMD(const fltx4& a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = 1.0 / sqrt(SubFloat(a, 0)); + SubFloat(retVal, 1) = 1.0 / sqrt(SubFloat(a, 1)); + SubFloat(retVal, 2) = 1.0 / sqrt(SubFloat(a, 2)); + SubFloat(retVal, 3) = 1.0 / sqrt(SubFloat(a, 3)); + return retVal; +} + +FORCEINLINE fltx4 ReciprocalEstSIMD(const fltx4& a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = 1.0 / SubFloat(a, 0); + SubFloat(retVal, 1) = 1.0 / SubFloat(a, 1); + SubFloat(retVal, 2) = 1.0 / SubFloat(a, 2); + SubFloat(retVal, 3) = 1.0 / SubFloat(a, 3); + return retVal; +} + +FORCEINLINE fltx4 ReciprocalSIMD(const fltx4& a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = 1.0 / SubFloat(a, 0); + SubFloat(retVal, 1) = 1.0 / SubFloat(a, 1); + SubFloat(retVal, 2) = 1.0 / SubFloat(a, 2); + SubFloat(retVal, 3) = 1.0 / SubFloat(a, 3); + return retVal; +} + +FORCEINLINE fltx4 ReciprocalEstSaturateSIMD(const fltx4& a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = 1.0 / (SubFloat(a, 0) == 0.0f ? FLT_EPSILON : SubFloat(a, 0)); + SubFloat(retVal, 1) = 1.0 / (SubFloat(a, 1) == 0.0f ? FLT_EPSILON : SubFloat(a, 1)); + SubFloat(retVal, 2) = 1.0 / (SubFloat(a, 2) == 0.0f ? FLT_EPSILON : SubFloat(a, 2)); + SubFloat(retVal, 3) = 1.0 / (SubFloat(a, 3) == 0.0f ? FLT_EPSILON : SubFloat(a, 3)); + return retVal; +} + +FORCEINLINE fltx4 ReciprocalSaturateSIMD(const fltx4& a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = 1.0 / (SubFloat(a, 0) == 0.0f ? FLT_EPSILON : SubFloat(a, 0)); + SubFloat(retVal, 1) = 1.0 / (SubFloat(a, 1) == 0.0f ? FLT_EPSILON : SubFloat(a, 1)); + SubFloat(retVal, 2) = 1.0 / (SubFloat(a, 2) == 0.0f ? FLT_EPSILON : SubFloat(a, 2)); + SubFloat(retVal, 3) = 1.0 / (SubFloat(a, 3) == 0.0f ? FLT_EPSILON : SubFloat(a, 3)); + return retVal; +} + +FORCEINLINE fltx4 ExpSIMD(const fltx4& toPower) +{ + fltx4 retVal; + SubFloat(retVal, 0) = powf(2, SubFloat(toPower, 0)); + SubFloat(retVal, 1) = powf(2, SubFloat(toPower, 1)); + SubFloat(retVal, 2) = powf(2, SubFloat(toPower, 2)); + SubFloat(retVal, 3) = powf(2, SubFloat(toPower, 3)); + + return retVal; +} + +FORCEINLINE fltx4 Dot3SIMD(const fltx4& a, const fltx4& b) +{ + float flDot = SubFloat(a, 0) * SubFloat(b, 0) + + SubFloat(a, 1) * SubFloat(b, 1) + + SubFloat(a, 2) * SubFloat(b, 2); + return ReplicateX4(flDot); +} + +FORCEINLINE fltx4 Dot4SIMD(const fltx4& a, const fltx4& b) +{ + float flDot = SubFloat(a, 0) * SubFloat(b, 0) + + SubFloat(a, 1) * SubFloat(b, 1) + + SubFloat(a, 2) * SubFloat(b, 2) + + SubFloat(a, 3) * SubFloat(b, 3); + return ReplicateX4(flDot); +} + +FORCEINLINE fltx4 ClampVectorSIMD(FLTX4 in, FLTX4 min, FLTX4 max) +{ + return MaxSIMD(min, MinSIMD(max, in)); +} + +FORCEINLINE fltx4 SetWToZeroSIMD(const fltx4& a) +{ + fltx4 retval; + retval = a; + SubFloat(retval, 0) = 0; + return retval; +} + +FORCEINLINE fltx4 LoadUnalignedSIMD(const void* pSIMD) +{ + return *(reinterpret_cast (pSIMD)); +} + +FORCEINLINE fltx4 LoadUnaligned3SIMD(const void* pSIMD) +{ + return *(reinterpret_cast (pSIMD)); +} + +FORCEINLINE fltx4 LoadUnalignedFloatSIMD(const float* pFlt) +{ + fltx4 retval; + SubFloat(retval, 0) = *pFlt; + return retval; +} + +FORCEINLINE fltx4 LoadAlignedSIMD(const void* pSIMD) +{ + return *(reinterpret_cast (pSIMD)); +} + +FORCEINLINE fltx4 LoadAlignedSIMD(const VectorAligned& pSIMD) +{ + fltx4 retval = LoadAlignedSIMD(pSIMD.Base()); + SubInt(retval, 3) = 0; + return retval; +} + + +FORCEINLINE fltx4 LoadGatherSIMD(const float& x, const float& y, const float& z, const float& w) +{ + fltx4 retval = { x, y, z, w }; + return retval; +} + +FORCEINLINE void StoreAlignedSIMD(float* pSIMD, const fltx4& a) +{ + *(reinterpret_cast (pSIMD)) = a; +} + +FORCEINLINE void StoreUnalignedSIMD(float* pSIMD, const fltx4& a) +{ + *(reinterpret_cast (pSIMD)) = a; +} + +FORCEINLINE void StoreUnalignedFloat(float* pSingleFloat, const fltx4& a) +{ + *pSingleFloat = SubFloat(a, 0); +} + +FORCEINLINE void StoreUnaligned3SIMD(float* pSIMD, const fltx4& a) +{ + *pSIMD = SubFloat(a, 0); + *(pSIMD + 1) = SubFloat(a, 1); + *(pSIMD + 2) = SubFloat(a, 2); +} + + +FORCEINLINE void StoreAligned3SIMD(VectorAligned* RESTRICT pSIMD, const fltx4& a) +{ + StoreAlignedSIMD(pSIMD->Base(), a); +} + +FORCEINLINE void StoreFourUnalignedVector3SIMD(fltx4 a, fltx4 b, fltx4 c, FLTX4 d, + Vector* const pDestination) +{ + StoreUnaligned3SIMD(pDestination->Base(), a); + StoreUnaligned3SIMD((pDestination + 1)->Base(), b); + StoreUnaligned3SIMD((pDestination + 2)->Base(), c); + StoreUnaligned3SIMD((pDestination + 3)->Base(), d); +} + +FORCEINLINE void StoreFourAlignedVector3SIMD(fltx4 a, fltx4 b, fltx4 c, FLTX4 d, + Vector* const pDestination) +{ + StoreUnaligned3SIMD(pDestination->Base(), a); + StoreUnaligned3SIMD((pDestination + 1)->Base(), b); + StoreUnaligned3SIMD((pDestination + 2)->Base(), c); + StoreUnaligned3SIMD((pDestination + 3)->Base(), d); +} + + +FORCEINLINE void TransposeSIMD(fltx4& x, fltx4& y, fltx4& z, fltx4& w) +{ +#define SWAP_FLOATS( _a_, _ia_, _b_, _ib_ ) { float tmp = SubFloat( _a_, _ia_ ); SubFloat( _a_, _ia_ ) = SubFloat( _b_, _ib_ ); SubFloat( _b_, _ib_ ) = tmp; } + SWAP_FLOATS(x, 1, y, 0); + SWAP_FLOATS(x, 2, z, 0); + SWAP_FLOATS(x, 3, w, 0); + SWAP_FLOATS(y, 2, z, 1); + SWAP_FLOATS(y, 3, w, 1); + SWAP_FLOATS(z, 3, w, 2); +} + +FORCEINLINE fltx4 FindLowestSIMD3(const fltx4& a) +{ + float lowest = min(min(SubFloat(a, 0), SubFloat(a, 1)), SubFloat(a, 2)); + return ReplicateX4(lowest); +} + +FORCEINLINE fltx4 FindHighestSIMD3(const fltx4& a) +{ + float highest = max(max(SubFloat(a, 0), SubFloat(a, 1)), SubFloat(a, 2)); + return ReplicateX4(highest); +} + +FORCEINLINE void ConvertStoreAsIntsSIMD(intx4* RESTRICT pDest, const fltx4& vSrc) +{ + (*pDest)[0] = SubFloat(vSrc, 0); + (*pDest)[1] = SubFloat(vSrc, 1); + (*pDest)[2] = SubFloat(vSrc, 2); + (*pDest)[3] = SubFloat(vSrc, 3); +} + +FORCEINLINE fltx4 IntSetImmediateSIMD(int nValue) +{ + fltx4 retval; + SubInt(retval, 0) = SubInt(retval, 1) = SubInt(retval, 2) = SubInt(retval, 3) = nValue; + return retval; +} + +FORCEINLINE i32x4 LoadAlignedIntSIMD(const void* RESTRICT pSIMD) +{ + return *(reinterpret_cast (pSIMD)); +} + +FORCEINLINE i32x4 LoadUnalignedIntSIMD(const void* RESTRICT pSIMD) +{ + return *(reinterpret_cast (pSIMD)); +} + +FORCEINLINE void StoreAlignedIntSIMD(int32* pSIMD, const fltx4& a) +{ + *(reinterpret_cast (pSIMD)) = a; +} + +FORCEINLINE void StoreAlignedIntSIMD(intx4& pSIMD, const fltx4& a) +{ + *(reinterpret_cast (pSIMD.Base())) = a; +} + +FORCEINLINE void StoreUnalignedIntSIMD(int32* pSIMD, const fltx4& a) +{ + *(reinterpret_cast (pSIMD)) = a; +} + +FORCEINLINE fltx4 LoadAndConvertUint16SIMD(const uint16* pInts) +{ + fltx4 retval; + SubFloat(retval, 0) = pInts[0]; + SubFloat(retval, 1) = pInts[1]; + SubFloat(retval, 2) = pInts[2]; + SubFloat(retval, 3) = pInts[3]; +} + + +FORCEINLINE fltx4 UnsignedIntConvertToFltSIMD(const u32x4& vSrcA) +{ + Assert(0); + fltx4 retval; + SubFloat(retval, 0) = ((float)SubInt(vSrcA, 0)); + SubFloat(retval, 1) = ((float)SubInt(vSrcA, 1)); + SubFloat(retval, 2) = ((float)SubInt(vSrcA, 2)); + SubFloat(retval, 3) = ((float)SubInt(vSrcA, 3)); + return retval; +} + + +#if 0 +FORCEINLINE fltx4 SignedIntConvertToFltSIMD(const i32x4& vSrcA) +{ + fltx4 retval; + SubFloat(retval, 0) = ((float)(reinterpret_cast(&vSrcA.m128_s32[0]))); + SubFloat(retval, 1) = ((float)(reinterpret_cast(&vSrcA.m128_s32[1]))); + SubFloat(retval, 2) = ((float)(reinterpret_cast(&vSrcA.m128_s32[2]))); + SubFloat(retval, 3) = ((float)(reinterpret_cast(&vSrcA.m128_s32[3]))); + return retval; +} + + +FORCEINLINE i32x4 IntShiftLeftWordSIMD(const i32x4& vSrcA, const i32x4& vSrcB) +{ + i32x4 retval; + SubInt(retval, 0) = SubInt(vSrcA, 0) << SubInt(vSrcB, 0); + SubInt(retval, 1) = SubInt(vSrcA, 1) << SubInt(vSrcB, 1); + SubInt(retval, 2) = SubInt(vSrcA, 2) << SubInt(vSrcB, 2); + SubInt(retval, 3) = SubInt(vSrcA, 3) << SubInt(vSrcB, 3); + + + return retval; +} + +#endif + +#elif ( defined( _PS3 ) ) +#define SN_IMPROVED_INTRINSICS ( (( __GNUC__ == 4 ) && ( __GNUC_MINOR__ == 1 ) && ( __GNUC_PATCHLEVEL__ == 1 )) ||\ + (defined(__SN_VER__) && (__SN_VER__ > 25002)) ) + +FORCEINLINE float FloatSIMD(fltx4& a, int idx) +{ +#if SN_IMPROVED_INTRINSICS + return vec_extract(a, idx); +#else + fltx4_union a_union; + vec_st(a, 0, &a_union.vmxf); + return a_union.m128_f32[idx]; +#endif +} + +FORCEINLINE unsigned int UIntSIMD(u32x4& a, int idx) +{ +#if SN_IMPROVED_INTRINSICS + return vec_extract(a, idx); +#else + fltx4_union a_union; + vec_st(a, 0, &a_union.vmxui); + return a_union.m128_u32[idx]; +#endif +} + +FORCEINLINE fltx4 AddSIMD(const fltx4& a, const fltx4& b) +{ + return vec_add(a, b); +} + +FORCEINLINE fltx4 SubSIMD(const fltx4& a, const fltx4& b) +{ + return vec_sub(a, b); +} + +FORCEINLINE fltx4 MulSIMD(const fltx4& a, const fltx4& b) +{ + return vec_madd(a, b, _VEC_ZEROF); +} + +FORCEINLINE fltx4 MaddSIMD(const fltx4& a, const fltx4& b, const fltx4& c) +{ + return vec_madd(a, b, c); +} + +FORCEINLINE fltx4 MsubSIMD(const fltx4& a, const fltx4& b, const fltx4& c) +{ + return vec_nmsub(a, b, c); +}; + +FORCEINLINE fltx4 Dot3SIMD(const fltx4& a, const fltx4& b) +{ + fltx4 result; + + result = vec_madd(a, b, _VEC_ZEROF); + result = vec_madd(vec_sld(a, a, 4), vec_sld(b, b, 4), result); + result = vec_madd(vec_sld(a, a, 8), vec_sld(b, b, 8), result); + + result = vec_splat(result, 0); + + return result; +} + +FORCEINLINE fltx4 Dot4SIMD(const fltx4& a, const fltx4& b) +{ + fltx4 result; + + result = vec_madd(a, b, _VEC_ZEROF); + result = vec_madd(vec_sld(a, a, 4), vec_sld(b, b, 4), result); + result = vec_add(vec_sld(result, result, 8), result); + + result = vec_splat(result, 0); + + return result; +} + +FORCEINLINE fltx4 SinSIMD(const fltx4& radians) +{ + return sinf4(radians); +} + +FORCEINLINE void SinCos3SIMD(fltx4& sine, fltx4& cosine, const fltx4& radians) +{ + sincosf4(radians, &sine, &cosine); +} + +FORCEINLINE void SinCosSIMD(fltx4& sine, fltx4& cosine, const fltx4& radians) +{ + sincosf4(radians, &sine, &cosine); +} + +FORCEINLINE fltx4 ArcCosSIMD(const fltx4& cs) +{ + return acosf4(cs); +} + +FORCEINLINE fltx4 ArcTan2SIMD(const fltx4& a, const fltx4& b) +{ + return atan2f4(a, b); +} + +FORCEINLINE fltx4 ArcSinSIMD(const fltx4& sine) +{ + return asinf4(sine); +} + +FORCEINLINE fltx4 MaxSIMD(const fltx4& a, const fltx4& b) +{ + return vec_max(a, b); +} +FORCEINLINE fltx4 MinSIMD(const fltx4& a, const fltx4& b) +{ + return vec_min(a, b); +} + +FORCEINLINE fltx4 AndSIMD(const fltx4& a, const fltx4& b) +{ + return vec_and(a, b); +} +FORCEINLINE fltx4 AndSIMD(const bi32x4& a, const fltx4& b) +{ + return vec_and((fltx4)a, b); +} +FORCEINLINE fltx4 AndSIMD(const fltx4& a, const bi32x4& b) +{ + return vec_and(a, (fltx4)b); +} +FORCEINLINE bi32x4 AndSIMD(const bi32x4& a, const bi32x4& b) +{ + return vec_and(a, b); +} + +#if 0 +FORCEINLINE fltx4 AndNotSIMD(const fltx4& a, const fltx4& b) +{ + return vec_andc(b, a); +} +FORCEINLINE fltx4 AndNotSIMD(const bi32x4& a, const fltx4& b) +{ + return vec_andc(b, (fltx4)a); +} +FORCEINLINE fltx4 AndNotSIMD(const fltx4& a, const bi32x4& b) +{ + return (fltx4)vec_andc(b, (bi32x4)a); +} +FORCEINLINE bi32x4 AndNotSIMD(const bi32x4& a, const bi32x4& b) +{ + return vec_andc(b, a); +} +#else +template< typename T, typename U > +FORCEINLINE T AndNotSIMD(const T& a, const U& b) +{ + return vec_andc(b, (T)a); +} + +FORCEINLINE fltx4 AndNotSIMD(const bi32x4& a, const fltx4& b) +{ + return vec_andc(b, (fltx4)a); +} +#endif + +FORCEINLINE fltx4 XorSIMD(const fltx4& a, const fltx4& b) +{ + return vec_xor(a, b); +} +FORCEINLINE fltx4 XorSIMD(const bi32x4& a, const fltx4& b) +{ + return vec_xor((fltx4)a, b); +} +FORCEINLINE fltx4 XorSIMD(const fltx4& a, const bi32x4& b) +{ + return vec_xor(a, (fltx4)b); +} +FORCEINLINE bi32x4 XorSIMD(const bi32x4& a, const bi32x4& b) +{ + return vec_xor(a, b); +} + +FORCEINLINE fltx4 OrSIMD(const fltx4& a, const fltx4& b) +{ + return vec_or(a, b); +} +FORCEINLINE fltx4 OrSIMD(const bi32x4& a, const fltx4& b) +{ + return vec_or((fltx4)a, b); +} +FORCEINLINE fltx4 OrSIMD(const fltx4& a, const bi32x4& b) +{ + return vec_or(a, (fltx4)b); +} +FORCEINLINE i32x4 OrSIMD(const i32x4& a, const i32x4& b) +{ + return vec_or(a, b); +} +FORCEINLINE u32x4 OrSIMD(const u32x4& a, const u32x4& b) +{ + return vec_or(a, b); +} + +#if !defined(__SPU__) +FORCEINLINE bi32x4 OrSIMD(const bi32x4& a, const bi32x4& b) +{ + return vec_or(a, b); +} +#endif + +FORCEINLINE fltx4 NegSIMD(const fltx4& a) +{ + return(SubSIMD(_VEC_ZEROF, a)); + +} + +FORCEINLINE bool IsAnyZeros(const fltx4& a) +{ + return vec_any_eq(a, _VEC_ZEROF); +} + +FORCEINLINE bool IsAnyZeros(const bi32x4& a) +{ + return vec_any_eq((u32x4)a, _VEC_ZERO); +} + +FORCEINLINE bool IsAllZeros(const bi32x4& a) +{ + return vec_all_eq((u32x4)a, _VEC_ZERO); +} + +FORCEINLINE bool IsAnyXYZZero(const fltx4& a) +{ +#if SN_IMPROVED_INTRINSICS + + fltx4 b = vec_insert(1.0f, a, 3); + + return vec_any_eq(b, _VEC_ZEROF); +#else + fltx4 b = vec_perm(a, _VEC_ONEF, _VEC_PERMUTE_XYZ0W1); + return vec_any_eq(b, _VEC_ZEROF); +#endif +} + +FORCEINLINE bool IsAllGreaterThan(const fltx4& a, const fltx4& b) +{ + return vec_all_gt(a, b); +} + +FORCEINLINE bool IsAllGreaterThanOrEq(const fltx4& a, const fltx4& b) +{ + return vec_all_ge(a, b); +} + +FORCEINLINE bool IsAllEqual(const fltx4& a, const fltx4& b) +{ + return vec_all_eq(a, b); +} + + +FORCEINLINE int TestSignSIMD(const fltx4& a) +{ + int nRet = 0; + + fltx4_union a_union; + vec_st(a, 0, &a_union.vmxf); + + nRet |= (a_union.m128_u32[0] & 0x80000000) >> 31; + nRet |= (a_union.m128_u32[1] & 0x80000000) >> 30; + nRet |= (a_union.m128_u32[2] & 0x80000000) >> 29; + nRet |= (a_union.m128_u32[3] & 0x80000000) >> 28; + + return nRet; +} +FORCEINLINE int TestSignSIMD(const bi32x4& a) +{ + int nRet = 0; + + fltx4_union a_union; + vec_st(a, 0, &a_union.vmxbi); + + nRet |= (a_union.m128_u32[0] & 0x80000000) >> 31; + nRet |= (a_union.m128_u32[1] & 0x80000000) >> 30; + nRet |= (a_union.m128_u32[2] & 0x80000000) >> 29; + nRet |= (a_union.m128_u32[3] & 0x80000000) >> 28; + + return nRet; +} + +FORCEINLINE bool IsAnyNegative(const bi32x4& a) +{ + return (0 != TestSignSIMD(a)); +} + +FORCEINLINE fltx4 SetWToZeroSIMD(const fltx4& a) +{ + return (fltx4)vec_and((u32x4)a, _VEC_CLEAR_WMASK); +} +FORCEINLINE bi32x4 SetWToZeroSIMD(const bi32x4& a) +{ + return (bi32x4)vec_and((u32x4)a, _VEC_CLEAR_WMASK); +} + +FORCEINLINE bool IsAnyNegative(const fltx4& a) +{ + return vec_any_lt(a, _VEC_ZEROF); +} + +FORCEINLINE bool IsAnyTrue(const fltx4& a) +{ + return vec_any_ne(a, _VEC_ZEROF); +} + +#ifdef DIFFERENT_NATIVE_VECTOR_TYPES + +FORCEINLINE bool IsAnyTrue(const bi32x4& a) +{ + return vec_any_ne((vector unsigned int) a, _VEC_0L); +} + +#endif + +FORCEINLINE bi32x4 CmpEqSIMD(const fltx4& a, const fltx4& b) +{ + return (bi32x4)vec_cmpeq(a, b); +} +FORCEINLINE bi32x4 CmpEqSIMD(const i32x4& a, const i32x4& b) +{ + return (bi32x4)vec_cmpeq(a, b); +} +FORCEINLINE bi32x4 CmpEqSIMD(const u32x4& a, const u32x4& b) +{ + return (bi32x4)vec_cmpeq(a, b); +} + +FORCEINLINE bi32x4 CmpGtSIMD(const fltx4& a, const fltx4& b) +{ + return (bi32x4)vec_cmpgt(a, b); +} +FORCEINLINE bi32x4 CmpGtSIMD(const i32x4& a, const i32x4& b) +{ + return (bi32x4)vec_cmpgt(a, b); +} +FORCEINLINE bi32x4 CmpGtSIMD(const u32x4& a, const u32x4& b) +{ + return (bi32x4)vec_cmpgt(a, b); +} + +FORCEINLINE bi32x4 CmpGeSIMD(const fltx4& a, const fltx4& b) +{ + return (bi32x4)vec_cmpge(a, b); +} + + +FORCEINLINE bi32x4 CmpLtSIMD(const fltx4& a, const fltx4& b) +{ + return (bi32x4)vec_cmplt(a, b); +} + +FORCEINLINE bi32x4 CmpLeSIMD(const fltx4& a, const fltx4& b) +{ + return (bi32x4)vec_cmple(a, b); +} + + + +FORCEINLINE bi32x4 CmpInBoundsSIMD(const fltx4& a, const fltx4& b) +{ + i32x4 control; + control = vec_cmpb(a, b); + return (bi32x4)vec_cmpeq((u32x4)control, _VEC_ZERO); +} + +FORCEINLINE int CmpAnyLeSIMD(const fltx4& a, const fltx4& b) +{ + return vec_any_le(a, b); +} + +FORCEINLINE int CmpAnyGeSIMD(const fltx4& a, const fltx4& b) +{ + return vec_any_ge(a, b); +} + +FORCEINLINE int CmpAnyLtSIMD(const fltx4& a, const fltx4& b) +{ + return vec_any_lt(a, b); +} +FORCEINLINE int CmpAnyLtSIMD(const bi32x4& a, const i32x4& b) +{ + return vec_any_lt((i32x4)a, b); +} + +FORCEINLINE int CmpAnyGtSIMD(const fltx4& a, const fltx4& b) +{ + return vec_any_gt(a, b); +} + +FORCEINLINE int CmpAnyNeSIMD(const fltx4& a, const fltx4& b) +{ + return vec_any_ne(a, b); +} +FORCEINLINE int CmpAnyNeSIMD(const bi32x4& a, const bi32x4& b) +{ + return vec_any_ne(a, b); +} +FORCEINLINE int CmpAnyNeSIMD(const bi32x4& a, const i32x4& b) +{ + return vec_any_ne(a, (bi32x4)b); +} + +FORCEINLINE int CmpAllLeSIMD(const fltx4& a, const fltx4& b) +{ + return vec_all_le(a, b); +} + +FORCEINLINE fltx4 MaskedAssign(const bi32x4& ReplacementMask, const fltx4& NewValue, const fltx4& OldValue) +{ + return vec_sel(OldValue, NewValue, ReplacementMask); +} + +FORCEINLINE fltx4 MaskedAssign(const fltx4& ReplacementMask, const fltx4& NewValue, const fltx4& OldValue) +{ + return vec_sel(OldValue, NewValue, (const bi32x4)ReplacementMask); +} + +FORCEINLINE vector signed short MaskedAssign(const vector unsigned short& ReplacementMask, const vector signed short& NewValue, const vector signed short& OldValue) +{ + return vec_sel(OldValue, NewValue, ReplacementMask); +} + +FORCEINLINE fltx4 ReplicateX4(float flValue) +{ +#if SN_IMPROVED_INTRINSICS + return vec_splats(flValue); +#else + float* pValue = &flValue; + Assert(pValue); + Assert(((unsigned int)pValue & 3) == 0); + + fltx4 result; + + result = vec_ld(0, pValue); + result = vec_splat(vec_perm(result, result, vec_lvsl(0, pValue)), 0); + + return result; +#endif +} + +FORCEINLINE fltx4 ReplicateX4(const float* pValue) +{ +#if SN_IMPROVED_INTRINSICS + return vec_splats(*pValue); +#else + Assert(pValue); + fltx4 result; + + result = vec_ld(0, pValue); + result = vec_splat(vec_perm(result, result, vec_lvsl(0, pValue)), 0); + + return result; +#endif +} + +FORCEINLINE i32x4 ReplicateIX4(int nValue) +{ +#if SN_IMPROVED_INTRINSICS + return vec_splats(nValue); +#else + int* pValue = &nValue; + Assert(pValue); + Assert(((unsigned int)pValue & 3) == 0); + i32x4 result; + + result = vec_ld(0, pValue); + result = vec_splat(vec_perm(result, result, vec_lvsl(0, pValue)), 0); + + return result; +#endif +} + +FORCEINLINE fltx4 SqrtSIMD(const fltx4& a) +{ + return sqrtf4(a); +} + +FORCEINLINE fltx4 SqrtEstSIMD(const fltx4& a) +{ +#if defined( _PS3 ) && !defined( SPU ) + fltx4 vRecipSquareRoot = vec_rsqrte(a); + i32x4 vOne = vec_splat_s32(1); + i32x4 vAllOnes = vec_splat_s32(-1); + i32x4 vShiftLeft24 = vec_splat_s32(-8); + fltx4 vZero = (fltx4)vec_splat_s32(0); + u32x4 vInputShifted = vec_sl((u32x4)a, (u32x4)vOne); + u32x4 vInfinityShifted = vec_sl((u32x4)vAllOnes, (u32x4)vShiftLeft24); + bi32x4 vEqualsZero = vec_vcmpeqfp(a, vZero); + bi32x4 vEqualsInfinity = vec_vcmpequw(vInputShifted, vInfinityShifted); + fltx4 vSquareRoot = vec_madd(a, vRecipSquareRoot, _VEC_ZEROF); + bi32x4 vResultMask = vec_vcmpequw((u32x4)vEqualsInfinity, (u32x4)vEqualsZero); + fltx4 vCorrectedSquareRoot = vec_sel(a, vSquareRoot, vResultMask); + + return vCorrectedSquareRoot; +#else + return SqrtSIMD(a); +#endif +} + +FORCEINLINE fltx4 ReciprocalSqrtEstSIMD(const fltx4& a) +{ + return vec_rsqrte(a); +} + +FORCEINLINE fltx4 ReciprocalSqrtSIMD(const fltx4& a) +{ + fltx4 result; + vmathV4RsqrtPerElem((VmathVector4*)&result, (const VmathVector4*)&a); + + return result; +} + +FORCEINLINE fltx4 ReciprocalEstSIMD(const fltx4& a) +{ + return vec_re(a); +} + +FORCEINLINE fltx4 ReciprocalEstSaturateSIMD(const fltx4& a) +{ + bi32x4 zero_mask = CmpEqSIMD(a, Four_Zeros); + fltx4 ret = OrSIMD(a, AndSIMD(Four_Epsilons, zero_mask)); + ret = ReciprocalEstSIMD(ret); + return ret; +} + + +FORCEINLINE fltx4 ReciprocalSIMD(const fltx4& a) +{ + fltx4 result; + vmathV4RecipPerElem((VmathVector4*)&result, (const VmathVector4*)&a); + + return result; +} + +FORCEINLINE fltx4 DivSIMD(const fltx4& a, const fltx4& b) +{ + return MulSIMD(ReciprocalSIMD(b), a); +} + +FORCEINLINE fltx4 DivEstSIMD(const fltx4& a, const fltx4& b) +{ + return MulSIMD(ReciprocalEstSIMD(b), a); +} + +FORCEINLINE fltx4 ReciprocalSaturateSIMD(const fltx4& a) +{ + bi32x4 zero_mask = CmpEqSIMD(a, _VEC_ZEROF); + fltx4 a_safe = OrSIMD(a, AndSIMD(_VEC_EPSILONF, zero_mask)); + return ReciprocalSIMD(a_safe); + +} + + +FORCEINLINE fltx4 ExpSIMD(const fltx4& toPower) +{ + return exp2f4(toPower); +} + +FORCEINLINE fltx4 Exp2EstSIMD(const fltx4& f) +{ + return exp2f4fast(f); +} + + +FORCEINLINE fltx4 ClampVectorSIMD(FLTX4 in, FLTX4 min, FLTX4 max) +{ + fltx4 result = vec_max(min, in); + return vec_min(max, result); +} + + +FORCEINLINE fltx4 LoadUnalignedSIMD(const void* pSIMD) +{ +#if SN_IMPROVED_INTRINSICS + + fltx4 v0, v1; + + Assert(pSIMD); + + + v0 = (fltx4)vec_lvlx(0, (float*)pSIMD); + v1 = (fltx4)vec_lvrx(16, (float*)pSIMD); + return vec_or(v0, v1); + +#else + + fltx4 v0, v1; + vector unsigned char permMask; + + Assert(pSIMD); + + v0 = vec_ld(0, pSIMD); + permMask = vec_lvsl(0, pSIMD); + v1 = vec_ld(15, pSIMD); + + return vec_perm(v0, v1, permMask); + +#endif +} + +FORCEINLINE fltx4 LoadUnsignedByte4SIMD(unsigned char* pBytes) +{ + +#if SN_IMPROVED_INTRINSICS + + __vector unsigned char res_uc; + __vector unsigned short res_us; + + __vector unsigned char vZero8 = (__vector unsigned char)vec_splat_u8(0); + __vector unsigned short vZero16 = (__vector unsigned short)vec_splat_u16(0); + + res_uc = (__vector unsigned char)vec_lvlx(0, pBytes); + res_uc = vec_mergeh(vZero8, res_uc); + res_us = vec_mergeh(vZero16, (__vector unsigned short)res_uc); + return vec_ctf((__vector unsigned int)res_us, 0); + +#else + + vector unsigned char v0, v1; + vector bool char res_uc; + vector unsigned char permMask; + vector bool short res_us; + + vector bool char vZero8 = (vector bool char)vec_splat_u8(0); + vector bool short vZero16 = (vector bool short)vec_splat_u16(0); + + v0 = vec_ld(0, pBytes); + permMask = vec_lvsl(0, pBytes); + v1 = vec_ld(3, pBytes); + res_uc = (vector bool char)vec_perm(v0, v1, permMask); + res_uc = vec_mergeh(vZero8, res_uc); + res_us = vec_mergeh(vZero16, (vector bool short)res_uc); + return vec_ctf((vector unsigned int)res_us, 0); + +#endif + +} + +FORCEINLINE fltx4 LoadSignedByte4SIMD(signed char* pBytes) +{ + +#if SN_IMPROVED_INTRINSICS + + vector signed char res_uc; + vector signed short res_us; + vector signed int res_ui; + + res_uc = (vector signed char)vec_lvlx(0, pBytes); + res_us = vec_unpackh(res_uc); + res_ui = vec_unpackh(res_us); + return vec_ctf(res_ui, 0); + +#else + + vector signed char v0, v1, res_uc; + vector unsigned char permMask; + vector signed short res_us; + vector signed int res_ui; + + v0 = vec_ld(0, pBytes); + permMask = vec_lvsl(0, pBytes); + v1 = vec_ld(3, pBytes); + res_uc = vec_perm(v0, v1, permMask); + res_us = vec_unpackh(res_uc); + res_ui = vec_unpackh(res_us); + return vec_ctf(res_ui, 0); + +#endif + +} + + +FORCEINLINE fltx4 LoadUnaligned3SIMD(const void* pSIMD) +{ + Assert(pSIMD); + + fltx4 v0 = vec_ld(0, (float*)(pSIMD)); + vector unsigned char permMask = vec_lvsl(0, (float*)(pSIMD)); + fltx4 v1 = vec_ld(11, (float*)(pSIMD)); + + return vec_perm(v0, v1, permMask); +} + + +FORCEINLINE fltx4 LoadUnalignedFloatSIMD(const float* pFlt) +{ + fltx4 v0 = vec_lde(0, const_cast(pFlt)); + vector unsigned char permMask = vec_lvsl(0, const_cast(pFlt)); + return vec_perm(v0, v0, permMask); +} + + +FORCEINLINE fltx4 LoadAlignedSIMD(const void* pSIMD) +{ + return vec_ld(0, (float*)pSIMD); +} + +#ifndef SPU +FORCEINLINE fltx4 LoadAlignedSIMD(const VectorAligned& pSIMD) +{ + fltx4 out; + out = vec_ld(0, pSIMD.Base()); + + return (fltx4)vec_and((u32x4)out, _VEC_CLEAR_WMASK); +} + +FORCEINLINE fltx4 LoadAlignedSIMD(const VectorAligned* RESTRICT pSIMD) +{ + fltx4 out; + out = vec_ld(0, pSIMD->Base()); + + return (fltx4)vec_and((u32x4)out, _VEC_CLEAR_WMASK); +} + + +FORCEINLINE void StoreAligned3SIMD(VectorAligned* RESTRICT pSIMD, const fltx4& a) +{ + vec_st(a, 0, pSIMD->Base()); +} +#endif + +FORCEINLINE void StoreAlignedSIMD(float* pSIMD, const fltx4& a) +{ + vec_st(a, 0, pSIMD); +} + +FORCEINLINE void StoreUnalignedSIMD(float* pSIMD, const fltx4& a) +{ +#if ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ == 1 ) && ( __GNUC_PATCHLEVEL__ == 1 ) + vec_stvlx(a, 0, pSIMD); + vec_stvrx(a, 16, pSIMD); +#else + fltx4_union a_union; + vec_st(a, 0, &a_union.vmxf); + pSIMD[0] = a_union.m128_f32[0]; + pSIMD[1] = a_union.m128_f32[1]; + pSIMD[2] = a_union.m128_f32[2]; + pSIMD[3] = a_union.m128_f32[3]; +#endif + +} + +FORCEINLINE void StoreUnaligned3SIMD(float* pSIMD, const fltx4& a) +{ + fltx4_union a_union; + vec_st(a, 0, &a_union.vmxf); + pSIMD[0] = a_union.m128_f32[0]; + pSIMD[1] = a_union.m128_f32[1]; + pSIMD[2] = a_union.m128_f32[2]; +}; + + + +#ifndef SPU + +FORCEINLINE fltx4 Compress4SIMD(fltx4 const a, fltx4 const& b, fltx4 const& c, fltx4 const& d); +FORCEINLINE fltx4 LoadGatherSIMD(const float& x, const float& y, const float& z, const float& w) +{ +#if USING_POINTLESSLY_SLOW_SONY_CODE + return vmathV4MakeFromElems_V(x, y, z, w).vec128; +#else + fltx4 vx = vec_lvlx(0, &x); + fltx4 vy = vec_lvlx(0, &y); + fltx4 vz = vec_lvlx(0, &z); + fltx4 vw = vec_lvlx(0, &w); + return Compress4SIMD(vx, vy, vz, vw); +#endif +} + + +FORCEINLINE void StoreFourUnalignedVector3SIMD(fltx4 a, fltx4 b, fltx4 c, FLTX4 d, + Vector* const pDestination) +{ + StoreUnaligned3SIMD(pDestination->Base(), a); + StoreUnaligned3SIMD((pDestination + 1)->Base(), b); + StoreUnaligned3SIMD((pDestination + 2)->Base(), c); + StoreUnaligned3SIMD((pDestination + 3)->Base(), d); +} + +FORCEINLINE void StoreFourAlignedVector3SIMD(fltx4 a, fltx4 b, fltx4 c, FLTX4 d, + Vector* const pDestination) +{ + StoreUnaligned3SIMD(pDestination->Base(), a); + StoreUnaligned3SIMD((pDestination + 1)->Base(), b); + StoreUnaligned3SIMD((pDestination + 2)->Base(), c); + StoreUnaligned3SIMD((pDestination + 3)->Base(), d); +} +#endif + +FORCEINLINE void ConvertStoreAsIntsSIMD(intx4* RESTRICT pDest, const fltx4& vSrc) +{ + i32x4 asInt = vec_cts(vSrc, 0); + vec_st(asInt, 0, pDest->Base()); +} + +FORCEINLINE void TransposeSIMD(fltx4& x, fltx4& y, fltx4& z, fltx4& w) +{ + fltx4 p0, p1, p2, p3; + + p0 = vec_mergeh(x, z); + p1 = vec_mergeh(y, w); + p2 = vec_mergel(x, z); + p3 = vec_mergel(y, w); + + x = vec_mergeh(p0, p1); + y = vec_mergel(p0, p1); + z = vec_mergeh(p2, p3); + w = vec_mergel(p2, p3); +} + +FORCEINLINE fltx4 LoadZeroSIMD(void) +{ + return _VEC_ZEROF; +} +FORCEINLINE i32x4 LoadZeroISIMD(void) +{ + return vec_splat_s32(0); +} + + +FORCEINLINE fltx4 LoadOneSIMD(void) +{ + return _VEC_ONEF; +} +FORCEINLINE i32x4 LoadOneISIMD(void) +{ + return vec_splat_s32(1); +} + +FORCEINLINE fltx4 SplatXSIMD(fltx4 a) +{ + return vec_splat(a, 0); +} +FORCEINLINE fltx4 SplatYSIMD(fltx4 a) +{ + return vec_splat(a, 1); +} +FORCEINLINE fltx4 SplatZSIMD(fltx4 a) +{ + return vec_splat(a, 2); +} +FORCEINLINE fltx4 SplatWSIMD(fltx4 a) +{ + return vec_splat(a, 3); +} + +FORCEINLINE bi32x4 SplatXSIMD(bi32x4 a) +{ + return vec_splat(a, 0); +} +FORCEINLINE bi32x4 SplatYSIMD(bi32x4 a) +{ + return vec_splat(a, 1); +} +FORCEINLINE bi32x4 SplatZSIMD(bi32x4 a) +{ + return vec_splat(a, 2); +} +FORCEINLINE bi32x4 SplatWSIMD(bi32x4 a) +{ + return vec_splat(a, 3); +} + +FORCEINLINE fltx4 SetXSIMD(const fltx4& a, const fltx4& x) +{ + return vec_sel(a, x, _VEC_COMPONENT_MASK_0); +} + +FORCEINLINE fltx4 SetYSIMD(const fltx4& a, const fltx4& y) +{ + return vec_sel(a, y, _VEC_COMPONENT_MASK_1); +} + +FORCEINLINE fltx4 SetZSIMD(const fltx4& a, const fltx4& z) +{ + return vec_sel(a, z, _VEC_COMPONENT_MASK_2); +} + +FORCEINLINE fltx4 SetWSIMD(const fltx4& a, const fltx4& w) +{ + return vec_sel(a, w, _VEC_COMPONENT_MASK_3); +} + +FORCEINLINE fltx4 SetComponentSIMD(const fltx4& a, int nComponent, float flValue) +{ +#if SN_IMPROVED_INTRINSICS + return vec_insert(flValue, a, nComponent); +#else + fltx4_union a_union; + a_union.vmxf = vec_ld(0, &a); + a_union.m128_f32[nComponent] = flValue; + return a_union.vmxf; +#endif +} + +FORCEINLINE float GetComponentSIMD(const fltx4& a, int nComponent) +{ +#if SN_IMPROVED_INTRINSICS + return vec_extract(a, nComponent); +#else + fltx4_union a_union; + a_union.vmxf = vec_ld(0, &a); + return a_union.m128_f32[nComponent]; +#endif +} + + +FORCEINLINE fltx4 RotateLeft(const fltx4& a) +{ + return vec_sld(a, a, 4); +} + +FORCEINLINE fltx4 RotateLeft2(const fltx4& a) +{ + return vec_sld(a, a, 8); +} + +FORCEINLINE fltx4 RotateRight(const fltx4& a) +{ + return vec_sld(a, a, 12); +} + +FORCEINLINE fltx4 RotateRight2(const fltx4& a) +{ + return vec_sld(a, a, 8); +} + +template < uint nBits, typename T > +FORCEINLINE T ShiftLeftByBits(const T& a) +{ + if (nBits >= 128) + { + return (T)LoadZeroSIMD(); + } + else if (nBits == 0) + { + return a; + } + else if ((nBits > 7)) + { + T t = vec_sld(a, ((T)LoadZeroSIMD()), (nBits >> 3)); + return ShiftLeftByBits< (nBits & 0x7) >(t); + } + else + { + vector unsigned int shifter = (vector unsigned int) (vec_splat_s8(((signed char)(nBits & 0x7)))); + return (T)vec_sll((vector signed int) a, shifter); + } +} + +template < uint nBits, typename T > +FORCEINLINE T ShiftRightByBits(const T& a) +{ + if (nBits >= 128) + { + return (T)LoadZeroSIMD(); + } + else if (nBits == 0) + { + return a; + } + else if ((nBits > 7)) + { + T t = vec_sld(((T)LoadZeroSIMD()), a, 16 - (nBits >> 3)); + return ShiftRightByBits< (nBits & 0x7) >(t); + } + else + { + vector unsigned int shifter = (vector unsigned int) (vec_splat_s8(((signed char)(nBits & 0x7)))); + return (T)vec_srl((vector unsigned int) a, shifter); + } +} + + + + +FORCEINLINE fltx4 FindLowestSIMD3(const fltx4& a) +{ + fltx4 result; + fltx4 x = vec_splat(a, 0); + fltx4 y = vec_splat(a, 1); + fltx4 z = vec_splat(a, 2); + + if (vec_any_nan(a)) + { + x = vec_all_nan(x) ? _VEC_FLTMAX : x; + y = vec_all_nan(y) ? _VEC_FLTMAX : y; + z = vec_all_nan(z) ? _VEC_FLTMAX : z; + } + + result = vec_min(y, x); + result = vec_min(z, result); + + return result; + +} + +FORCEINLINE fltx4 FindHighestSIMD3(const fltx4& a) +{ + fltx4 result; + fltx4 x = vec_splat(a, 0); + fltx4 y = vec_splat(a, 1); + fltx4 z = vec_splat(a, 2); + + if (vec_any_nan(a)) + { + x = vec_all_nan(x) ? _VEC_FLTMIN : x; + y = vec_all_nan(y) ? _VEC_FLTMIN : y; + z = vec_all_nan(z) ? _VEC_FLTMIN : z; + } + + result = vec_max(y, x); + result = vec_max(z, result); + + return result; +} + + +FORCEINLINE i32x4 LoadAlignedIntSIMD(const int32* RESTRICT pSIMD) +{ + return vec_ld(0, const_cast(pSIMD)); +} + +FORCEINLINE i32x4 LoadUnalignedIntSIMD(const int32* RESTRICT pSIMD) +{ + i32x4 v0, v1; + vector unsigned char permMask; + + Assert(pSIMD); + + v0 = vec_ld(0, const_cast(pSIMD)); + permMask = vec_lvsl(0, const_cast(pSIMD)); + v1 = vec_ld(15, const_cast(pSIMD)); + + return vec_perm(v0, v1, permMask); + +} + +FORCEINLINE void StoreAlignedIntSIMD(int32* pSIMD, const i32x4& a) +{ + vec_st(a, 0, pSIMD); +} + +FORCEINLINE void StoreAlignedIntSIMD(int32* pSIMD, const fltx4& a) +{ + vec_st((i32x4)a, 0, pSIMD); +} + +FORCEINLINE void StoreAlignedIntSIMD(intx4& pSIMD, const i32x4& a) +{ + vec_st(a, 0, pSIMD.Base()); +} + +FORCEINLINE void StoreUnalignedIntSIMD(int32* pSIMD, const i32x4& a) +{ +#if SN_IMPROVED_INTRINSICS + + vec_stvlx(a, 0, pSIMD); + vec_stvrx(a, 16, pSIMD); + +#else + + fltx4_union tmp; + vec_st(a, 0, &tmp.vmxi); + + pSIMD[0] = tmp.m128_u32[0]; + pSIMD[1] = tmp.m128_u32[1]; + pSIMD[2] = tmp.m128_u32[2]; + pSIMD[3] = tmp.m128_u32[3]; + +#endif +} + +FORCEINLINE fltx4 CompressSIMD(fltx4 const& a, fltx4 const& b) +{ + const int32 ALIGN16 n4shuffleACXZ[4] ALIGN16_POST = { 0x00010203, 0x08090A0B, 0x10111213, 0x18191A1B }; + return vec_perm(a, b, (vec_uchar16)LoadAlignedIntSIMD(n4shuffleACXZ)); +} + +FORCEINLINE fltx4 Compress4SIMD(fltx4 const a, fltx4 const& b, fltx4 const& c, fltx4 const& d) +{ + fltx4 ab = vec_mergeh(a, b); + fltx4 cd = vec_mergeh(c, d); + static const int32 ALIGN16 shuffleABXY[4] ALIGN16_POST = { 0x00010203, 0x04050607, 0x10111213, 0x14151617 }; + + return vec_perm(ab, cd, (vec_uchar16)LoadAlignedIntSIMD(shuffleABXY)); +} + + +FORCEINLINE fltx4 UnsignedIntConvertToFltSIMD(const i32x4& vSrcA) +{ + return vec_ctf(vSrcA, 0); +} + + +FORCEINLINE fltx4 SignedIntConvertToFltSIMD(const i32x4& vSrcA) +{ + return vec_ctf(vSrcA, 0); +} + +#define UnsignedFixedIntConvertToFltSIMD(vSrcA, uImmed) (vec_ctf( (vSrcA), (uImmed) )) + +#define SignedFixedIntConvertToFltSIMD(vSrcA, uImmed) (vec_ctf( (vSrcA), (uImmed) )) + +#define IntSetImmediateSIMD(x) (vec_splat_s32(x)) + + +FORCEINLINE u32x4 IntShiftLeftWordSIMD(u32x4 vSrcA, u32x4 vSrcB) +{ + return vec_sl(vSrcA, vSrcB); +} + + +FORCEINLINE float SubFloat(const fltx4& a, int idx) +{ +#if ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ == 1 ) && ( __GNUC_PATCHLEVEL__ == 1 ) + return(vec_extract(a, idx)); +#else + fltx4_union a_union; + vec_st(a, 0, &a_union.vmxf); + return a_union.m128_f32[idx]; +#endif +} + +FORCEINLINE float& SubFloat(fltx4& a, int idx) +{ + fltx4_union& a_union = (fltx4_union&)a; + return a_union.m128_f32[idx]; +} + +FORCEINLINE uint32 SubInt(const u32x4& a, int idx) +{ +#if ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ == 1 ) && ( __GNUC_PATCHLEVEL__ == 1 ) + return(vec_extract(a, idx)); +#else + fltx4_union a_union; + vec_st(a, 0, &a_union.vmxui); + return a_union.m128_u32[idx]; +#endif +} + +FORCEINLINE uint32 SubInt(const fltx4& a, int idx) +{ +#if ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ == 1 ) && ( __GNUC_PATCHLEVEL__ == 1 ) + return(vec_extract((u32x4)a, idx)); +#else + fltx4_union a_union; + vec_st(a, 0, &a_union.vmxf); + return a_union.m128_u32[idx]; +#endif +} + +FORCEINLINE uint32& SubInt(u32x4& a, int idx) +{ + fltx4_union& a_union = (fltx4_union&)a; + return a_union.m128_u32[idx]; +} + +FORCEINLINE uint32 SubFloatConvertToInt(const fltx4& a, int idx) +{ + +#if ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ == 1 ) && ( __GNUC_PATCHLEVEL__ == 1 ) + return(vec_extract(vec_ctu(a, 0), idx)); +#else + u32x4 t = vec_ctu(a, 0); + return SubInt(t, idx); +#endif + +} + +template< typename T, typename U > +FORCEINLINE T PermuteVMX(T a, T b, U swizzleMask) +{ + return vec_perm(a, b, (vec_uchar16)swizzleMask); +} + + +#if !defined(__SPU__) +#define fsel __fsel +#endif + +inline bool IsVector3LessThan(const fltx4& v1, const fltx4& v2) +{ + return vec_any_lt(v1, v2); +} + +inline bool IsVector3GreaterOrEqual(const fltx4& v1, const fltx4& v2) +{ + return !IsVector3LessThan(v1, v2); +} + +FORCEINLINE fltx4 ReciprocalSqrtEstSaturateSIMD(const fltx4& a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = 1.0 / sqrt(SubFloat(a, 0) != 0.0f ? SubFloat(a, 0) : FLT_EPSILON); + SubFloat(retVal, 1) = 1.0 / sqrt(SubFloat(a, 1) != 0.0f ? SubFloat(a, 1) : FLT_EPSILON); + SubFloat(retVal, 2) = 1.0 / sqrt(SubFloat(a, 2) != 0.0f ? SubFloat(a, 2) : FLT_EPSILON); + SubFloat(retVal, 3) = 1.0 / sqrt(SubFloat(a, 3) != 0.0f ? SubFloat(a, 3) : FLT_EPSILON); + return retVal; +} + +FORCEINLINE fltx4 FloorSIMD(const fltx4& a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = floor(SubFloat(a, 0)); + SubFloat(retVal, 1) = floor(SubFloat(a, 1)); + SubFloat(retVal, 2) = floor(SubFloat(a, 2)); + SubFloat(retVal, 3) = floor(SubFloat(a, 3)); + return retVal; +} + +#elif ( defined( _X360 ) ) + +inline bool IsVector3LessThan(const fltx4& v1, const fltx4& v2) +{ + return !XMVector3GreaterOrEqual(v1, v2); +} + +inline BOOL IsVector3GreaterOrEqual(const fltx4& v1, const fltx4& v2) +{ + return XMVector3GreaterOrEqual(v1, v2); +} + + +FORCEINLINE float& FloatSIMD(fltx4& a, int idx) +{ + fltx4_union& a_union = (fltx4_union&)a; + return a_union.m128_f32[idx]; +} + +FORCEINLINE unsigned int& UIntSIMD(fltx4& a, int idx) +{ + fltx4_union& a_union = (fltx4_union&)a; + return a_union.m128_u32[idx]; +} + +FORCEINLINE fltx4 AddSIMD(const fltx4& a, const fltx4& b) +{ + return __vaddfp(a, b); +} + +FORCEINLINE fltx4 SubSIMD(const fltx4& a, const fltx4& b) +{ + return __vsubfp(a, b); +} + +FORCEINLINE fltx4 MulSIMD(const fltx4& a, const fltx4& b) +{ + return __vmulfp(a, b); +} + +FORCEINLINE fltx4 MaddSIMD(const fltx4& a, const fltx4& b, const fltx4& c) +{ + return __vmaddfp(a, b, c); +} + +FORCEINLINE fltx4 MsubSIMD(const fltx4& a, const fltx4& b, const fltx4& c) +{ + return __vnmsubfp(a, b, c); +}; + +FORCEINLINE fltx4 Dot3SIMD(const fltx4& a, const fltx4& b) +{ + return __vmsum3fp(a, b); +} + +FORCEINLINE fltx4 Dot4SIMD(const fltx4& a, const fltx4& b) +{ + return __vmsum4fp(a, b); +} + +FORCEINLINE fltx4 SinSIMD(const fltx4& radians) +{ + return XMVectorSin(radians); +} + +FORCEINLINE void SinCos3SIMD(fltx4& sine, fltx4& cosine, const fltx4& radians) +{ + XMVectorSinCos(&sine, &cosine, radians); +} + +FORCEINLINE void SinCosSIMD(fltx4& sine, fltx4& cosine, const fltx4& radians) +{ + XMVectorSinCos(&sine, &cosine, radians); +} + +FORCEINLINE void CosSIMD(fltx4& cosine, const fltx4& radians) +{ + cosine = XMVectorCos(radians); +} + +FORCEINLINE fltx4 ArcSinSIMD(const fltx4& sine) +{ + return XMVectorASin(sine); +} + +FORCEINLINE fltx4 ArcCosSIMD(const fltx4& cs) +{ + return XMVectorACos(cs); +} + +FORCEINLINE fltx4 ArcTan2SIMD(const fltx4& a, const fltx4& b) +{ + return XMVectorATan2(a, b); +} + +FORCEINLINE fltx4 MaxSIMD(const fltx4& a, const fltx4& b) +{ + return __vmaxfp(a, b); +} + +FORCEINLINE fltx4 MinSIMD(const fltx4& a, const fltx4& b) +{ + return __vminfp(a, b); +} + +FORCEINLINE fltx4 AndSIMD(const fltx4& a, const fltx4& b) +{ + return __vand(a, b); +} + +FORCEINLINE fltx4 AndNotSIMD(const fltx4& a, const fltx4& b) +{ + return __vandc(b, a); +} + +FORCEINLINE fltx4 XorSIMD(const fltx4& a, const fltx4& b) +{ + return __vxor(a, b); +} + +FORCEINLINE fltx4 OrSIMD(const fltx4& a, const fltx4& b) +{ + return __vor(a, b); +} + +FORCEINLINE fltx4 NegSIMD(const fltx4& a) +{ + return XMVectorNegate(a); +} + +FORCEINLINE bool IsAllZeros(const fltx4& a) +{ + unsigned int equalFlags = 0; + __vcmpeqfpR(a, Four_Zeros, &equalFlags); + return XMComparisonAllTrue(equalFlags); +} + +FORCEINLINE bool IsAnyZeros(const fltx4& a) +{ + unsigned int conditionregister; + XMVectorEqualR(&conditionregister, a, XMVectorZero()); + return XMComparisonAnyTrue(conditionregister); +} + +FORCEINLINE bool IsAnyXYZZero(const fltx4& a) +{ + fltx4 temp = __vrlimi(a, a, 1, 1); + unsigned int conditionregister; + XMVectorEqualR(&conditionregister, temp, XMVectorZero()); + return XMComparisonAnyTrue(conditionregister); +} + +FORCEINLINE bool IsAllGreaterThan(const fltx4& a, const fltx4& b) +{ + unsigned int cr; + XMVectorGreaterR(&cr, a, b); + return XMComparisonAllTrue(cr); +} + +FORCEINLINE bool IsAllGreaterThanOrEq(const fltx4& a, const fltx4& b) +{ + unsigned int cr; + XMVectorGreaterOrEqualR(&cr, a, b); + return XMComparisonAllTrue(cr); +} + +FORCEINLINE bool IsAnyGreaterThan(const fltx4& a, const fltx4& b) +{ + unsigned int cr; + XMVectorGreaterR(&cr, a, b); + return XMComparisonAnyTrue(cr); +} + +FORCEINLINE bool IsAnyGreaterThanOrEq(const fltx4& a, const fltx4& b) +{ + unsigned int cr; + XMVectorGreaterOrEqualR(&cr, a, b); + return XMComparisonAnyTrue(cr); +} + +FORCEINLINE bool IsAllEqual(const fltx4& a, const fltx4& b) +{ + unsigned int cr; + XMVectorEqualR(&cr, a, b); + return XMComparisonAllTrue(cr); +} + + +FORCEINLINE int TestSignSIMD(const fltx4& a) +{ + int nRet = 0; + + const fltx4_union& a_union = (const fltx4_union&)a; + nRet |= (a_union.m128_u32[0] & 0x80000000) >> 31; + nRet |= (a_union.m128_u32[1] & 0x80000000) >> 30; + nRet |= (a_union.m128_u32[2] & 0x80000000) >> 29; + nRet |= (a_union.m128_u32[3] & 0x80000000) >> 28; + + return nRet; +} + +FORCEINLINE fltx4 SetWToZeroSIMD(const fltx4& a) +{ + return __vrlimi(a, __vzero(), 1, 0); +} + +FORCEINLINE bool IsAnyNegative(const fltx4& a) +{ + unsigned int equalFlags = 0; + fltx4 signMask = __vspltisw(-1); + signMask = __vslw(signMask, signMask); + __vcmpequwR(Four_Zeros, __vand(signMask, a), &equalFlags); + return !XMComparisonAllTrue(equalFlags); +} + +FORCEINLINE bool IsAnyTrue(const fltx4& a) +{ + unsigned int equalFlags = 0; + __vcmpequwR(Four_Zeros, a, &equalFlags); + return XMComparisonAnyFalse(equalFlags); +} + +FORCEINLINE fltx4 CmpEqSIMD(const fltx4& a, const fltx4& b) +{ + return __vcmpeqfp(a, b); +} + + +FORCEINLINE fltx4 CmpGtSIMD(const fltx4& a, const fltx4& b) +{ + return __vcmpgtfp(a, b); +} + +FORCEINLINE fltx4 CmpGeSIMD(const fltx4& a, const fltx4& b) +{ + return __vcmpgefp(a, b); +} + +FORCEINLINE fltx4 CmpLtSIMD(const fltx4& a, const fltx4& b) +{ + return __vcmpgtfp(b, a); +} + +FORCEINLINE fltx4 CmpLeSIMD(const fltx4& a, const fltx4& b) +{ + return __vcmpgefp(b, a); +} + +FORCEINLINE fltx4 CmpInBoundsSIMD(const fltx4& a, const fltx4& b) +{ + return XMVectorInBounds(a, b); +} + +FORCEINLINE fltx4 MaskedAssign(const fltx4& ReplacementMask, const fltx4& NewValue, const fltx4& OldValue) +{ + return __vsel(OldValue, NewValue, ReplacementMask); +} + + +template< typename T, typename U > +FORCEINLINE T PermuteVMX(T a, T b, U swizzleMask) +{ + return __vperm(a, b, swizzleMask); +} + +FORCEINLINE fltx4 ReplicateX4(float flValue) +{ + float* pValue = &flValue; + Assert(pValue); + Assert(((unsigned int)pValue & 3) == 0); + return __vspltw(__lvlx(pValue, 0), 0); +} + +FORCEINLINE fltx4 ReplicateX4(const float* pValue) +{ + Assert(pValue); + return __vspltw(__lvlx(pValue, 0), 0); +} + +FORCEINLINE fltx4 ReplicateIX4(int nValue) +{ + int* pValue = &nValue; + Assert(pValue); + Assert(((unsigned int)pValue & 3) == 0); + return __vspltw(__lvlx(pValue, 0), 0); +} + +FORCEINLINE fltx4 CeilSIMD(const fltx4& a) +{ + return __vrfip(a); +} + +FORCEINLINE fltx4 RoundSIMD(const fltx4& a) +{ + return __vrfin(a); +} + +FORCEINLINE fltx4 FloorSIMD(const fltx4& a) +{ + return __vrfim(a); +} + +FORCEINLINE fltx4 SqrtEstSIMD(const fltx4& a) +{ + return XMVectorSqrtEst(a); +} + +FORCEINLINE fltx4 SqrtSIMD(const fltx4& a) +{ + return XMVectorSqrt(a); +} + +FORCEINLINE fltx4 ReciprocalSqrtEstSIMD(const fltx4& a) +{ + return __vrsqrtefp(a); +} + +FORCEINLINE fltx4 ReciprocalSqrtEstSaturateSIMD(const fltx4& a) +{ + fltx4 zero_mask = CmpEqSIMD(a, Four_Zeros); + fltx4 a_safe = OrSIMD(a, AndSIMD(Four_Epsilons, zero_mask)); + return ReciprocalSqrtEstSIMD(a_safe); +} + +FORCEINLINE fltx4 ReciprocalSqrtSIMD(const fltx4& a) +{ + return XMVectorReciprocalSqrt(a); +} + +FORCEINLINE fltx4 ReciprocalEstSIMD(const fltx4& a) +{ + return __vrefp(a); +} + +FORCEINLINE fltx4 ReciprocalSIMD(const fltx4& a) +{ + return XMVectorReciprocal(a); +} + +FORCEINLINE fltx4 DivSIMD(const fltx4& a, const fltx4& b) +{ + return MulSIMD(ReciprocalSIMD(b), a); +} + +FORCEINLINE fltx4 DivEstSIMD(const fltx4& a, const fltx4& b) +{ + return MulSIMD(ReciprocalEstSIMD(b), a); +} + +FORCEINLINE fltx4 ReciprocalEstSaturateSIMD(const fltx4& a) +{ + fltx4 zero_mask = CmpEqSIMD(a, Four_Zeros); + fltx4 a_safe = OrSIMD(a, AndSIMD(Four_Epsilons, zero_mask)); + return ReciprocalEstSIMD(a_safe); +} + +FORCEINLINE fltx4 ReciprocalSaturateSIMD(const fltx4& a) +{ + fltx4 zero_mask = CmpEqSIMD(a, Four_Zeros); + fltx4 a_safe = OrSIMD(a, AndSIMD(Four_Epsilons, zero_mask)); + return ReciprocalSIMD(a_safe); + +} + +FORCEINLINE fltx4 ExpSIMD(const fltx4& toPower) +{ + return XMVectorExp(toPower); +} + +FORCEINLINE fltx4 Exp2EstSIMD(const fltx4& f) +{ + return XMVectorExpEst(f); +} + +FORCEINLINE fltx4 ClampVectorSIMD(FLTX4 in, FLTX4 min, FLTX4 max) +{ + return XMVectorClamp(in, min, max); +} + +FORCEINLINE fltx4 LoadUnalignedSIMD(const void* pSIMD) +{ + return XMLoadVector4(pSIMD); +} + +FORCEINLINE fltx4 LoadUnaligned3SIMD(const void* pSIMD) +{ + return XMLoadVector3(pSIMD); +} + +FORCEINLINE fltx4 LoadUnalignedFloatSIMD(const float* pFlt) +{ + return __lvlx(pFlt, 0); +} + +FORCEINLINE fltx4 LoadAlignedSIMD(const void* pSIMD) +{ + return *(reinterpret_cast (pSIMD)); +} + +FORCEINLINE fltx4 LoadAlignedSIMD(const VectorAligned& pSIMD) +{ + fltx4 out = XMLoadVector3A(pSIMD.Base()); + return __vrlimi(out, __vzero(), 1, 0); +} + +FORCEINLINE fltx4 LoadAlignedSIMD(const VectorAligned* RESTRICT pSIMD) +{ + fltx4 out = XMLoadVector3A(pSIMD); + return __vrlimi(out, __vzero(), 1, 0); +} + +FORCEINLINE void StoreAlignedSIMD(float* pSIMD, const fltx4& a) +{ + *(reinterpret_cast (pSIMD)) = a; +} + +FORCEINLINE void StoreUnalignedSIMD(float* pSIMD, const fltx4& a) +{ + XMStoreVector4(pSIMD, a); +} + +FORCEINLINE void StoreUnaligned3SIMD(float* pSIMD, const fltx4& a) +{ + XMStoreVector3(pSIMD, a); +} + +FORCEINLINE void StoreAligned3SIMD(VectorAligned* RESTRICT pSIMD, const fltx4& a) +{ + XMStoreVector3A(pSIMD->Base(), a); +} + +FORCEINLINE void StoreFourUnalignedVector3SIMD(fltx4 a, fltx4 b, fltx4 c, FLTX4 d, + Vector* const pDestination) +{ + b = __vrlimi(b, b, 15, 1); + c = __vrlimi(c, c, 15, 2); + + a = __vrlimi(a, b, 1, 0); + b = __vrlimi(b, c, 2 | 1, 0); + c = __vrlimi(c, d, 4 | 2 | 1, 3); + + float* RESTRICT pOut = pDestination->Base(); + StoreUnalignedSIMD(pOut + 0, a); + StoreUnalignedSIMD(pOut + 4, b); + StoreUnalignedSIMD(pOut + 8, c); +} + +FORCEINLINE void StoreFourAlignedVector3SIMD(fltx4 a, fltx4 b, fltx4 c, FLTX4 d, + Vector* const pDestination) +{ + b = __vrlimi(b, b, 15, 1); + c = __vrlimi(c, c, 15, 2); + + a = __vrlimi(a, b, 1, 0); + b = __vrlimi(b, c, 2 | 1, 0); + c = __vrlimi(c, d, 4 | 2 | 1, 3); + + float* RESTRICT pOut = pDestination->Base(); + StoreAlignedSIMD(pOut + 0, a); + StoreAlignedSIMD(pOut + 4, b); + StoreAlignedSIMD(pOut + 8, c); +} + +FORCEINLINE void ConvertStoreAsIntsSIMD(intx4* RESTRICT pDest, const fltx4& vSrc) +{ + fltx4 asInt = __vctsxs(vSrc, 0); + XMStoreVector4A(pDest->Base(), asInt); +} + +FORCEINLINE void TransposeSIMD(fltx4& x, fltx4& y, fltx4& z, fltx4& w) +{ + XMMATRIX xyzwMatrix = _XMMATRIX(x, y, z, w); + xyzwMatrix = XMMatrixTranspose(xyzwMatrix); + x = xyzwMatrix.r[0]; + y = xyzwMatrix.r[1]; + z = xyzwMatrix.r[2]; + w = xyzwMatrix.r[3]; +} + +FORCEINLINE fltx4 LoadZeroSIMD(void) +{ + return XMVectorZero(); +} + +FORCEINLINE fltx4 LoadOneSIMD(void) +{ + return XMVectorSplatOne(); +} + +FORCEINLINE fltx4 SplatXSIMD(fltx4 a) +{ + return XMVectorSplatX(a); +} + +FORCEINLINE fltx4 SplatYSIMD(fltx4 a) +{ + return XMVectorSplatY(a); +} + +FORCEINLINE fltx4 SplatZSIMD(fltx4 a) +{ + return XMVectorSplatZ(a); +} + +FORCEINLINE fltx4 SplatWSIMD(fltx4 a) +{ + return XMVectorSplatW(a); +} + +FORCEINLINE fltx4 SetXSIMD(const fltx4& a, const fltx4& x) +{ + fltx4 result = __vrlimi(a, x, 8, 0); + return result; +} + +FORCEINLINE fltx4 SetYSIMD(const fltx4& a, const fltx4& y) +{ + fltx4 result = __vrlimi(a, y, 4, 0); + return result; +} + +FORCEINLINE fltx4 SetZSIMD(const fltx4& a, const fltx4& z) +{ + fltx4 result = __vrlimi(a, z, 2, 0); + return result; +} + +FORCEINLINE fltx4 SetWSIMD(const fltx4& a, const fltx4& w) +{ + fltx4 result = __vrlimi(a, w, 1, 0); + return result; +} + +FORCEINLINE fltx4 SetComponentSIMD(const fltx4& a, int nComponent, float flValue) +{ + static int s_nVrlimiMask[4] = { 8, 4, 2, 1 }; + fltx4 val = ReplicateX4(flValue); + fltx4 result = __vrlimi(a, val, s_nVrlimiMask[nComponent], 0); + return result; +} + +FORCEINLINE fltx4 RotateLeft(const fltx4& a) +{ + fltx4 compareOne = a; + return __vrlimi(compareOne, a, 8 | 4 | 2 | 1, 1); +} + +FORCEINLINE fltx4 RotateLeft2(const fltx4& a) +{ + fltx4 compareOne = a; + return __vrlimi(compareOne, a, 8 | 4 | 2 | 1, 2); +} + +FORCEINLINE fltx4 RotateRight(const fltx4& a) +{ + fltx4 compareOne = a; + return __vrlimi(compareOne, a, 8 | 4 | 2 | 1, 3); +} + +FORCEINLINE fltx4 RotateRight2(const fltx4& a) +{ + fltx4 compareOne = a; + return __vrlimi(compareOne, a, 8 | 4 | 2 | 1, 2); +} + + +template < uint nBits > +FORCEINLINE fltx4 ShiftLeftByBits(const fltx4& a) +{ + if (nBits >= 128) + { + return LoadZeroSIMD(); + } + else if (nBits == 0) + { + return a; + } + else if ((nBits > 7)) + { + fltx4 t = __vsldoi(a, (LoadZeroSIMD()), (nBits >> 3)); + return ShiftLeftByBits< (nBits & 0x7) >(t); + } + else + { + u32x4 shifter = u32x4(__vspltisb(((signed char)(nBits & 0x7)))); + return __vsl(a, shifter); + } +} + +template < uint nBits > +FORCEINLINE fltx4 ShiftRightByBits(const fltx4& a) +{ + if (nBits >= 128) + { + return LoadZeroSIMD(); + } + else if (nBits == 0) + { + return a; + } + else if ((nBits > 7)) + { + fltx4 t = __vsldoi((LoadZeroSIMD()), a, 16 - (nBits >> 3)); + return ShiftRightByBits< (nBits & 0x7) >(t); + } + else + { + u32x4 shifter = u32x4(__vspltisb(((signed char)(nBits & 0x7)))); + return __vsr(a, shifter); + } +} + +FORCEINLINE fltx4 FindLowestSIMD3(const fltx4& a) +{ + fltx4 compareOne = a; + compareOne = __vrlimi(compareOne, a, 8 | 4, 1); + fltx4 retval = MinSIMD(a, compareOne); + compareOne = __vrlimi(compareOne, a, 8, 2); + retval = MinSIMD(retval, compareOne); + return SplatXSIMD(retval); +} + +FORCEINLINE fltx4 FindHighestSIMD3(const fltx4& a) +{ + fltx4 compareOne = a; + compareOne = __vrlimi(compareOne, a, 8 | 4, 1); + fltx4 retval = MaxSIMD(a, compareOne); + compareOne = __vrlimi(compareOne, a, 8, 2); + retval = MaxSIMD(retval, compareOne); + return SplatXSIMD(retval); +} + + +void TransformManyPointsBy(VectorAligned* RESTRICT pVectors, unsigned int numVectors, FLTX4 mRow1, FLTX4 mRow2, FLTX4 mRow3); + +FORCEINLINE void TransformManyPointsBy(VectorAligned* RESTRICT pVectors, unsigned int numVectors, const matrix3x4_t& pMatrix) +{ + return TransformManyPointsBy(pVectors, numVectors, + LoadUnalignedSIMD(pMatrix[0]), LoadUnalignedSIMD(pMatrix[1]), LoadUnalignedSIMD(pMatrix[2])); +} + +FORCEINLINE void TransformManyPointsByA(VectorAligned* RESTRICT pVectors, unsigned int numVectors, const matrix3x4_t& pMatrix) +{ + return TransformManyPointsBy(pVectors, numVectors, + LoadAlignedSIMD(pMatrix[0]), LoadAlignedSIMD(pMatrix[1]), LoadAlignedSIMD(pMatrix[2])); +} + +FORCEINLINE i32x4 LoadAlignedIntSIMD(const void* RESTRICT pSIMD) +{ + return XMLoadVector4A(pSIMD); +} + +FORCEINLINE i32x4 LoadUnalignedIntSIMD(const void* RESTRICT pSIMD) +{ + return XMLoadVector4(pSIMD); +} + +FORCEINLINE void StoreAlignedIntSIMD(int32* pSIMD, const fltx4& a) +{ + *(reinterpret_cast (pSIMD)) = a; +} + +FORCEINLINE void StoreAlignedIntSIMD(intx4& pSIMD, const fltx4& a) +{ + *(reinterpret_cast (pSIMD.Base())) = a; +} + +FORCEINLINE void StoreUnalignedIntSIMD(int32* pSIMD, const fltx4& a) +{ + XMStoreVector4(pSIMD, a); +} + +FORCEINLINE fltx4 LoadAndConvertUint16SIMD(const uint16* pInts) +{ + return XMLoadUShort4(reinterpret_cast(pInts)); +} + +FORCEINLINE fltx4 CompressSIMD(fltx4 const& a, fltx4 const& b) +{ + return XMVectorPermute(a, b, XMVectorPermuteControl(0, 2, 4, 6)); +} + +FORCEINLINE fltx4 Compress4SIMD(fltx4 const a, fltx4 const& b, fltx4 const& c, fltx4 const& d) +{ + fltx4 abcd = __vrlimi(a, b, 4, 3); + abcd = __vrlimi(abcd, c, 2, 2); + abcd = __vrlimi(abcd, d, 1, 1); + + return abcd; +} + + +FORCEINLINE fltx4 LoadGatherSIMD(const float& x, const float& y, const float& z, const float& w) +{ + fltx4 vx = __lvlx(&x, 0); + fltx4 vy = __lvlx(&y, 0); + fltx4 vz = __lvlx(&z, 0); + fltx4 vw = __lvlx(&w, 0); + return Compress4SIMD(vx, vy, vz, vw); +} + +FORCEINLINE fltx4 UnsignedIntConvertToFltSIMD(const i32x4& vSrcA) +{ + return __vcfux(vSrcA, 0); +} + +FORCEINLINE fltx4 SignedIntConvertToFltSIMD(const i32x4& vSrcA) +{ + return __vcfsx(vSrcA, 0); +} + +#define UnsignedFixedIntConvertToFltSIMD(vSrcA, uImmed) (__vcfux( (vSrcA), (uImmed) )) + +#define SignedFixedIntConvertToFltSIMD(vSrcA, uImmed) (__vcfsx( (vSrcA), (uImmed) )) + +#define IntSetImmediateSIMD(x) (__vspltisw(x)) + +FORCEINLINE fltx4 IntShiftLeftWordSIMD(fltx4 vSrcA, fltx4 vSrcB) +{ + return __vslw(vSrcA, vSrcB); +} + +FORCEINLINE float SubFloat(const fltx4& a, int idx) +{ + const fltx4_union& a_union = (const fltx4_union&)a; + return a_union.m128_f32[idx]; +} + +FORCEINLINE float& SubFloat(fltx4& a, int idx) +{ + fltx4_union& a_union = (fltx4_union&)a; + return a_union.m128_f32[idx]; +} + +FORCEINLINE uint32 SubFloatConvertToInt(const fltx4& a, int idx) +{ + fltx4 t = __vctuxs(a, 0); + const fltx4_union& a_union = (const fltx4_union&)t; + return a_union.m128_u32[idx]; +} + + +FORCEINLINE uint32 SubInt(const fltx4& a, int idx) +{ + const fltx4_union& a_union = (const fltx4_union&)a; + return a_union.m128_u32[idx]; +} + +FORCEINLINE uint32& SubInt(fltx4& a, int idx) +{ + fltx4_union& a_union = (fltx4_union&)a; + return a_union.m128_u32[idx]; +} + +#else + +FORCEINLINE void StoreAlignedSIMD(float* RESTRICT pSIMD, const fltx4& a) +{ + _mm_store_ps(pSIMD, a); +} + +FORCEINLINE void StoreAlignedSIMD(short* RESTRICT pSIMD, const shortx8& a) +{ + _mm_store_si128((shortx8*)pSIMD, a); +} +FORCEINLINE void StoreUnalignedSIMD(float* RESTRICT pSIMD, const fltx4& a) +{ + _mm_storeu_ps(pSIMD, a); +} + +FORCEINLINE void StoreUnalignedSIMD(short* RESTRICT pSIMD, const shortx8& a) +{ + _mm_storeu_si128((shortx8*)pSIMD, a); +} + +FORCEINLINE void StoreUnalignedFloat(float* pSingleFloat, const fltx4& a) +{ + _mm_store_ss(pSingleFloat, a); +} + + +FORCEINLINE fltx4 RotateLeft(const fltx4& a); +FORCEINLINE fltx4 RotateLeft2(const fltx4& a); + +FORCEINLINE void StoreUnaligned3SIMD(float* pSIMD, const fltx4& a) +{ + _mm_store_ss(pSIMD, a); + _mm_store_ss(pSIMD + 1, RotateLeft(a)); + _mm_store_ss(pSIMD + 2, RotateLeft2(a)); +} + + +FORCEINLINE void StoreAligned3SIMD(VectorAligned* RESTRICT pSIMD, const fltx4& a) +{ + StoreAlignedSIMD(pSIMD->Base(), a); +} + +FORCEINLINE void StoreFourUnalignedVector3SIMD(fltx4 a, fltx4 b, fltx4 c, FLTX4 d, + Vector* const pDestination) +{ + StoreUnaligned3SIMD(pDestination->Base(), a); + StoreUnaligned3SIMD((pDestination + 1)->Base(), b); + StoreUnaligned3SIMD((pDestination + 2)->Base(), c); + StoreUnaligned3SIMD((pDestination + 3)->Base(), d); +} + +FORCEINLINE void StoreFourAlignedVector3SIMD(fltx4 a, fltx4 b, fltx4 c, FLTX4 d, + Vector* const pDestination) +{ + StoreUnaligned3SIMD(pDestination->Base(), a); + StoreUnaligned3SIMD((pDestination + 1)->Base(), b); + StoreUnaligned3SIMD((pDestination + 2)->Base(), c); + StoreUnaligned3SIMD((pDestination + 3)->Base(), d); +} + +FORCEINLINE fltx4 LoadAlignedSIMD(const void* pSIMD) +{ + return _mm_load_ps(reinterpret_cast (pSIMD)); +} + +FORCEINLINE shortx8 LoadAlignedShortSIMD(const void* pSIMD) +{ + return _mm_load_si128(reinterpret_cast (pSIMD)); +} + +FORCEINLINE shortx8 LoadUnalignedShortSIMD(const void* pSIMD) +{ + return _mm_loadu_si128(reinterpret_cast (pSIMD)); +} + +FORCEINLINE fltx4 AndSIMD(const fltx4& a, const fltx4& b) +{ + return _mm_and_ps(a, b); +} + +FORCEINLINE fltx4 AndNotSIMD(const fltx4& a, const fltx4& b) +{ + return _mm_andnot_ps(a, b); +} + +FORCEINLINE fltx4 XorSIMD(const fltx4& a, const fltx4& b) +{ + return _mm_xor_ps(a, b); +} + +FORCEINLINE fltx4 OrSIMD(const fltx4& a, const fltx4& b) +{ + return _mm_or_ps(a, b); +} + +FORCEINLINE fltx4 SetWToZeroSIMD(const fltx4& a) +{ + return AndSIMD(a, LoadAlignedSIMD(g_SIMD_clear_wmask)); +} + +FORCEINLINE fltx4 LoadAlignedSIMD(const VectorAligned& pSIMD) +{ + return SetWToZeroSIMD(LoadAlignedSIMD(pSIMD.Base())); +} + +FORCEINLINE fltx4 LoadUnalignedSIMD(const void* pSIMD) +{ + return _mm_loadu_ps(reinterpret_cast(pSIMD)); +} + +FORCEINLINE fltx4 LoadUnaligned3SIMD(const void* pSIMD) +{ + return _mm_loadu_ps(reinterpret_cast(pSIMD)); +} + +FORCEINLINE fltx4 LoadUnalignedFloatSIMD(const float* pFlt) +{ + return _mm_load_ss(pFlt); +} + +FORCEINLINE fltx4 ReplicateIX4(int i) +{ + fltx4 value = _mm_set_ss(*((float*)&i));; + return _mm_shuffle_ps(value, value, 0); +} + + +FORCEINLINE fltx4 ReplicateX4(float flValue) +{ + __m128 value = _mm_set_ss(flValue); + return _mm_shuffle_ps(value, value, 0); +} + +FORCEINLINE fltx4 ReplicateX4(const float* flValue) +{ + __m128 value = _mm_set_ss(*flValue); + return _mm_shuffle_ps(value, value, 0); +} + +FORCEINLINE float SubFloat(const fltx4& a, int idx) +{ +#ifndef POSIX + return a.m128_f32[idx]; +#else + return (reinterpret_cast(&a))[idx]; +#endif +} + +FORCEINLINE float& SubFloat(fltx4& a, int idx) +{ +#ifndef POSIX + return a.m128_f32[idx]; +#else + return (reinterpret_cast(&a))[idx]; +#endif +} + +FORCEINLINE uint32 SubFloatConvertToInt(const fltx4& a, int idx) +{ + return (uint32)SubFloat(a, idx); +} + +FORCEINLINE uint32 SubInt(const fltx4& a, int idx) +{ +#ifndef POSIX + return a.m128_u32[idx]; +#else + return (reinterpret_cast(&a))[idx]; +#endif +} + +FORCEINLINE uint32& SubInt(fltx4& a, int idx) +{ +#ifndef POSIX + return a.m128_u32[idx]; +#else + return (reinterpret_cast(&a))[idx]; +#endif +} + +FORCEINLINE fltx4 LoadZeroSIMD(void) +{ + return Four_Zeros; +} + +FORCEINLINE fltx4 LoadOneSIMD(void) +{ + return Four_Ones; +} + +FORCEINLINE fltx4 MaskedAssign(const fltx4& ReplacementMask, const fltx4& NewValue, const fltx4& OldValue) +{ + return OrSIMD( + AndSIMD(ReplacementMask, NewValue), + AndNotSIMD(ReplacementMask, OldValue)); +} + +#define MM_SHUFFLE_REV(a,b,c,d) _MM_SHUFFLE(d,c,b,a) + +FORCEINLINE fltx4 SplatXSIMD(fltx4 const& a) +{ + return _mm_shuffle_ps(a, a, MM_SHUFFLE_REV(0, 0, 0, 0)); +} + +FORCEINLINE fltx4 SplatYSIMD(fltx4 const& a) +{ + return _mm_shuffle_ps(a, a, MM_SHUFFLE_REV(1, 1, 1, 1)); +} + +FORCEINLINE fltx4 SplatZSIMD(fltx4 const& a) +{ + return _mm_shuffle_ps(a, a, MM_SHUFFLE_REV(2, 2, 2, 2)); +} + +FORCEINLINE fltx4 SplatWSIMD(fltx4 const& a) +{ + return _mm_shuffle_ps(a, a, MM_SHUFFLE_REV(3, 3, 3, 3)); +} + +FORCEINLINE fltx4 ShuffleXXYY(const fltx4& a) +{ + return _mm_shuffle_ps(a, a, MM_SHUFFLE_REV(0, 0, 1, 1)); +} + +FORCEINLINE fltx4 ShuffleXYXY(const fltx4& a) +{ + return _mm_shuffle_ps(a, a, MM_SHUFFLE_REV(0, 1, 0, 1)); +} + +FORCEINLINE fltx4 ShuffleZZWW(const fltx4& a) +{ + return _mm_shuffle_ps(a, a, MM_SHUFFLE_REV(2, 2, 3, 3)); +} + + + + +FORCEINLINE fltx4 SetXSIMD(const fltx4& a, const fltx4& x) +{ + fltx4 result = MaskedAssign(LoadAlignedSIMD(g_SIMD_ComponentMask[0]), x, a); + return result; +} + +FORCEINLINE fltx4 SetYSIMD(const fltx4& a, const fltx4& y) +{ + fltx4 result = MaskedAssign(LoadAlignedSIMD(g_SIMD_ComponentMask[1]), y, a); + return result; +} + +FORCEINLINE fltx4 SetZSIMD(const fltx4& a, const fltx4& z) +{ + fltx4 result = MaskedAssign(LoadAlignedSIMD(g_SIMD_ComponentMask[2]), z, a); + return result; +} + +FORCEINLINE fltx4 SetWSIMD(const fltx4& a, const fltx4& w) +{ + fltx4 result = MaskedAssign(LoadAlignedSIMD(g_SIMD_ComponentMask[3]), w, a); + return result; +} + +FORCEINLINE fltx4 SetComponentSIMD(const fltx4& a, int nComponent, float flValue) +{ + fltx4 val = ReplicateX4(flValue); + fltx4 result = MaskedAssign(LoadAlignedSIMD(g_SIMD_ComponentMask[nComponent]), val, a); + return result; +} + +FORCEINLINE fltx4 RotateLeft(const fltx4& a) +{ + return _mm_shuffle_ps(a, a, MM_SHUFFLE_REV(1, 2, 3, 0)); +} + +FORCEINLINE fltx4 RotateLeft2(const fltx4& a) +{ + return _mm_shuffle_ps(a, a, MM_SHUFFLE_REV(2, 3, 0, 1)); +} + +FORCEINLINE fltx4 RotateRight(const fltx4& a) +{ + return _mm_shuffle_ps(a, a, MM_SHUFFLE_REV(3, 0, 1, 2)); +} + +FORCEINLINE fltx4 RotateRight2(const fltx4& a) +{ + return _mm_shuffle_ps(a, a, MM_SHUFFLE_REV(2, 3, 0, 1)); +} + +FORCEINLINE fltx4 AddSIMD(const fltx4& a, const fltx4& b) +{ + return _mm_add_ps(a, b); +} + +FORCEINLINE fltx4 SubSIMD(const fltx4& a, const fltx4& b) +{ + return _mm_sub_ps(a, b); +}; + +FORCEINLINE fltx4 MulSIMD(const fltx4& a, const fltx4& b) +{ + return _mm_mul_ps(a, b); +}; + +FORCEINLINE fltx4 DivSIMD(const fltx4& a, const fltx4& b) +{ + return _mm_div_ps(a, b); +}; + +fltx4 ReciprocalEstSIMD(const fltx4& a); +FORCEINLINE fltx4 DivEstSIMD(const fltx4& a, const fltx4& b) +{ + return MulSIMD(ReciprocalEstSIMD(b), a); +}; + +FORCEINLINE fltx4 MaddSIMD(const fltx4& a, const fltx4& b, const fltx4& c) +{ + return AddSIMD(MulSIMD(a, b), c); +} + +FORCEINLINE fltx4 MsubSIMD(const fltx4& a, const fltx4& b, const fltx4& c) +{ + return SubSIMD(c, MulSIMD(a, b)); +}; + +FORCEINLINE fltx4 Dot3SIMD(const fltx4& a, const fltx4& b) +{ + fltx4 m = MulSIMD(a, b); + return AddSIMD(AddSIMD(SplatXSIMD(m), SplatYSIMD(m)), SplatZSIMD(m)); +} + +FORCEINLINE fltx4 Dot4SIMD(const fltx4& a, const fltx4& b) +{ + fltx4 fl4Product = MulSIMD(a, b); + fltx4 fl4YXWZ = _mm_shuffle_ps(fl4Product, fl4Product, MM_SHUFFLE_REV(1, 0, 3, 2)); + fltx4 fl4UUVV = AddSIMD(fl4Product, fl4YXWZ); + fltx4 fl4VVUU = RotateLeft2(fl4UUVV); + return AddSIMD(fl4UUVV, fl4VVUU); +} + +FORCEINLINE fltx4 SinSIMD(const fltx4& radians) +{ + fltx4 result; + SubFloat(result, 0) = sin(SubFloat(radians, 0)); + SubFloat(result, 1) = sin(SubFloat(radians, 1)); + SubFloat(result, 2) = sin(SubFloat(radians, 2)); + SubFloat(result, 3) = sin(SubFloat(radians, 3)); + return result; +} + +FORCEINLINE void SinCos3SIMD(fltx4& sine, fltx4& cosine, const fltx4& radians) +{ + SinCos(SubFloat(radians, 0), &SubFloat(sine, 0), &SubFloat(cosine, 0)); + SinCos(SubFloat(radians, 1), &SubFloat(sine, 1), &SubFloat(cosine, 1)); + SinCos(SubFloat(radians, 2), &SubFloat(sine, 2), &SubFloat(cosine, 2)); +} + +FORCEINLINE void SinCosSIMD(fltx4& sine, fltx4& cosine, const fltx4& radians) +{ + SinCos(SubFloat(radians, 0), &SubFloat(sine, 0), &SubFloat(cosine, 0)); + SinCos(SubFloat(radians, 1), &SubFloat(sine, 1), &SubFloat(cosine, 1)); + SinCos(SubFloat(radians, 2), &SubFloat(sine, 2), &SubFloat(cosine, 2)); + SinCos(SubFloat(radians, 3), &SubFloat(sine, 3), &SubFloat(cosine, 3)); +} + +FORCEINLINE fltx4 ArcSinSIMD(const fltx4& sine) +{ + fltx4 result; + SubFloat(result, 0) = asin(SubFloat(sine, 0)); + SubFloat(result, 1) = asin(SubFloat(sine, 1)); + SubFloat(result, 2) = asin(SubFloat(sine, 2)); + SubFloat(result, 3) = asin(SubFloat(sine, 3)); + return result; +} + +FORCEINLINE fltx4 ArcCosSIMD(const fltx4& cs) +{ + fltx4 result; + SubFloat(result, 0) = acos(SubFloat(cs, 0)); + SubFloat(result, 1) = acos(SubFloat(cs, 1)); + SubFloat(result, 2) = acos(SubFloat(cs, 2)); + SubFloat(result, 3) = acos(SubFloat(cs, 3)); + return result; +} + +FORCEINLINE fltx4 ArcTan2SIMD(const fltx4& a, const fltx4& b) +{ + fltx4 result; + SubFloat(result, 0) = atan2(SubFloat(a, 0), SubFloat(b, 0)); + SubFloat(result, 1) = atan2(SubFloat(a, 1), SubFloat(b, 1)); + SubFloat(result, 2) = atan2(SubFloat(a, 2), SubFloat(b, 2)); + SubFloat(result, 3) = atan2(SubFloat(a, 3), SubFloat(b, 3)); + return result; +} + +FORCEINLINE fltx4 NegSIMD(const fltx4& a) +{ + return SubSIMD(LoadZeroSIMD(), a); +} + +FORCEINLINE int TestSignSIMD(const fltx4& a) +{ + return _mm_movemask_ps(a); +} + +FORCEINLINE bool IsAnyNegative(const fltx4& a) +{ + return (0 != TestSignSIMD(a)); +} + +FORCEINLINE bool IsAnyTrue(const fltx4& a) +{ + return (0 != TestSignSIMD(a)); +} + +FORCEINLINE fltx4 CmpEqSIMD(const fltx4& a, const fltx4& b) +{ + return _mm_cmpeq_ps(a, b); +} + +FORCEINLINE fltx4 CmpGtSIMD(const fltx4& a, const fltx4& b) +{ + return _mm_cmpgt_ps(a, b); +} + +FORCEINLINE fltx4 CmpGeSIMD(const fltx4& a, const fltx4& b) +{ + return _mm_cmpge_ps(a, b); +} + +FORCEINLINE fltx4 CmpLtSIMD(const fltx4& a, const fltx4& b) +{ + return _mm_cmplt_ps(a, b); +} + +FORCEINLINE fltx4 CmpLeSIMD(const fltx4& a, const fltx4& b) +{ + return _mm_cmple_ps(a, b); +} + +FORCEINLINE bool IsAllGreaterThan(const fltx4& a, const fltx4& b) +{ + return TestSignSIMD(CmpLeSIMD(a, b)) == 0; +} + +FORCEINLINE bool IsAllGreaterThanOrEq(const fltx4& a, const fltx4& b) +{ + return TestSignSIMD(CmpLtSIMD(a, b)) == 0; +} + +FORCEINLINE bool IsAllEqual(const fltx4& a, const fltx4& b) +{ + return TestSignSIMD(CmpEqSIMD(a, b)) == 0xf; +} + +FORCEINLINE fltx4 CmpInBoundsSIMD(const fltx4& a, const fltx4& b) +{ + return AndSIMD(CmpLeSIMD(a, b), CmpGeSIMD(a, NegSIMD(b))); +} + +FORCEINLINE fltx4 MinSIMD(const fltx4& a, const fltx4& b) +{ + return _mm_min_ps(a, b); +} + +FORCEINLINE fltx4 MaxSIMD(const fltx4& a, const fltx4& b) +{ + return _mm_max_ps(a, b); +} + + + +FORCEINLINE fltx4 CeilSIMD(const fltx4& a) +{ + fltx4 retVal; + SubFloat(retVal, 0) = ceil(SubFloat(a, 0)); + SubFloat(retVal, 1) = ceil(SubFloat(a, 1)); + SubFloat(retVal, 2) = ceil(SubFloat(a, 2)); + SubFloat(retVal, 3) = ceil(SubFloat(a, 3)); + return retVal; + +} + +fltx4 AbsSIMD(const fltx4& x); +fltx4 fabs(const fltx4& x); + +FORCEINLINE fltx4 FloorSIMD(const fltx4& val) +{ + fltx4 fl4Abs = fabs(val); + fltx4 ival = SubSIMD(AddSIMD(fl4Abs, Four_2ToThe23s), Four_2ToThe23s); + ival = MaskedAssign(CmpGtSIMD(ival, fl4Abs), SubSIMD(ival, Four_Ones), ival); + return XorSIMD(ival, XorSIMD(val, fl4Abs)); +} + + + +FORCEINLINE bool IsAnyZeros(const fltx4& a) +{ + return TestSignSIMD(CmpEqSIMD(a, Four_Zeros)) != 0; +} + +inline bool IsAllZeros(const fltx4& var) +{ + return TestSignSIMD(CmpEqSIMD(var, Four_Zeros)) == 0xF; +} + +FORCEINLINE fltx4 SqrtEstSIMD(const fltx4& a) +{ + return _mm_sqrt_ps(a); +} + +FORCEINLINE fltx4 SqrtSIMD(const fltx4& a) +{ + return _mm_sqrt_ps(a); +} + +FORCEINLINE fltx4 ReciprocalSqrtEstSIMD(const fltx4& a) +{ + return _mm_rsqrt_ps(a); +} + +FORCEINLINE fltx4 ReciprocalSqrtEstSaturateSIMD(const fltx4& a) +{ + fltx4 zero_mask = CmpEqSIMD(a, Four_Zeros); + fltx4 ret = OrSIMD(a, AndSIMD(Four_Epsilons, zero_mask)); + ret = ReciprocalSqrtEstSIMD(ret); + return ret; +} + +FORCEINLINE fltx4 ReciprocalSqrtSIMD(const fltx4& a) +{ + fltx4 guess = ReciprocalSqrtEstSIMD(a); + guess = MulSIMD(guess, SubSIMD(Four_Threes, MulSIMD(a, MulSIMD(guess, guess)))); + guess = MulSIMD(Four_PointFives, guess); + return guess; +} + +FORCEINLINE fltx4 ReciprocalEstSIMD(const fltx4& a) +{ + return _mm_rcp_ps(a); +} + +FORCEINLINE fltx4 ReciprocalEstSaturateSIMD(const fltx4& a) +{ + fltx4 zero_mask = CmpEqSIMD(a, Four_Zeros); + fltx4 ret = OrSIMD(a, AndSIMD(Four_Epsilons, zero_mask)); + ret = ReciprocalEstSIMD(ret); + return ret; +} + +FORCEINLINE fltx4 ReciprocalSIMD(const fltx4& a) +{ + fltx4 ret = ReciprocalEstSIMD(a); + ret = SubSIMD(AddSIMD(ret, ret), MulSIMD(a, MulSIMD(ret, ret))); + return ret; +} + +FORCEINLINE fltx4 ReciprocalSaturateSIMD(const fltx4& a) +{ + fltx4 zero_mask = CmpEqSIMD(a, Four_Zeros); + fltx4 ret = OrSIMD(a, AndSIMD(Four_Epsilons, zero_mask)); + ret = ReciprocalSIMD(ret); + return ret; +} + +FORCEINLINE fltx4 ExpSIMD(const fltx4& toPower) +{ + fltx4 retval; + SubFloat(retval, 0) = powf(2, SubFloat(toPower, 0)); + SubFloat(retval, 1) = powf(2, SubFloat(toPower, 1)); + SubFloat(retval, 2) = powf(2, SubFloat(toPower, 2)); + SubFloat(retval, 3) = powf(2, SubFloat(toPower, 3)); + + return retval; +} + +FORCEINLINE fltx4 ClampVectorSIMD(FLTX4 in, FLTX4 min, FLTX4 max) +{ + return MaxSIMD(min, MinSIMD(max, in)); +} + +FORCEINLINE void TransposeSIMD(fltx4& x, fltx4& y, fltx4& z, fltx4& w) +{ + _MM_TRANSPOSE4_PS(x, y, z, w); +} + +FORCEINLINE fltx4 FindLowestSIMD3(const fltx4& a) +{ + fltx4 compareOne = RotateLeft(a); + fltx4 retval = MinSIMD(a, compareOne); + compareOne = RotateLeft2(a); + retval = MinSIMD(retval, compareOne); + return SplatXSIMD(retval); + +} + +FORCEINLINE fltx4 FindHighestSIMD3(const fltx4& a) +{ + fltx4 compareOne = RotateLeft(a); + fltx4 retval = MaxSIMD(a, compareOne); + compareOne = RotateLeft2(a); + retval = MaxSIMD(retval, compareOne); + return SplatXSIMD(retval); + +} + + +inline bool IsVector3LessThan(const fltx4& v1, const fltx4& v2) +{ + bi32x4 isOut = CmpLtSIMD(v1, v2); + return IsAnyNegative(isOut); +} + +inline bool IsVector4LessThan(const fltx4& v1, const fltx4& v2) +{ + bi32x4 isOut = CmpLtSIMD(v1, v2); + return IsAnyNegative(isOut); +} + + + +#if 0 +FORCEINLINE fltx4 IntSetImmediateSIMD(int to) +{ + fltx4 retval; + SubInt(retval, 0) = to; + SubInt(retval, 1) = to; + SubInt(retval, 2) = to; + SubInt(retval, 3) = to; + return retval; +} +#endif + +FORCEINLINE i32x4 LoadAlignedIntSIMD(const void* RESTRICT pSIMD) +{ + return _mm_load_ps(reinterpret_cast(pSIMD)); +} + +FORCEINLINE i32x4 LoadUnalignedIntSIMD(const void* RESTRICT pSIMD) +{ + return _mm_loadu_ps(reinterpret_cast(pSIMD)); +} + +FORCEINLINE void StoreAlignedIntSIMD(int32* RESTRICT pSIMD, const fltx4& a) +{ + _mm_store_ps(reinterpret_cast(pSIMD), a); +} + +FORCEINLINE void StoreAlignedIntSIMD(intx4& pSIMD, const fltx4& a) +{ + _mm_store_ps(reinterpret_cast(pSIMD.Base()), a); +} + +FORCEINLINE void StoreUnalignedIntSIMD(int32* RESTRICT pSIMD, const fltx4& a) +{ + _mm_storeu_ps(reinterpret_cast(pSIMD), a); +} + +FORCEINLINE fltx4 CompressSIMD(fltx4 const& a, fltx4 const& b) +{ + return _mm_shuffle_ps(a, b, MM_SHUFFLE_REV(0, 2, 0, 2)); +} + +FORCEINLINE fltx4 LoadAndConvertUint16SIMD(const uint16* pInts) +{ +#ifdef POSIX + fltx4 retval; + SubFloat(retval, 0) = pInts[0]; + SubFloat(retval, 1) = pInts[1]; + SubFloat(retval, 2) = pInts[2]; + SubFloat(retval, 3) = pInts[3]; + return retval; +#else + __m128i inA = _mm_loadl_epi64((__m128i const*) pInts); + inA = _mm_unpacklo_epi16(inA, _mm_setzero_si128()); + return _mm_cvtepi32_ps(inA); +#endif +} + + +FORCEINLINE fltx4 Compress4SIMD(fltx4 const a, fltx4 const& b, fltx4 const& c, fltx4 const& d) +{ + fltx4 aacc = _mm_shuffle_ps(a, c, MM_SHUFFLE_REV(0, 0, 0, 0)); + fltx4 bbdd = _mm_shuffle_ps(b, d, MM_SHUFFLE_REV(0, 0, 0, 0)); + return MaskedAssign(LoadAlignedSIMD(g_SIMD_EveryOtherMask), bbdd, aacc); +} + +FORCEINLINE void ExpandSIMD(fltx4 const& a, fltx4& fl4OutA, fltx4& fl4OutB) +{ + fl4OutA = _mm_shuffle_ps(a, a, MM_SHUFFLE_REV(0, 0, 1, 1)); + fl4OutB = _mm_shuffle_ps(a, a, MM_SHUFFLE_REV(2, 2, 3, 3)); + +} + + +FORCEINLINE fltx4 LoadGatherSIMD(const float& x, const float& y, const float& z, const float& w) +{ + fltx4 vx = _mm_load_ss(&x); + fltx4 vy = _mm_load_ss(&y); + fltx4 vz = _mm_load_ss(&z); + fltx4 vw = _mm_load_ss(&w); + return Compress4SIMD(vx, vy, vz, vw); +} + +FORCEINLINE fltx4 UnsignedIntConvertToFltSIMD(const u32x4& vSrcA) +{ + fltx4 retval; + SubFloat(retval, 0) = ((float)SubInt(retval, 0)); + SubFloat(retval, 1) = ((float)SubInt(retval, 1)); + SubFloat(retval, 2) = ((float)SubInt(retval, 2)); + SubFloat(retval, 3) = ((float)SubInt(retval, 3)); + return retval; +} + +FORCEINLINE fltx4 SignedIntConvertToFltSIMD(const i32x4& vSrcA) +{ + return _mm_cvtepi32_ps((const __m128i&)vSrcA); +} + +FORCEINLINE fltx4 SignedIntConvertToFltSIMD(const shortx8& vSrcA) +{ + return _mm_cvtepi32_ps(vSrcA); +} + +#if 0 +FORCEINLINE fltx4 SignedIntConvertToFltSIMD(const i32x4& vSrcA) +{ + fltx4 retval; + SubFloat(retval, 0) = ((float)(reinterpret_cast(&vSrcA)[0])); + SubFloat(retval, 1) = ((float)(reinterpret_cast(&vSrcA)[1])); + SubFloat(retval, 2) = ((float)(reinterpret_cast(&vSrcA)[2])); + SubFloat(retval, 3) = ((float)(reinterpret_cast(&vSrcA)[3])); + return retval; +} + +#endif + +FORCEINLINE i32x4 IntShiftLeftWordSIMD(const i32x4& vSrcA, const i32x4& vSrcB) +{ + i32x4 retval; + SubInt(retval, 0) = SubInt(vSrcA, 0) << SubInt(vSrcB, 0); + SubInt(retval, 1) = SubInt(vSrcA, 1) << SubInt(vSrcB, 1); + SubInt(retval, 2) = SubInt(vSrcA, 2) << SubInt(vSrcB, 2); + SubInt(retval, 3) = SubInt(vSrcA, 3) << SubInt(vSrcB, 3); + + + return retval; +} + + +FORCEINLINE void ConvertStoreAsIntsSIMD(intx4* RESTRICT pDest, const fltx4& vSrc) +{ +#if defined(_MSC_VER) && _MSC_VER >= 1900 && defined(COMPILER_MSVC64) + (*pDest)[0] = (int)SubFloat(vSrc, 0); + (*pDest)[1] = (int)SubFloat(vSrc, 1); + (*pDest)[2] = (int)SubFloat(vSrc, 2); + (*pDest)[3] = (int)SubFloat(vSrc, 3); +#else + __m64 bottom = _mm_cvttps_pi32(vSrc); + __m64 top = _mm_cvttps_pi32(_mm_movehl_ps(vSrc, vSrc)); + + *reinterpret_cast<__m64*>(&(*pDest)[0]) = bottom; + *reinterpret_cast<__m64*>(&(*pDest)[2]) = top; + + _mm_empty(); +#endif +} + + + +#endif + +FORCEINLINE void RotateLeftDoubleSIMD(fltx4& a, fltx4& b) +{ + a = SetWSIMD(RotateLeft(a), SplatXSIMD(b)); + b = RotateLeft(b); +} + + +#if !defined(PLATFORM_PPC) && !defined( POSIX ) && !defined(SPU) +#if 1 +FORCEINLINE fltx4 operator+(FLTX4 a, FLTX4 b) +{ + return AddSIMD(a, b); +} + +FORCEINLINE fltx4 operator-(FLTX4 a, FLTX4 b) +{ + return SubSIMD(a, b); +} + +FORCEINLINE fltx4 operator*(FLTX4 a, FLTX4 b) +{ + return MulSIMD(a, b); +} + +FORCEINLINE fltx4 operator&(FLTX4 a, FLTX4 b) +{ + return AndSIMD(a, b); +} + +FORCEINLINE fltx4 operator|(FLTX4 a, FLTX4 b) +{ + return OrSIMD(a, b); +} + +FORCEINLINE fltx4 operator^(FLTX4 a, FLTX4 b) +{ + return XorSIMD(a, b); +} + +FORCEINLINE fltx4 operator-(FLTX4 a) +{ + return NegSIMD(a); +} +#endif +#endif + +#if defined(_X360) || defined(_PS3) +FORCEINLINE fltx4 VectorMergeHighSIMD(fltx4 fl4SrcA, fltx4 fl4SrcB) +{ +#if defined( _X360 ) + return __vmrghw(fl4SrcA, fl4SrcB); +#else + return vec_mergeh(fl4SrcA, fl4SrcB); +#endif +} + +FORCEINLINE fltx4 VectorMergeLowSIMD(fltx4 fl4SrcA, fltx4 fl4SrcB) +{ +#if defined( _X360 ) + return __vmrglw(fl4SrcA, fl4SrcB); +#else + return vec_mergel(fl4SrcA, fl4SrcB); +#endif +} +#endif + +#ifndef SPU +struct ALIGN16 fourplanes_t +{ + fltx4 nX; + fltx4 nY; + fltx4 nZ; + fltx4 dist; + bi32x4 xSign; + bi32x4 ySign; + bi32x4 zSign; + fltx4 nXAbs; + fltx4 nYAbs; + fltx4 nZAbs; + + void ComputeSignbits(); + + void Set4Planes(const VPlane* pPlanes); + void Set2Planes(const VPlane* pPlanes); + void Get4Planes(VPlane* pPlanesOut) const; + void Get2Planes(VPlane* pPlanesOut) const; + void GetPlane(int index, Vector* pNormal, float* pDist) const; + void SetPlane(int index, const Vector& vecNormal, float planeDist); +}; + + + +#endif + +class FourQuaternions; +class ALIGN16 FourVectors +{ +public: + fltx4 x, y, z; + + FourVectors(void) + { + } + + FourVectors(FourVectors const& src) + { + x = src.x; + y = src.y; + z = src.z; + } + + explicit FORCEINLINE FourVectors(float a) + { + fltx4 aReplicated = ReplicateX4(a); + x = y = z = aReplicated; + } + + FORCEINLINE void Init(void) + { + x = Four_Zeros; + y = Four_Zeros; + z = Four_Zeros; + } + + FORCEINLINE void Init(float flX, float flY, float flZ) + { + x = ReplicateX4(flX); + y = ReplicateX4(flY); + z = ReplicateX4(flZ); + } + + FORCEINLINE FourVectors(float flX, float flY, float flZ) + { + Init(flX, flY, flZ); + } + + FORCEINLINE void Init(fltx4 const& fl4X, fltx4 const& fl4Y, fltx4 const& fl4Z) + { + x = fl4X; + y = fl4Y; + z = fl4Z; + } + + FORCEINLINE FourVectors(fltx4 const& fl4X, fltx4 const& fl4Y, fltx4 const& fl4Z) + { + Init(fl4X, fl4Y, fl4Z); + } + + + + FORCEINLINE FourVectors(Vector const& a, Vector const& b, Vector const& c, Vector const& d) + { + LoadAndSwizzle(a, b, c, d); + } + + FORCEINLINE FourVectors(VectorAligned const& a, VectorAligned const& b, VectorAligned const& c, VectorAligned const& d) + { + LoadAndSwizzleAligned(a, b, c, d); + } + + FORCEINLINE FourVectors(const float* xs, const float* ys, const float* zs) : + x(LoadAlignedSIMD(xs)), y(LoadAlignedSIMD(ys)), z(LoadAlignedSIMD(zs)) + {}; + + FORCEINLINE void DuplicateVector(Vector const& v) + { + x = ReplicateX4(v.x); + y = ReplicateX4(v.y); + z = ReplicateX4(v.z); + } + + FORCEINLINE fltx4 const& operator[](int idx) const + { + return *((&x) + idx); + } + + FORCEINLINE fltx4& operator[](int idx) + { + return *((&x) + idx); + } + + FORCEINLINE void operator+=(FourVectors const& b) + { + x = AddSIMD(x, b.x); + y = AddSIMD(y, b.y); + z = AddSIMD(z, b.z); + } + + FORCEINLINE void operator-=(FourVectors const& b) + { + x = SubSIMD(x, b.x); + y = SubSIMD(y, b.y); + z = SubSIMD(z, b.z); + } + + FORCEINLINE void operator*=(FourVectors const& b) + { + x = MulSIMD(x, b.x); + y = MulSIMD(y, b.y); + z = MulSIMD(z, b.z); + } + + FORCEINLINE void operator*=(const fltx4& scale) + { + x = MulSIMD(x, scale); + y = MulSIMD(y, scale); + z = MulSIMD(z, scale); + } + + FORCEINLINE void operator*=(float scale) + { + fltx4 scalepacked = ReplicateX4(scale); + *this *= scalepacked; + } + + FORCEINLINE fltx4 operator*(FourVectors const& b) const + { + fltx4 dot = MulSIMD(x, b.x); + dot = MaddSIMD(y, b.y, dot); + dot = MaddSIMD(z, b.z, dot); + return dot; + } + + FORCEINLINE fltx4 operator*(Vector const& b) const + { + fltx4 dot = MulSIMD(x, ReplicateX4(b.x)); + dot = MaddSIMD(y, ReplicateX4(b.y), dot); + dot = MaddSIMD(z, ReplicateX4(b.z), dot); + return dot; + } + + FORCEINLINE FourVectors operator*(float b) const + { + fltx4 scalepacked = ReplicateX4(b); + FourVectors res; + res.x = MulSIMD(x, scalepacked); + res.y = MulSIMD(y, scalepacked); + res.z = MulSIMD(z, scalepacked); + return res; + } + + FORCEINLINE FourVectors operator*(FLTX4 fl4Scale) const + { + FourVectors res; + res.x = MulSIMD(x, fl4Scale); + res.y = MulSIMD(y, fl4Scale); + res.z = MulSIMD(z, fl4Scale); + return res; + } + + FORCEINLINE void VProduct(FourVectors const& b) + { + x = MulSIMD(x, b.x); + y = MulSIMD(y, b.y); + z = MulSIMD(z, b.z); + } + FORCEINLINE void MakeReciprocal(void) + { + x = ReciprocalSIMD(x); + y = ReciprocalSIMD(y); + z = ReciprocalSIMD(z); + } + + FORCEINLINE void MakeReciprocalSaturate(void) + { + x = ReciprocalSaturateSIMD(x); + y = ReciprocalSaturateSIMD(y); + z = ReciprocalSaturateSIMD(z); + } + + inline void RotateBy(const matrix3x4_t& matrix); + static void RotateManyBy(FourVectors* RESTRICT pVectors, unsigned int numVectors, const matrix3x4_t& rotationMatrix); + + static void RotateManyBy(FourVectors* RESTRICT pVectors, unsigned int numVectors, const matrix3x4_t& rotationMatrix, FourVectors* RESTRICT pOut); + + inline void TransformBy(const matrix3x4_t& matrix); + + static void TransformManyBy(FourVectors* RESTRICT pVectors, unsigned int numVectors, const matrix3x4_t& rotationMatrix, FourVectors* RESTRICT pOut); + + static void TransformManyBy(FourVectors* RESTRICT pVectors, unsigned int numVectors, const matrix3x4_t& rotationMatrix); + + static void CalcClosestPointOnLineSIMD(const FourVectors& P, const FourVectors& vLineA, const FourVectors& vLineB, FourVectors& vClosest, fltx4* outT = 0); + static fltx4 CalcClosestPointToLineTSIMD(const FourVectors& P, const FourVectors& vLineA, const FourVectors& vLineB, FourVectors& vDir); + + FORCEINLINE const float& X(int idx) const + { + return SubFloat((fltx4&)x, idx); + } + + FORCEINLINE const float& Y(int idx) const + { + return SubFloat((fltx4&)y, idx); + } + + FORCEINLINE const float& Z(int idx) const + { + return SubFloat((fltx4&)z, idx); + } + + FORCEINLINE float& X(int idx) + { + return SubFloat(x, idx); + } + + FORCEINLINE float& Y(int idx) + { + return SubFloat(y, idx); + } + + FORCEINLINE float& Z(int idx) + { + return SubFloat(z, idx); + } + + FORCEINLINE Vector Vec(int idx) const + { + return Vector(X(idx), Y(idx), Z(idx)); + } + + FORCEINLINE void operator=(FourVectors const& src) + { + x = src.x; + y = src.y; + z = src.z; + } + + FORCEINLINE void LoadAndSwizzle(Vector const& a, Vector const& b, Vector const& c, Vector const& d) + { +#if defined( _X360 ) || defined(_PS3) + fltx4 tx = LoadUnalignedSIMD(&a.x); + fltx4 ty = LoadUnalignedSIMD(&b.x); + fltx4 tz = LoadUnalignedSIMD(&c.x); + fltx4 tw = LoadUnalignedSIMD(&d.x); + fltx4 r0 = VectorMergeHighSIMD(tx, tz); + fltx4 r1 = VectorMergeHighSIMD(ty, tw); + fltx4 r2 = VectorMergeLowSIMD(tx, tz); + fltx4 r3 = VectorMergeLowSIMD(ty, tw); + + x = VectorMergeHighSIMD(r0, r1); + y = VectorMergeLowSIMD(r0, r1); + z = VectorMergeHighSIMD(r2, r3); +#else + x = LoadUnalignedSIMD(&(a.x)); + y = LoadUnalignedSIMD(&(b.x)); + z = LoadUnalignedSIMD(&(c.x)); + fltx4 w = LoadUnalignedSIMD(&(d.x)); + TransposeSIMD(x, y, z, w); +#endif + } + + FORCEINLINE void LoadAndSwizzle(Vector const& a) + { + LoadAndSwizzle(a, a, a, a); + } + + FORCEINLINE void Load(const float& a, const float& b, const float& c, const float& d) + { +#if defined( _X360 ) || defined( _PS3 ) + fltx4 temp[4]; + temp[0] = LoadUnalignedFloatSIMD(&a); + temp[1] = LoadUnalignedFloatSIMD(&b); + temp[2] = LoadUnalignedFloatSIMD(&c); + temp[3] = LoadUnalignedFloatSIMD(&d); + y = VectorMergeHighSIMD(temp[0], temp[2]); + z = VectorMergeHighSIMD(temp[1], temp[3]); + + x = VectorMergeHighSIMD(y, z); + y = x; + z = x; +#else + ALIGN16 float temp[4]; + temp[0] = a; temp[1] = b; temp[2] = c; temp[3] = d; + fltx4 v = LoadAlignedSIMD(temp); + x = v; + y = v; + z = v; +#endif + } + + FORCEINLINE void LoadAndSwizzle(FLTX4 a, FLTX4 b, FLTX4 c, FLTX4 d) + { +#if defined( _X360 ) || defined( _PS3 ) + fltx4 tx = a; + fltx4 ty = b; + fltx4 tz = c; + fltx4 tw = d; + fltx4 r0 = VectorMergeHighSIMD(tx, tz); + fltx4 r1 = VectorMergeHighSIMD(ty, tw); + fltx4 r2 = VectorMergeLowSIMD(tx, tz); + fltx4 r3 = VectorMergeLowSIMD(ty, tw); + + x = VectorMergeHighSIMD(r0, r1); + y = VectorMergeLowSIMD(r0, r1); + z = VectorMergeHighSIMD(r2, r3); +#else + x = a; + y = b; + z = c; + fltx4 w = d; + TransposeSIMD(x, y, z, w); +#endif + } + + FORCEINLINE void LoadAndSwizzleAligned(const float* RESTRICT a, const float* RESTRICT b, const float* RESTRICT c, const float* RESTRICT d) + { +#if defined( _X360 ) || defined( _PS3 ) + fltx4 tx = LoadAlignedSIMD(a); + fltx4 ty = LoadAlignedSIMD(b); + fltx4 tz = LoadAlignedSIMD(c); + fltx4 tw = LoadAlignedSIMD(d); + fltx4 r0 = VectorMergeHighSIMD(tx, tz); + fltx4 r1 = VectorMergeHighSIMD(ty, tw); + fltx4 r2 = VectorMergeLowSIMD(tx, tz); + fltx4 r3 = VectorMergeLowSIMD(ty, tw); + + x = VectorMergeHighSIMD(r0, r1); + y = VectorMergeLowSIMD(r0, r1); + z = VectorMergeHighSIMD(r2, r3); +#else + x = LoadAlignedSIMD(a); + y = LoadAlignedSIMD(b); + z = LoadAlignedSIMD(c); + fltx4 w = LoadAlignedSIMD(d); + TransposeSIMD(x, y, z, w); +#endif + } + + FORCEINLINE void LoadAndSwizzleAligned(Vector const& a, Vector const& b, Vector const& c, Vector const& d) + { + LoadAndSwizzleAligned(&a.x, &b.x, &c.x, &d.x); + } + + FORCEINLINE void TransposeOnto(fltx4& out0, fltx4& out1, fltx4& out2, fltx4& out3, FLTX4 w = Four_Zeros) const + { +#if defined( _X360 ) || defined(_PS3) + fltx4 r0 = VectorMergeHighSIMD(x, z); + fltx4 r1 = VectorMergeHighSIMD(y, w); + fltx4 r2 = VectorMergeLowSIMD(x, z); + fltx4 r3 = VectorMergeLowSIMD(y, w); + + out0 = VectorMergeHighSIMD(r0, r1); + out1 = VectorMergeLowSIMD(r0, r1); + out2 = VectorMergeHighSIMD(r2, r3); + out3 = VectorMergeLowSIMD(r2, r3); +#else + out0 = x; + out1 = y; + out2 = z; + out3 = w; + + TransposeSIMD(out0, out1, out2, out3); +#endif + } + +#if !defined(__SPU__) + FORCEINLINE void StoreUnalignedVector3SIMD(Vector* RESTRICT out0, Vector* RESTRICT out1, Vector* RESTRICT out2, Vector* RESTRICT out3) const; +#endif + + FORCEINLINE void StoreAlignedVectorSIMD(VectorAligned* RESTRICT out0, VectorAligned* RESTRICT out1, VectorAligned* RESTRICT out2, VectorAligned* RESTRICT out3) const; + +#if !defined(__SPU__) + FORCEINLINE void StoreUnalignedContigVector3SIMD(Vector* RESTRICT pDestination) + { + fltx4 a, b, c, d; + TransposeOnto(a, b, c, d); + StoreFourUnalignedVector3SIMD(a, b, c, d, pDestination); + } +#endif + +#if !defined(__SPU__) + FORCEINLINE void StoreAlignedContigVector3SIMD(Vector* RESTRICT pDestination) + { + fltx4 a, b, c, d; + TransposeOnto(a, b, c, d); + StoreFourAlignedVector3SIMD(a, b, c, d, pDestination); + } + + FORCEINLINE void StoreAlignedContigVectorASIMD(VectorAligned* RESTRICT pDestination) + { + StoreAlignedVectorSIMD(pDestination, pDestination + 1, pDestination + 2, pDestination + 3); + } +#endif + + FORCEINLINE fltx4 LengthSqr(void) const + { + const FourVectors& a = *this; + return a * a; + } + + FORCEINLINE fltx4 length2(void) const + { + return (*this) * (*this); + } + + FORCEINLINE fltx4 length(void) const + { + return SqrtEstSIMD(length2()); + } + + FORCEINLINE fltx4 Length(void) const + { + return SqrtSIMD(length2()); + } + + + FORCEINLINE void VectorNormalizeFast(void) + { + fltx4 mag_sq = (*this) * (*this); + (*this) *= ReciprocalSqrtEstSIMD(mag_sq); + } + + FORCEINLINE void VectorNormalize(void) + { + fltx4 mag_sq = (*this) * (*this); + (*this) *= ReciprocalSqrtSIMD(mag_sq); + } + + FORCEINLINE fltx4 DistToSqr(FourVectors const& pnt) + { + fltx4 fl4dX = SubSIMD(pnt.x, x); + fltx4 fl4dY = SubSIMD(pnt.y, y); + fltx4 fl4dZ = SubSIMD(pnt.z, z); + return AddSIMD(MulSIMD(fl4dX, fl4dX), AddSIMD(MulSIMD(fl4dY, fl4dY), MulSIMD(fl4dZ, fl4dZ))); + + } + + FORCEINLINE fltx4 TValueOfClosestPointOnLine(FourVectors const& p0, FourVectors const& p1) const + { + FourVectors lineDelta = p1; + lineDelta -= p0; + fltx4 OOlineDirDotlineDir = ReciprocalSIMD(p1 * p1); + FourVectors v4OurPnt = *this; + v4OurPnt -= p0; + return MulSIMD(OOlineDirDotlineDir, v4OurPnt * lineDelta); + } + + FORCEINLINE fltx4 DistSqrToLineSegment(FourVectors const& p0, FourVectors const& p1) const + { + FourVectors lineDelta = p1; + FourVectors v4OurPnt = *this; + v4OurPnt -= p0; + lineDelta -= p0; + + fltx4 OOlineDirDotlineDir = ReciprocalSIMD(lineDelta * lineDelta); + + fltx4 fl4T = MulSIMD(OOlineDirDotlineDir, v4OurPnt * lineDelta); + + fl4T = MinSIMD(fl4T, Four_Ones); + fl4T = MaxSIMD(fl4T, Four_Zeros); + lineDelta *= fl4T; + return v4OurPnt.DistToSqr(lineDelta); + } + FORCEINLINE FourVectors Normalized()const + { + fltx4 fl4LengthInv = ReciprocalSqrtSIMD(LengthSqr()); + FourVectors out; + out.x = x * fl4LengthInv; + out.y = y * fl4LengthInv; + out.z = z * fl4LengthInv; + return out; + } + + FORCEINLINE FourVectors NormalizedSafeX() const + { + fltx4 f4LenSqr = LengthSqr(); + fltx4 isBigEnough = CmpGeSIMD(f4LenSqr, Four_Epsilons); + fltx4 fl4LengthInv = ReciprocalSqrtSIMD(f4LenSqr); + FourVectors out; + out.x = MaskedAssign(isBigEnough, x * fl4LengthInv, Four_Ones); + out.y = AndSIMD(y * fl4LengthInv, isBigEnough); + out.z = AndSIMD(z * fl4LengthInv, isBigEnough); + return out; + } + FORCEINLINE FourVectors NormalizedSafeY() const + { + fltx4 f4LenSqr = LengthSqr(); + fltx4 isBigEnough = CmpGeSIMD(f4LenSqr, Four_Epsilons); + fltx4 fl4LengthInv = ReciprocalSqrtSIMD(f4LenSqr); + FourVectors out; + out.x = AndSIMD(x * fl4LengthInv, isBigEnough); + out.y = MaskedAssign(isBigEnough, y * fl4LengthInv, Four_Ones); + out.z = AndSIMD(z * fl4LengthInv, isBigEnough); + return out; + } + + FORCEINLINE FourVectors NormalizedSafeZ() const + { + fltx4 f4LenSqr = LengthSqr(); + fltx4 isBigEnough = CmpGeSIMD(f4LenSqr, Four_Epsilons); + fltx4 fl4LengthInv = ReciprocalSqrtSIMD(f4LenSqr); + FourVectors out; + out.x = AndSIMD(x * fl4LengthInv, isBigEnough); + out.y = AndSIMD(y * fl4LengthInv, isBigEnough); + out.z = MaskedAssign(isBigEnough, z * fl4LengthInv, Four_Ones); + return out; + } +}; + + +inline FourVectors CrossProduct(const FourVectors& a, const FourVectors& b) +{ + return FourVectors(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x); +} + +inline fltx4 DotProduct(const FourVectors& a, const FourVectors& b) +{ + return a.x * b.x + a.y * b.y + a.z * b.z; +} + +inline FourVectors operator * (fltx4 left, const FourVectors& right) +{ + return right * left; +} + + +inline FourVectors Mul(const FourVectors& a, const fltx4& b) +{ + FourVectors ret; + ret.x = MulSIMD(a.x, b); + ret.y = MulSIMD(a.y, b); + ret.z = MulSIMD(a.z, b); + return ret; +} + +inline FourVectors Mul(const FourVectors& a, const FourVectors& b) +{ + FourVectors ret; + ret.x = MulSIMD(a.x, b.x); + ret.y = MulSIMD(a.y, b.y); + ret.z = MulSIMD(a.z, b.z); + return ret; +} + +inline FourVectors Madd(const FourVectors& a, const fltx4& b, const FourVectors& c) +{ + FourVectors ret; + ret.x = MaddSIMD(a.x, b, c.x); + ret.y = MaddSIMD(a.y, b, c.y); + ret.z = MaddSIMD(a.z, b, c.z); + return ret; +} + +inline FourVectors operator ^(const FourVectors& a, const FourVectors& b) +{ + FourVectors ret; + ret.x = SubSIMD(MulSIMD(a.y, b.z), MulSIMD(a.z, b.y)); + ret.y = SubSIMD(MulSIMD(a.z, b.x), MulSIMD(a.x, b.z)); + ret.z = SubSIMD(MulSIMD(a.x, b.y), MulSIMD(a.y, b.x)); + return ret; +} + +inline FourVectors operator-(const FourVectors& a, const FourVectors& b) +{ + FourVectors ret; + ret.x = SubSIMD(a.x, b.x); + ret.y = SubSIMD(a.y, b.y); + ret.z = SubSIMD(a.z, b.z); + return ret; +} + +inline FourVectors operator+(const FourVectors& a, const FourVectors& b) +{ + FourVectors ret; + ret.x = AddSIMD(a.x, b.x); + ret.y = AddSIMD(a.y, b.y); + ret.z = AddSIMD(a.z, b.z); + return ret; +} + +inline FourVectors maximum(const FourVectors& a, const FourVectors& b) +{ + FourVectors ret; + ret.x = MaxSIMD(a.x, b.x); + ret.y = MaxSIMD(a.y, b.y); + ret.z = MaxSIMD(a.z, b.z); + return ret; +} + +inline FourVectors minimum(const FourVectors& a, const FourVectors& b) +{ + FourVectors ret; + ret.x = MinSIMD(a.x, b.x); + ret.y = MinSIMD(a.y, b.y); + ret.z = MinSIMD(a.z, b.z); + return ret; +} + +FORCEINLINE FourVectors RotateLeft(const FourVectors& src) +{ + FourVectors ret; + ret.x = RotateLeft(src.x); + ret.y = RotateLeft(src.y); + ret.z = RotateLeft(src.z); + return ret; +} + +FORCEINLINE FourVectors RotateRight(const FourVectors& src) +{ + FourVectors ret; + ret.x = RotateRight(src.x); + ret.y = RotateRight(src.y); + ret.z = RotateRight(src.z); + return ret; +} +FORCEINLINE FourVectors MaskedAssign(const bi32x4& ReplacementMask, const FourVectors& NewValue, const FourVectors& OldValue) +{ + FourVectors ret; + ret.x = MaskedAssign(ReplacementMask, NewValue.x, OldValue.x); + ret.y = MaskedAssign(ReplacementMask, NewValue.y, OldValue.y); + ret.z = MaskedAssign(ReplacementMask, NewValue.z, OldValue.z); + return ret; +} + +FORCEINLINE FourVectors VectorReflect(const FourVectors& incident, const FourVectors& normal) +{ + FourVectors ret = incident; + fltx4 iDotNx2 = incident * normal; + iDotNx2 = AddSIMD(iDotNx2, iDotNx2); + FourVectors nPart = normal; + nPart *= iDotNx2; + ret -= nPart; + return ret; +} + +FORCEINLINE FourVectors VectorSlide(const FourVectors& incident, const FourVectors& normal) +{ + FourVectors ret = incident; + fltx4 iDotN = incident * normal; + FourVectors nPart = normal; + nPart *= iDotN; + ret -= nPart; + return ret; +} + +FORCEINLINE FourVectors VectorNormalizeFast(const FourVectors& src) +{ + fltx4 mag_sq = ReciprocalSqrtEstSIMD(src * src); + FourVectors result; + result.x = MulSIMD(src.x, mag_sq); + result.y = MulSIMD(src.y, mag_sq); + result.z = MulSIMD(src.z, mag_sq); + return result; +} + +#if !defined(__SPU__) +FORCEINLINE void FourVectors::StoreUnalignedVector3SIMD(Vector* RESTRICT out0, Vector* RESTRICT out1, Vector* RESTRICT out2, Vector* RESTRICT out3) const +{ +#ifdef _X360 + fltx4 x0, x1, x2, x3, y0, y1, y2, y3, z0, z1, z2, z3; + x0 = SplatXSIMD(x); + x1 = SplatYSIMD(x); + x2 = SplatZSIMD(x); + x3 = SplatWSIMD(x); + + y0 = SplatXSIMD(y); + y1 = SplatYSIMD(y); + y2 = SplatZSIMD(y); + y3 = SplatWSIMD(y); + + z0 = SplatXSIMD(z); + z1 = SplatYSIMD(z); + z2 = SplatZSIMD(z); + z3 = SplatWSIMD(z); + + __stvewx(x0, out0->Base(), 0); + __stvewx(y0, out0->Base(), 4); + __stvewx(z0, out0->Base(), 8); + + __stvewx(x1, out1->Base(), 0); + __stvewx(y1, out1->Base(), 4); + __stvewx(z1, out1->Base(), 8); + + __stvewx(x2, out2->Base(), 0); + __stvewx(y2, out2->Base(), 4); + __stvewx(z2, out2->Base(), 8); + + __stvewx(x3, out3->Base(), 0); + __stvewx(y3, out3->Base(), 4); + __stvewx(z3, out3->Base(), 8); +#else + fltx4 a, b, c, d; + TransposeOnto(a, b, c, d); + StoreUnaligned3SIMD(out0->Base(), a); + StoreUnaligned3SIMD(out1->Base(), b); + StoreUnaligned3SIMD(out2->Base(), c); + StoreUnaligned3SIMD(out3->Base(), d); +#endif +} + +FORCEINLINE void FourVectors::StoreAlignedVectorSIMD(VectorAligned* RESTRICT out0, VectorAligned* RESTRICT out1, VectorAligned* RESTRICT out2, VectorAligned* RESTRICT out3) const +{ + fltx4 a, b, c, d; + TransposeOnto(a, b, c, d); + StoreAligned3SIMD(out0, a); + StoreAligned3SIMD(out1, b); + StoreAligned3SIMD(out2, c); + StoreAligned3SIMD(out3, d); + +} +#endif + +#if !defined(__SPU__) +void FourVectors::RotateBy(const matrix3x4_t& matrix) +{ + fltx4 matSplat00, matSplat01, matSplat02, + matSplat10, matSplat11, matSplat12, + matSplat20, matSplat21, matSplat22; + + fltx4 matCol0 = LoadUnalignedSIMD(matrix[0]); + fltx4 matCol1 = LoadUnalignedSIMD(matrix[1]); + fltx4 matCol2 = LoadUnalignedSIMD(matrix[2]); + + matSplat00 = SplatXSIMD(matCol0); + matSplat01 = SplatYSIMD(matCol0); + matSplat02 = SplatZSIMD(matCol0); + + matSplat10 = SplatXSIMD(matCol1); + matSplat11 = SplatYSIMD(matCol1); + matSplat12 = SplatZSIMD(matCol1); + + matSplat20 = SplatXSIMD(matCol2); + matSplat21 = SplatYSIMD(matCol2); + matSplat22 = SplatZSIMD(matCol2); + + fltx4 outX, outY, outZ; + outX = AddSIMD(AddSIMD(MulSIMD(x, matSplat00), MulSIMD(y, matSplat01)), MulSIMD(z, matSplat02)); + outY = AddSIMD(AddSIMD(MulSIMD(x, matSplat10), MulSIMD(y, matSplat11)), MulSIMD(z, matSplat12)); + outZ = AddSIMD(AddSIMD(MulSIMD(x, matSplat20), MulSIMD(y, matSplat21)), MulSIMD(z, matSplat22)); + + x = outX; + y = outY; + z = outZ; +} + + +void FourVectors::TransformBy(const matrix3x4_t& matrix) +{ + fltx4 matSplat00, matSplat01, matSplat02, + matSplat10, matSplat11, matSplat12, + matSplat20, matSplat21, matSplat22; + + fltx4 matCol0 = LoadUnalignedSIMD(matrix[0]); + fltx4 matCol1 = LoadUnalignedSIMD(matrix[1]); + fltx4 matCol2 = LoadUnalignedSIMD(matrix[2]); + + matSplat00 = SplatXSIMD(matCol0); + matSplat01 = SplatYSIMD(matCol0); + matSplat02 = SplatZSIMD(matCol0); + + matSplat10 = SplatXSIMD(matCol1); + matSplat11 = SplatYSIMD(matCol1); + matSplat12 = SplatZSIMD(matCol1); + + matSplat20 = SplatXSIMD(matCol2); + matSplat21 = SplatYSIMD(matCol2); + matSplat22 = SplatZSIMD(matCol2); + + fltx4 outX, outY, outZ; + + outX = MaddSIMD(z, matSplat02, AddSIMD(MulSIMD(x, matSplat00), MulSIMD(y, matSplat01))); + outY = MaddSIMD(z, matSplat12, AddSIMD(MulSIMD(x, matSplat10), MulSIMD(y, matSplat11))); + outZ = MaddSIMD(z, matSplat22, AddSIMD(MulSIMD(x, matSplat20), MulSIMD(y, matSplat21))); + + x = AddSIMD(outX, ReplicateX4(matrix[0][3])); + y = AddSIMD(outY, ReplicateX4(matrix[1][3])); + z = AddSIMD(outZ, ReplicateX4(matrix[2][3])); +} +#endif + +fltx4 NoiseSIMD(FourVectors const& v); + +FourVectors DNoiseSIMD(FourVectors const& v); + +FourVectors CurlNoiseSIMD(FourVectors const& v); + + +fltx4 NoiseSIMD(const fltx4& x, const fltx4& y, const fltx4& z); + + +inline fltx4 fabs(const fltx4& x) +{ + return AndSIMD(x, LoadAlignedSIMD(g_SIMD_clear_signmask)); +} + +inline fltx4 AbsSIMD(const fltx4& x) +{ + return fabs(x); +} + +inline fltx4 fnegate(const fltx4& x) +{ + return XorSIMD(x, LoadAlignedSIMD(g_SIMD_signmask)); +} + +fltx4 Pow_FixedPoint_Exponent_SIMD(const fltx4& x, int exponent); + +inline fltx4 PowSIMD(const fltx4& x, float exponent) +{ + return Pow_FixedPoint_Exponent_SIMD(x, (int)(4.0 * exponent)); +} + +inline fltx4 LinearToGammaSIMD(fltx4 x) +{ + x = MaxSIMD(MinSIMD(Four_Ones, x), Four_Zeros); + return AddSIMD(Four_LinearToGammaCoefficients_E, + MulSIMD(x, AddSIMD(Four_LinearToGammaCoefficients_D, + MulSIMD(x, AddSIMD(Four_LinearToGammaCoefficients_C, + MulSIMD(x, AddSIMD(Four_LinearToGammaCoefficients_B, + MulSIMD(x, Four_LinearToGammaCoefficients_A)))))))); +} + + +inline fltx4 GammaToLinearSIMD(fltx4 x) +{ + x = MaxSIMD(x, Four_Zeros); + x = AddSIMD(Four_GammaToLinearCoefficients_D, + MulSIMD(x, AddSIMD(Four_GammaToLinearCoefficients_C, + MulSIMD(x, AddSIMD(Four_GammaToLinearCoefficients_B, + MulSIMD(x, Four_GammaToLinearCoefficients_A)))))); + return MinSIMD(x, Four_Ones); +} + +inline fltx4 GammaToLinearExtendedSIMD(fltx4 x) +{ + x = MaxSIMD(x, Four_Zeros); + fltx4 fl4Ret = AddSIMD(Four_GammaToLinearCoefficients_D, + MulSIMD(x, AddSIMD(Four_GammaToLinearCoefficients_C, + MulSIMD(x, AddSIMD(Four_GammaToLinearCoefficients_B, + MulSIMD(x, Four_GammaToLinearCoefficients_A)))))); + return MaskedAssign(CmpGeSIMD(x, Four_Ones), x, fl4Ret); +} + +void SeedRandSIMD(uint32 seed); +fltx4 RandSIMD(int nContext = 0); + +int GetSIMDRandContext(void); +void ReleaseSIMDRandContext(int nContext); + +FORCEINLINE fltx4 RandSignedSIMD(void) +{ + return SubSIMD(MulSIMD(Four_Twos, RandSIMD()), Four_Ones); +} + + +FORCEINLINE fltx4 LerpSIMD(const fltx4& percent, const fltx4& a, const fltx4& b) +{ + return AddSIMD(a, MulSIMD(SubSIMD(b, a), percent)); +} + +FORCEINLINE fltx4 RemapValClampedSIMD(const fltx4& val, const fltx4& a, const fltx4& b, const fltx4& c, const fltx4& d) +{ + fltx4 range = MaskedAssign(CmpEqSIMD(a, b), Four_Ones, SubSIMD(b, a)); + fltx4 cVal = MaxSIMD(Four_Zeros, MinSIMD(Four_Ones, DivSIMD(SubSIMD(val, a), range))); + return LerpSIMD(cVal, c, d); +} + +inline fltx4 SimpleSpline(const fltx4& value) +{ + fltx4 valueDoubled = MulSIMD(value, Four_Twos); + fltx4 valueSquared = MulSIMD(value, value); + + return SubSIMD( + MulSIMD(Four_Threes, valueSquared), + MulSIMD(valueDoubled, valueSquared)); +} + +inline fltx4 SimpleSplineRemapValWithDeltas(const fltx4& val, + const fltx4& A, const fltx4& BMinusA, + const fltx4& OneOverBMinusA, const fltx4& C, + const fltx4& DMinusC) +{ + fltx4 cVal = MulSIMD(SubSIMD(val, A), OneOverBMinusA); + return AddSIMD(C, MulSIMD(DMinusC, SimpleSpline(cVal))); +} + +inline fltx4 SimpleSplineRemapValWithDeltasClamped(const fltx4& val, + const fltx4& A, const fltx4& BMinusA, + const fltx4& OneOverBMinusA, const fltx4& C, + const fltx4& DMinusC) +{ + fltx4 cVal = MulSIMD(SubSIMD(val, A), OneOverBMinusA); + cVal = MinSIMD(Four_Ones, MaxSIMD(Four_Zeros, cVal)); + return AddSIMD(C, MulSIMD(DMinusC, SimpleSpline(cVal))); +} + +FORCEINLINE fltx4 FracSIMD(const fltx4& val) +{ + fltx4 fl4Abs = fabs(val); + fltx4 ival = SubSIMD(AddSIMD(fl4Abs, Four_2ToThe23s), Four_2ToThe23s); + ival = MaskedAssign(CmpGtSIMD(ival, fl4Abs), SubSIMD(ival, Four_Ones), ival); + return XorSIMD(SubSIMD(fl4Abs, ival), XorSIMD(val, fl4Abs)); +} + +#ifndef SPU +FORCEINLINE fltx4 Mod2SIMD(const fltx4& val) +{ + fltx4 fl4Abs = fabs(val); + fltx4 ival = SubSIMD(AndSIMD(LoadAlignedSIMD((float*)g_SIMD_lsbmask), AddSIMD(fl4Abs, Four_2ToThe23s)), Four_2ToThe23s); + ival = MaskedAssign(CmpGtSIMD(ival, fl4Abs), SubSIMD(ival, Four_Twos), ival); + return XorSIMD(SubSIMD(fl4Abs, ival), XorSIMD(val, fl4Abs)); +} +#endif + +FORCEINLINE fltx4 Mod2SIMDPositiveInput(const fltx4& val) +{ + fltx4 ival = SubSIMD(AndSIMD(LoadAlignedSIMD(g_SIMD_lsbmask), AddSIMD(val, Four_2ToThe23s)), Four_2ToThe23s); + ival = MaskedAssign(CmpGtSIMD(ival, val), SubSIMD(ival, Four_Twos), ival); + return SubSIMD(val, ival); +} + + +FORCEINLINE fltx4 _SinEst01SIMD(const fltx4& val) +{ + return MulSIMD(val, SubSIMD(Four_Fours, MulSIMD(val, Four_Fours))); +} + +FORCEINLINE fltx4 _Sin01SIMD(const fltx4& val) +{ + fltx4 fl4BadEst = MulSIMD(val, SubSIMD(Four_Fours, MulSIMD(val, Four_Fours))); + return AddSIMD(MulSIMD(Four_Point225s, SubSIMD(MulSIMD(fl4BadEst, fl4BadEst), fl4BadEst)), fl4BadEst); +} + +FORCEINLINE fltx4 SinEst01SIMD(const fltx4& val) +{ + fltx4 fl4Abs = fabs(val); + fltx4 fl4Reduced2 = Mod2SIMDPositiveInput(fl4Abs); + bi32x4 fl4OddMask = CmpGeSIMD(fl4Reduced2, Four_Ones); + fltx4 fl4val = SubSIMD(fl4Reduced2, AndSIMD(Four_Ones, fl4OddMask)); + fltx4 fl4Sin = _SinEst01SIMD(fl4val); + fl4Sin = XorSIMD(fl4Sin, AndSIMD(LoadAlignedSIMD(g_SIMD_signmask), XorSIMD(val, fl4OddMask))); + return fl4Sin; + +} + +FORCEINLINE fltx4 Sin01SIMD(const fltx4& val) +{ + fltx4 fl4Abs = fabs(val); + fltx4 fl4Reduced2 = Mod2SIMDPositiveInput(fl4Abs); + bi32x4 fl4OddMask = CmpGeSIMD(fl4Reduced2, Four_Ones); + fltx4 fl4val = SubSIMD(fl4Reduced2, AndSIMD(Four_Ones, fl4OddMask)); + fltx4 fl4Sin = _Sin01SIMD(fl4val); + fl4Sin = XorSIMD(fl4Sin, AndSIMD(LoadAlignedSIMD(g_SIMD_signmask), XorSIMD(val, fl4OddMask))); + return fl4Sin; + +} + +FORCEINLINE fltx4 NatExpSIMD(const fltx4& val) +{ + fltx4 fl4Result; + SubFloat(fl4Result, 0) = exp(SubFloat(val, 0)); + SubFloat(fl4Result, 1) = exp(SubFloat(val, 1)); + SubFloat(fl4Result, 2) = exp(SubFloat(val, 2)); + SubFloat(fl4Result, 3) = exp(SubFloat(val, 3)); + return fl4Result; +} + +FORCEINLINE fltx4 PreCalcBiasParameter(const fltx4& bias_parameter) +{ + return SubSIMD(ReciprocalSIMD(bias_parameter), Four_Twos); +} + +FORCEINLINE fltx4 BiasSIMD(const fltx4& val, const fltx4& precalc_param) +{ + return DivSIMD(val, AddSIMD(MulSIMD(precalc_param, SubSIMD(Four_Ones, val)), Four_Ones)); +} + +#ifndef SPU +FORCEINLINE int BoxOnPlaneSideSIMD(const fltx4& emins, const fltx4& emaxs, const cplane_t* p, float tolerance = 0.f) +{ + fltx4 corners[2]; + fltx4 normal = LoadUnalignedSIMD(p->normal.Base()); + fltx4 dist = ReplicateX4(-p->dist); + normal = SetWSIMD(normal, dist); + fltx4 t4 = ReplicateX4(tolerance); + fltx4 negt4 = ReplicateX4(-tolerance); + bi32x4 cmp = CmpGeSIMD(normal, Four_Zeros); + corners[0] = MaskedAssign(cmp, emaxs, emins); + corners[1] = MaskedAssign(cmp, emins, emaxs); + fltx4 dot1 = Dot4SIMD(normal, corners[0]); + fltx4 dot2 = Dot4SIMD(normal, corners[1]); + cmp = CmpGeSIMD(dot1, t4); + bi32x4 cmp2 = CmpGtSIMD(negt4, dot2); + fltx4 result = MaskedAssign(cmp, Four_Ones, Four_Zeros); + fltx4 result2 = MaskedAssign(cmp2, Four_Twos, Four_Zeros); + result = AddSIMD(result, result2); + intx4 sides; + ConvertStoreAsIntsSIMD(&sides, result); + return sides[0]; +} + + +class KDop32_t +{ +public: + fltx4 m_Mins[4]; + fltx4 m_Maxes[4]; + + FORCEINLINE bool Intersects(KDop32_t const& other) const; + + FORCEINLINE void operator|=(KDop32_t const& other); + + FORCEINLINE bool IsEmpty(void) const; + + FORCEINLINE void Init(void) + { + for (int i = 0; i < ARRAYSIZE(m_Mins); i++) + { + m_Mins[i] = Four_FLT_MAX; + m_Maxes[i] = Four_Negative_FLT_MAX; + } + } + + void AddPointSet(Vector const* pPoints, int nPnts); + + void CreateFromPointSet(Vector const* pPoints, int nPnts); +}; + +FORCEINLINE void KDop32_t::operator|=(KDop32_t const& other) +{ + m_Mins[0] = MinSIMD(m_Mins[0], other.m_Mins[0]); + m_Mins[1] = MinSIMD(m_Mins[1], other.m_Mins[1]); + m_Mins[2] = MinSIMD(m_Mins[2], other.m_Mins[2]); + m_Mins[3] = MinSIMD(m_Mins[3], other.m_Mins[3]); + + m_Maxes[0] = MaxSIMD(m_Maxes[0], other.m_Maxes[0]); + m_Maxes[1] = MaxSIMD(m_Maxes[1], other.m_Maxes[1]); + m_Maxes[2] = MaxSIMD(m_Maxes[2], other.m_Maxes[2]); + m_Maxes[3] = MaxSIMD(m_Maxes[3], other.m_Maxes[3]); + + +} + +FORCEINLINE bool KDop32_t::Intersects(KDop32_t const& other) const +{ + bi32x4 c00 = CmpLeSIMD(m_Mins[0], other.m_Maxes[0]); + bi32x4 c01 = CmpLeSIMD(m_Mins[1], other.m_Maxes[1]); + bi32x4 c02 = CmpLeSIMD(m_Mins[2], other.m_Maxes[2]); + bi32x4 c03 = CmpLeSIMD(m_Mins[3], other.m_Maxes[3]); + + bi32x4 c10 = CmpGeSIMD(m_Maxes[0], other.m_Mins[0]); + bi32x4 c11 = CmpGeSIMD(m_Maxes[1], other.m_Mins[1]); + bi32x4 c12 = CmpGeSIMD(m_Maxes[2], other.m_Mins[2]); + bi32x4 c13 = CmpGeSIMD(m_Maxes[3], other.m_Mins[3]); + + bi32x4 a0 = AndSIMD(AndSIMD(c00, c01), AndSIMD(c02, c03)); + bi32x4 a1 = AndSIMD(AndSIMD(c10, c11), AndSIMD(c12, c13)); + + return !(IsAnyZeros(AndSIMD(a1, a0))); +} + + +FORCEINLINE bool KDop32_t::IsEmpty(void) const +{ + bi32x4 c00 = CmpLtSIMD(m_Maxes[0], m_Mins[0]); + bi32x4 c01 = CmpLtSIMD(m_Maxes[1], m_Mins[1]); + bi32x4 c02 = CmpLtSIMD(m_Maxes[2], m_Mins[2]); + bi32x4 c03 = CmpLtSIMD(m_Maxes[3], m_Mins[3]); + + return IsAnyTrue(OrSIMD(OrSIMD(c00, c01), OrSIMD(c02, c03))); +} + + +extern const fltx4 g_KDop32XDirs[4]; +extern const fltx4 g_KDop32YDirs[4]; +extern const fltx4 g_KDop32ZDirs[4]; +#endif + +#if 0 + +#define _VEC_SWIZZLE_QUAT48_UNPACK (__vector unsigned char) { 16, 17, 0, 1, 16, 17, 2, 3, 16, 17, 4, 5, 16, 17, 6, 7 } +#define _VEC_SWIZZLE_QUAT48_UNPACK_SHIFT (__vector unsigned int ) { 0, 0, 1, 0 } + +FORCEINLINE fltx4 UnpackQuaternion48SIMD(const Quaternion48* RESTRICT pVec) +{ + fltx4 q16s = LoadUnaligned3SIMD((const float*)pVec); + + bool wneg = pVec->wneg; + + q16s = vec_perm(q16s, Four_Threes, _VEC_SWIZZLE_QUAT48_UNPACK); + + u32x4 tmp = IntShiftLeftWordSIMD(*(u32x4*)&q16s, _VEC_SWIZZLE_QUAT48_UNPACK_SHIFT); + q16s = *(fltx4*)&tmp; + + const fltx4 vUpkMul = SplatXSIMD(g_SIMD_Quat48_Unpack_Magic_Constants); + const fltx4 vUpkAdd = SplatYSIMD(g_SIMD_Quat48_Unpack_Magic_Constants); + + fltx4 ret = vec_madd(q16s, vUpkMul, vUpkAdd); + + fltx4 dotxyz = Dot3SIMD(ret, ret); + dotxyz = ClampVectorSIMD(dotxyz, Four_Zeros, Four_Ones); + + fltx4 ww = SubSIMD(Four_Ones, dotxyz); + ww = SqrtSIMD(ww); + if (wneg) + { + ret = SetWSIMD(ret, NegSIMD(ww)); + } + else + { + ret = SetWSIMD(ret, ww); + } + return ret; +} + +#endif + +FORCEINLINE fltx4 SetWFromXSIMD(const fltx4& a, const fltx4& x) +{ + fltx4 value = SplatXSIMD(x); + return SetWSIMD(a, value); +} + +FORCEINLINE fltx4 SetWFromYSIMD(const fltx4& a, const fltx4& y) +{ + fltx4 value = SplatYSIMD(y); + return SetWSIMD(a, value); +} + +FORCEINLINE fltx4 SetWFromZSIMD(const fltx4& a, const fltx4& z) +{ + fltx4 value = SplatZSIMD(z); + return SetWSIMD(a, value); +} + +FORCEINLINE fltx4 CrossProductSIMD(const fltx4& A, const fltx4& B) +{ +#if defined( _X360 ) + return XMVector3Cross(A, B); +#elif defined( _WIN32 ) + fltx4 A1 = _mm_shuffle_ps(A, A, MM_SHUFFLE_REV(1, 2, 0, 3)); + fltx4 B1 = _mm_shuffle_ps(B, B, MM_SHUFFLE_REV(2, 0, 1, 3)); + fltx4 Result1 = MulSIMD(A1, B1); + fltx4 A2 = _mm_shuffle_ps(A, A, MM_SHUFFLE_REV(2, 0, 1, 3)); + fltx4 B2 = _mm_shuffle_ps(B, B, MM_SHUFFLE_REV(1, 2, 0, 3)); + fltx4 Result2 = MulSIMD(A2, B2); + return SubSIMD(Result1, Result2); + +#elif defined(_PS3) + return _vmathVfCross(A, B); +#else + fltx4 CrossVal; + SubFloat(CrossVal, 0) = SubFloat(A, 1) * SubFloat(B, 2) - SubFloat(A, 2) * SubFloat(B, 1); + SubFloat(CrossVal, 1) = SubFloat(A, 2) * SubFloat(B, 0) - SubFloat(A, 0) * SubFloat(B, 2); + SubFloat(CrossVal, 2) = SubFloat(A, 0) * SubFloat(B, 1) - SubFloat(A, 1) * SubFloat(B, 0); + SubFloat(CrossVal, 3) = 0; + return CrossVal; +#endif +} + +inline const fltx4 Length3SIMD(const fltx4 vec) +{ + fltx4 scLengthSqr = Dot3SIMD(vec, vec); + bi32x4 isSignificant = CmpGtSIMD(scLengthSqr, Four_Epsilons); + fltx4 scLengthInv = ReciprocalSqrtSIMD(scLengthSqr); + return AndSIMD(isSignificant, MulSIMD(scLengthInv, scLengthSqr)); +} + +inline const fltx4 Normalized3SIMD(const fltx4 vec) +{ + fltx4 scLengthSqr = Dot3SIMD(vec, vec); + bi32x4 isSignificant = CmpGtSIMD(scLengthSqr, Four_Epsilons); + fltx4 scLengthInv = ReciprocalSqrtSIMD(scLengthSqr); + return AndSIMD(isSignificant, MulSIMD(vec, scLengthInv)); +} + + +#ifndef COMPILER_GCC + +FORCEINLINE fltx4 operator+=(fltx4& a, FLTX4 b) +{ + a = AddSIMD(a, b); + return a; +} + +FORCEINLINE fltx4 operator-=(fltx4& a, FLTX4 b) +{ + a = SubSIMD(a, b); + return a; +} + + +FORCEINLINE fltx4 operator*=(fltx4& a, FLTX4 b) +{ + a = MulSIMD(a, b); + return a; +} + +#endif +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/steam.h b/SpyCustom/sdk/steam.h new file mode 100644 index 0000000..7c93f42 --- /dev/null +++ b/SpyCustom/sdk/steam.h @@ -0,0 +1,79 @@ +#pragma once +#include + +template +__forceinline static FuncType CallVFunction(void* ppClass, int index) +{ + int* pVTable = *(int**)ppClass; + int dwAddress = pVTable[index]; + return (FuncType)(dwAddress); +} + +enum EGCResult +{ + k_EGCResultOK = 0, + k_EGCResultNoMessage = 1, + k_EGCResultBufferTooSmall = 2, + k_EGCResultNotLoggedOn = 3, + k_EGCResultInvalidMessage = 4, +}; + +class ISteamGameCoordinator +{ +public: + virtual EGCResult GCSendMessage(int unMsgType, const void* pubData, int cubData) = 0; + virtual bool IsMessageAvailable(int* pcubMsgSize) = 0; + virtual EGCResult GCRetrieveMessage(int* punMsgType, void* pubDest, int cubDest, int* pcubMsgSize) = 0; + +}; + +class CSteamID +{ +public: + CSteamID() + { + m_steamid.m_comp.m_unAccountID = 0; + m_steamid.m_comp.m_EAccountType = 0; + m_steamid.m_comp.m_EUniverse = 0; + m_steamid.m_comp.m_unAccountInstance = 0; + } + uint32_t GetAccountID() const { return m_steamid.m_comp.m_unAccountID; } + +private: + union SteamID_t + { + struct SteamIDComponent_t + { + uint32_t m_unAccountID : 32; + unsigned int m_unAccountInstance : 20; + unsigned int m_EAccountType : 4; + int m_EUniverse : 8; + } m_comp; + + uint64_t m_unAll64Bits; + } m_steamid; +}; + +class ISteamUser +{ +public: + virtual uint32_t GetHSteamUser() = 0; + virtual bool BLoggedOn() = 0; + virtual CSteamID GetSteamID() = 0; +}; + +class ISteamClient +{ +public: + ISteamUser* GetISteamUser(void* hSteamUser, void* hSteamPipe, const char* pchVersion) + { + typedef ISteamUser* (__stdcall* func)(void*, void*, const char*); + return CallVFunction(this, 5)(hSteamUser, hSteamPipe, pchVersion); + } + + ISteamGameCoordinator* GetISteamGenericInterface(void* hSteamUser, void* hSteamPipe, const char* pchVersion) + { + typedef ISteamGameCoordinator* (__stdcall* func)(void*, void*, const char*); + return CallVFunction(this, 12)(hSteamUser, hSteamPipe, pchVersion); + } +}; \ No newline at end of file diff --git a/SpyCustom/sdk/steamtypes.h b/SpyCustom/sdk/steamtypes.h new file mode 100644 index 0000000..a6ae74e --- /dev/null +++ b/SpyCustom/sdk/steamtypes.h @@ -0,0 +1,145 @@ +#ifndef STEAMTYPES_H +#define STEAMTYPES_H +#ifdef _WIN32 +#pragma once +#endif + +#define S_CALLTYPE __cdecl + +#ifndef WCHARTYPES_H +typedef unsigned char uint8; +#endif + +#if defined( __GNUC__ ) && !defined(POSIX) +#if __GNUC__ < 4 +#error "Steamworks requires GCC 4.X (4.2 or 4.4 have been tested)" +#endif +#define POSIX 1 +#endif + +#if defined(__x86_64__) || defined(_WIN64) +#define X64BITS +#endif + +#if !defined(VALVE_BIG_ENDIAN) && defined(_PS3) +#define VALVE_BIG_ENDIAN +#endif + +typedef unsigned char uint8; +typedef signed char int8; + +#if defined( _WIN32 ) + +typedef __int16 int16; +typedef unsigned __int16 uint16; +typedef __int32 int32; +typedef unsigned __int32 uint32; +typedef __int64 int64; +typedef unsigned __int64 uint64; + +typedef int64 lint64; +typedef uint64 ulint64; + +#ifdef X64BITS +typedef __int64 intp; +typedef unsigned __int64 uintp; +#else +typedef __int32 intp; +typedef unsigned __int32 uintp; +#endif + +#else + +typedef short int16; +typedef unsigned short uint16; +typedef int int32; +typedef unsigned int uint32; +typedef long long int64; +typedef unsigned long long uint64; + +typedef long int lint64; +typedef unsigned long int ulint64; + +#ifdef X64BITS +typedef long long intp; +typedef unsigned long long uintp; +#else +typedef int intp; +typedef unsigned int uintp; +#endif + +#endif + +#ifdef __clang__ +# define CLANG_ATTR(ATTR) __attribute__((annotate( ATTR ))) +#else +# define CLANG_ATTR(ATTR) +#endif + +#define METHOD_DESC(DESC) CLANG_ATTR( "desc:" #DESC ";" ) +#define IGNOREATTR() CLANG_ATTR( "ignore" ) +#define OUT_STRUCT() CLANG_ATTR( "out_struct: ;" ) +#define OUT_ARRAY_CALL(COUNTER,FUNCTION,PARAMS) CLANG_ATTR( "out_array_call:" #COUNTER "," #FUNCTION "," #PARAMS ";" ) +#define OUT_ARRAY_COUNT(COUNTER, DESC) CLANG_ATTR( "out_array_count:" #COUNTER ";desc:" #DESC ) +#define ARRAY_COUNT(COUNTER) CLANG_ATTR( "array_count:" #COUNTER ";" ) +#define ARRAY_COUNT_D(COUNTER, DESC) CLANG_ATTR( "array_count:" #COUNTER ";desc:" #DESC ) +#define BUFFER_COUNT(COUNTER) CLANG_ATTR( "buffer_count:" #COUNTER ";" ) +#define OUT_BUFFER_COUNT(COUNTER) CLANG_ATTR( "out_buffer_count:" #COUNTER ";" ) +#define OUT_STRING_COUNT(COUNTER) CLANG_ATTR( "out_string_count:" #COUNTER ";" ) +#define DESC(DESC) CLANG_ATTR("desc:" #DESC ";") + + +const int k_cubSaltSize = 8; +typedef uint8 Salt_t[k_cubSaltSize]; + +typedef uint64 GID_t; + +const GID_t k_GIDNil = 0xffffffffffffffffull; + +typedef uint64 JobID_t; +typedef GID_t TxnID_t; + +const GID_t k_TxnIDNil = k_GIDNil; +const GID_t k_TxnIDUnknown = 0; + +const JobID_t k_JobIDNil = 0xffffffffffffffffull; + +typedef uint32 PackageId_t; +const PackageId_t k_uPackageIdFreeSub = 0x0; +const PackageId_t k_uPackageIdInvalid = 0xFFFFFFFF; + +typedef uint32 BundleId_t; +const BundleId_t k_uBundleIdInvalid = 0; + +typedef uint32 AppId_t; +const AppId_t k_uAppIdInvalid = 0x0; + +typedef uint64 AssetClassId_t; +const AssetClassId_t k_ulAssetClassIdInvalid = 0x0; + +typedef uint32 PhysicalItemId_t; +const PhysicalItemId_t k_uPhysicalItemIdInvalid = 0x0; + + +typedef uint32 DepotId_t; +const DepotId_t k_uDepotIdInvalid = 0x0; + +typedef uint32 RTime32; + +typedef uint32 CellID_t; +const CellID_t k_uCellIDInvalid = 0xFFFFFFFF; + +typedef uint64 SteamAPICall_t; +const SteamAPICall_t k_uAPICallInvalid = 0x0; + +typedef uint32 AccountID_t; + +typedef uint32 PartnerId_t; +const PartnerId_t k_uPartnerIdInvalid = 0; + +typedef uint64 ManifestId_t; +const ManifestId_t k_uManifestIdInvalid = 0; + + + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/string_t.h b/SpyCustom/sdk/string_t.h new file mode 100644 index 0000000..f2a709e --- /dev/null +++ b/SpyCustom/sdk/string_t.h @@ -0,0 +1,66 @@ +#ifndef STRING_T_H +#define STRING_T_H + +#if defined( _WIN32 ) +#pragma once +#endif + +#ifndef NO_STRING_T + +#ifdef WEAK_STRING_T + +typedef int string_t; + +#define NULL_STRING 0 + +#define STRING( offset ) ( ( offset ) ? reinterpret_cast( offset ) : "" ) + +#define MAKE_STRING( str ) ( ( *str != 0 ) ? reinterpret_cast( str ) : 0 ) + +#define IDENT_STRINGS( s1, s2 ) ( *((void **)&(s1)) == *((void **)&(s2)) ) + +#else + +struct string_t +{ +public: + bool operator!() const { return (pszValue == NULL); } + bool operator==(const string_t& rhs) const { return (pszValue == rhs.pszValue); } + bool operator!=(const string_t& rhs) const { return (pszValue != rhs.pszValue); } + bool operator<(const string_t& rhs) const { return ((void*)pszValue < (void*)rhs.pszValue); } + + const char* ToCStr() const { return (pszValue) ? pszValue : ""; } + +protected: + const char* pszValue; +}; + +struct castable_string_t : public string_t +{ + castable_string_t() { pszValue = NULL; } + castable_string_t(const char* pszFrom) { pszValue = (pszFrom && *pszFrom) ? pszFrom : 0; } +}; + +#define NULL_STRING castable_string_t() + +#define STRING( string_t_obj ) (string_t_obj).ToCStr() + +#define MAKE_STRING( c_str ) castable_string_t( c_str ) + +#define IDENT_STRINGS( s1, s2 ) ( *((void **)&(s1)) == *((void **)&(s2)) ) + +#endif + +#else + +typedef const char* string_t; +#define NULL_STRING 0 +#define STRING( c_str ) ( c_str ) +#define MAKE_STRING( c_str ) ( c_str ) +#define IDENT_STRINGS( s1, s2 ) ( *((void **)&(s1)) == *((void **)&(s2)) ) + +#endif + +inline void EnsureValidValue(string_t& x) { x = NULL_STRING; } + +#endif diff --git a/SpyCustom/sdk/stringpool.h b/SpyCustom/sdk/stringpool.h new file mode 100644 index 0000000..c091d16 --- /dev/null +++ b/SpyCustom/sdk/stringpool.h @@ -0,0 +1,465 @@ +#ifndef STRINGPOOL_H +#define STRINGPOOL_H + +#if defined( _WIN32 ) +#pragma once +#endif + +#include "utlrbtree.h" +#include "utlvector.h" +#include "utlbuffer.h" +#include "generichash.h" + +enum StringPoolCase_t +{ + StringPoolCaseInsensitive, + StringPoolCaseSensitive +}; + +class CStringPool +{ +public: + CStringPool(StringPoolCase_t caseSensitivity = StringPoolCaseInsensitive); + ~CStringPool(); + + unsigned int Count() const; + + const char* Allocate(const char* pszValue); + void FreeAll(); + + const char* Find(const char* pszValue); + +protected: + typedef CUtlRBTree CStrSet; + + CStrSet m_Strings; +}; + +template +class CCountedStringPoolBase +{ +public: + + struct hash_item_t + { + char* pString; + T nNextElement; + unsigned char nReferenceCount; + unsigned char pad; + }; + + enum + { + INVALID_ELEMENT = 0, + MAX_REFERENCE = 0xFF, + HASH_TABLE_SIZE = 1024 + }; + + CUtlVector m_HashTable; + CUtlVector m_Elements; + T m_FreeListStart; + StringPoolCase_t m_caseSensitivity; + +public: + CCountedStringPoolBase(StringPoolCase_t caseSensitivity = StringPoolCaseInsensitive); + virtual ~CCountedStringPoolBase(); + + void FreeAll(); + + char* FindString(const char* pIntrinsic); + char* ReferenceString(const char* pIntrinsic); + void DereferenceString(const char* pIntrinsic); + + T FindStringHandle(const char* pIntrinsic); + T ReferenceStringHandle(const char* pIntrinsic); + char* HandleToString(T handle); + void SpewStrings(); + unsigned Hash(const char* pszKey); + + bool SaveToBuffer(CUtlBuffer& buffer); + bool RestoreFromBuffer(CUtlBuffer& buffer); + + void VerifyNotOverflowed(unsigned int value); +}; + +typedef CCountedStringPoolBase CCountedStringPool; + +template +inline CCountedStringPoolBase::CCountedStringPoolBase(StringPoolCase_t caseSensitivity) +{ + MEM_ALLOC_CREDIT(); + m_HashTable.EnsureCount(HASH_TABLE_SIZE); + + for (int i = 0; i < m_HashTable.Count(); i++) + { + m_HashTable[i] = INVALID_ELEMENT; + } + + m_FreeListStart = INVALID_ELEMENT; + m_Elements.AddToTail(); + m_Elements[0].pString = NULL; + m_Elements[0].nReferenceCount = 0; + m_Elements[0].nNextElement = INVALID_ELEMENT; + + m_caseSensitivity = caseSensitivity; +} + +template +inline CCountedStringPoolBase::~CCountedStringPoolBase() +{ + FreeAll(); +} + +template +inline void CCountedStringPoolBase::FreeAll() +{ + int i; + + for (i = 0; i < m_HashTable.Count(); i++) + { + m_HashTable[i] = INVALID_ELEMENT; + } + + m_FreeListStart = INVALID_ELEMENT; + + for (i = 0; i < m_Elements.Count(); i++) + { + if (m_Elements[i].pString) + { + delete[] m_Elements[i].pString; + m_Elements[i].pString = NULL; + m_Elements[i].nReferenceCount = 0; + m_Elements[i].nNextElement = INVALID_ELEMENT; + } + } + + m_Elements.RemoveAll(); + m_Elements.AddToTail(); + m_Elements[0].pString = NULL; + m_Elements[0].nReferenceCount = 0; + m_Elements[0].nNextElement = INVALID_ELEMENT; +} + +template +inline unsigned CCountedStringPoolBase::Hash(const char* pszKey) +{ + if (m_caseSensitivity == StringPoolCaseInsensitive) + { + return HashStringCaseless(pszKey); + } + return HashString(pszKey); +} + +template +inline T CCountedStringPoolBase::FindStringHandle(const char* pIntrinsic) +{ + if (pIntrinsic == NULL) + return INVALID_ELEMENT; + + T nHashBucketIndex = (Hash(pIntrinsic) % HASH_TABLE_SIZE); + T nCurrentBucket = m_HashTable[nHashBucketIndex]; + + if (nCurrentBucket != INVALID_ELEMENT) + { + for (; nCurrentBucket != INVALID_ELEMENT; nCurrentBucket = m_Elements[nCurrentBucket].nNextElement) + { + if (!Q_stricmp(pIntrinsic, m_Elements[nCurrentBucket].pString)) + { + return nCurrentBucket; + } + } + } + + return 0; + +} + +template +inline char* CCountedStringPoolBase::FindString(const char* pIntrinsic) +{ + if (pIntrinsic == NULL) + return NULL; + + return m_Elements[FindStringHandle(pIntrinsic)].pString; +} + +template +inline T CCountedStringPoolBase::ReferenceStringHandle(const char* pIntrinsic) +{ + if (pIntrinsic == NULL) + return INVALID_ELEMENT; + + T nHashBucketIndex = (Hash(pIntrinsic) % HASH_TABLE_SIZE); + T nCurrentBucket = m_HashTable[nHashBucketIndex]; + + if (nCurrentBucket != INVALID_ELEMENT) + { + for (; nCurrentBucket != INVALID_ELEMENT; nCurrentBucket = m_Elements[nCurrentBucket].nNextElement) + { + if (!Q_stricmp(pIntrinsic, m_Elements[nCurrentBucket].pString)) + { + if (m_Elements[nCurrentBucket].nReferenceCount < MAX_REFERENCE) + { + m_Elements[nCurrentBucket].nReferenceCount++; + } + return nCurrentBucket; + } + } + } + + if (m_FreeListStart != INVALID_ELEMENT) + { + nCurrentBucket = m_FreeListStart; + m_FreeListStart = m_Elements[nCurrentBucket].nNextElement; + } + else + { + unsigned int newElement = m_Elements.AddToTail(); + VerifyNotOverflowed(newElement); + nCurrentBucket = newElement; + } + + m_Elements[nCurrentBucket].nReferenceCount = 1; + + m_Elements[nCurrentBucket].nNextElement = m_HashTable[nHashBucketIndex]; + m_HashTable[nHashBucketIndex] = nCurrentBucket; + + m_Elements[nCurrentBucket].pString = new char[Q_strlen(pIntrinsic) + 1]; + Q_strcpy(m_Elements[nCurrentBucket].pString, pIntrinsic); + + return nCurrentBucket; +} + +template<> +inline void CCountedStringPoolBase::VerifyNotOverflowed(unsigned int value) { Assert(value < 0xffff); } + +template<> +inline void CCountedStringPoolBase::VerifyNotOverflowed(unsigned int value) {} + +template +inline char* CCountedStringPoolBase::ReferenceString(const char* pIntrinsic) +{ + if (!pIntrinsic) + return NULL; + + return m_Elements[ReferenceStringHandle(pIntrinsic)].pString; +} + +template +inline void CCountedStringPoolBase::DereferenceString(const char* pIntrinsic) +{ + if (!pIntrinsic) + return; + + T nHashBucketIndex = (Hash(pIntrinsic) % m_HashTable.Count()); + T nCurrentBucket = m_HashTable[nHashBucketIndex]; + + if (nCurrentBucket == INVALID_ELEMENT) + return; + + for (T previous = INVALID_ELEMENT; nCurrentBucket != INVALID_ELEMENT; nCurrentBucket = m_Elements[nCurrentBucket].nNextElement) + { + if (!Q_stricmp(pIntrinsic, m_Elements[nCurrentBucket].pString)) + { + if (m_Elements[nCurrentBucket].nReferenceCount < MAX_REFERENCE) + { + m_Elements[nCurrentBucket].nReferenceCount--; + } + + if (m_Elements[nCurrentBucket].nReferenceCount == 0) + { + if (previous == INVALID_ELEMENT) + { + m_HashTable[nHashBucketIndex] = m_Elements[nCurrentBucket].nNextElement; + } + else + { + m_Elements[previous].nNextElement = m_Elements[nCurrentBucket].nNextElement; + } + + delete[] m_Elements[nCurrentBucket].pString; + m_Elements[nCurrentBucket].pString = NULL; + m_Elements[nCurrentBucket].nReferenceCount = 0; + + m_Elements[nCurrentBucket].nNextElement = m_FreeListStart; + m_FreeListStart = nCurrentBucket; + break; + + } + } + + previous = nCurrentBucket; + } +} + +template +inline char* CCountedStringPoolBase::HandleToString(T handle) +{ + return m_Elements[handle].pString; +} + +template +inline void CCountedStringPoolBase::SpewStrings() +{ + int i; + for (i = 0; i < m_Elements.Count(); i++) + { + char* string = m_Elements[i].pString; + + Msg("String %d: ref:%d %s\n", i, m_Elements[i].nReferenceCount, string == NULL ? "EMPTY - ok for slot zero only!" : string); + } + + Msg("\n%d total counted strings.", m_Elements.Count()); +} + +#define STRING_POOL_VERSION MAKEID( 'C', 'S', 'P', '1' ) +#define MAX_STRING_SAVE 1024 + +template<> +inline bool CCountedStringPoolBase::SaveToBuffer(CUtlBuffer& buffer) +{ + if (m_Elements.Count() <= 1) + { + return true; + } + + buffer.PutInt(STRING_POOL_VERSION); + + buffer.PutUnsignedShort(m_FreeListStart); + + buffer.PutInt(m_HashTable.Count()); + for (int i = 0; i < m_HashTable.Count(); i++) + { + buffer.PutUnsignedShort(m_HashTable[i]); + } + + buffer.PutInt(m_Elements.Count()); + for (int i = 1; i < m_Elements.Count(); i++) + { + buffer.PutUnsignedShort(m_Elements[i].nNextElement); + buffer.PutUnsignedChar(m_Elements[i].nReferenceCount); + + const char* pString = m_Elements[i].pString; + if (strlen(pString) >= MAX_STRING_SAVE) + { + return false; + } + buffer.PutString(pString ? pString : ""); + } + + return buffer.IsValid(); +} + +template<> +inline bool CCountedStringPoolBase::RestoreFromBuffer(CUtlBuffer& buffer) +{ + int signature = buffer.GetInt(); + if (signature != STRING_POOL_VERSION) + { + return false; + } + + FreeAll(); + + m_FreeListStart = buffer.GetUnsignedShort(); + + int hashCount = buffer.GetInt(); + m_HashTable.SetCount(hashCount); + + for (int i = 0; i < hashCount; i++) + { + m_HashTable[i] = buffer.GetUnsignedShort(); + } + + int tableCount = buffer.GetInt(); + if (tableCount > 1) + { + m_Elements.AddMultipleToTail(tableCount - 1); + } + + char tempString[MAX_STRING_SAVE]; + for (int i = 1; i < tableCount; i++) + { + m_Elements[i].nNextElement = buffer.GetUnsignedShort(); + m_Elements[i].nReferenceCount = buffer.GetUnsignedChar(); + buffer.GetString(tempString, sizeof(tempString)); + m_Elements[i].pString = strdup(tempString); + } + + return buffer.IsValid(); +} + +template<> +inline bool CCountedStringPoolBase::SaveToBuffer(CUtlBuffer& buffer) +{ + if (m_Elements.Count() <= 1) + { + return true; + } + + buffer.PutInt(STRING_POOL_VERSION); + + buffer.PutUnsignedInt(m_FreeListStart); + + buffer.PutInt(m_HashTable.Count()); + for (int i = 0; i < m_HashTable.Count(); i++) + { + buffer.PutUnsignedInt(m_HashTable[i]); + } + + buffer.PutInt(m_Elements.Count()); + for (int i = 1; i < m_Elements.Count(); i++) + { + buffer.PutUnsignedInt(m_Elements[i].nNextElement); + buffer.PutUnsignedChar(m_Elements[i].nReferenceCount); + + const char* pString = m_Elements[i].pString; + if (strlen(pString) >= MAX_STRING_SAVE) + { + return false; + } + buffer.PutString(pString ? pString : ""); + } + + return buffer.IsValid(); +} + +template<> +inline bool CCountedStringPoolBase::RestoreFromBuffer(CUtlBuffer& buffer) +{ + int signature = buffer.GetInt(); + if (signature != STRING_POOL_VERSION) + { + return false; + } + + FreeAll(); + + m_FreeListStart = buffer.GetUnsignedInt(); + + int hashCount = buffer.GetInt(); + m_HashTable.SetCount(hashCount); + + for (int i = 0; i < hashCount; i++) + { + m_HashTable[i] = buffer.GetUnsignedInt(); + } + + int tableCount = buffer.GetInt(); + if (tableCount > 1) + { + m_Elements.AddMultipleToTail(tableCount - 1); + } + + char tempString[MAX_STRING_SAVE]; + for (int i = 1; i < tableCount; i++) + { + m_Elements[i].nNextElement = buffer.GetUnsignedInt(); + m_Elements[i].nReferenceCount = buffer.GetUnsignedChar(); + buffer.GetString(tempString, sizeof(tempString)); + m_Elements[i].pString = strdup(tempString); + } + + return buffer.IsValid(); +} +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/strtools.h b/SpyCustom/sdk/strtools.h new file mode 100644 index 0000000..c79aa79 --- /dev/null +++ b/SpyCustom/sdk/strtools.h @@ -0,0 +1,660 @@ +#ifndef TIER1_STRTOOLS_H +#define TIER1_STRTOOLS_H + +#include "platform.h" + +#include +#include +#ifdef _WIN32 +#pragma once +#elif POSIX +#include +#include +#include +#endif + +#include +#include + +#ifdef _WIN64 +#define str_size unsigned int +#else +#define str_size size_t +#endif + +template< class T, class I > class CUtlMemory; +template< class T, class A > class CUtlVector; + + +void _V_memset(const char* file, int line, void* dest, int fill, int count); +void _V_memcpy(const char* file, int line, void* dest, const void* src, int count); +void _V_memmove(const char* file, int line, void* dest, const void* src, int count); +int _V_memcmp(const char* file, int line, const void* m1, const void* m2, int count); +int _V_strlen(const char* file, int line, const char* str); +void _V_strcpy(const char* file, int line, char* dest, const char* src); +char* _V_strrchr(const char* file, int line, const char* s, char c); +int _V_strcmp(const char* file, int line, const char* s1, const char* s2); +int _V_wcscmp(const char* file, int line, const wchar_t* s1, const wchar_t* s2); +char* _V_strstr(const char* file, int line, const char* s1, const char* search); +int _V_wcslen(const char* file, int line, const wchar_t* pwch); +wchar_t* _V_wcslower(const char* file, int line, wchar_t* start); +wchar_t* _V_wcsupr(const char* file, int line, wchar_t* start); + +char* V_strupr(char* start); +char* V_strlower(char* start); +int V_stricmp(const char* s1, const char* s2); +int V_strncmp(const char* s1, const char* s2, int count); +int V_strnicmp(const char* s1, const char* s2, int n); + +#ifdef POSIX + +inline char* strupr(char* start) +{ + return V_strupr(start); +} + +inline char* strlwr(char* start) +{ + return V_strlower(start); +} + +inline wchar_t* _wcslwr(wchar_t* start) +{ + wchar_t* str = start; + while (str && *str) + { + *str = (wchar_t)towlower(static_cast(*str)); + str++; + } + return start; +}; + +inline wchar_t* _wcsupr(wchar_t* start) +{ + wchar_t* str = start; + while (str && *str) + { + *str = (wchar_t)towupper(static_cast(*str)); + str++; + } + return start; +}; + +#endif + + +#ifdef _DEBUG + +#define V_memset(dest, fill, count) _V_memset (__FILE__, __LINE__, (dest), (fill), (count)) +#define V_memcpy(dest, src, count) _V_memcpy (__FILE__, __LINE__, (dest), (src), (count)) +#define V_memmove(dest, src, count) _V_memmove (__FILE__, __LINE__, (dest), (src), (count)) +#define V_memcmp(m1, m2, count) _V_memcmp (__FILE__, __LINE__, (m1), (m2), (count)) +#define V_strlen(str) _V_strlen (__FILE__, __LINE__, (str)) +#define V_strcpy(dest, src) _V_strcpy (__FILE__, __LINE__, (dest), (src)) +#define V_strrchr(s, c) _V_strrchr (__FILE__, __LINE__, (s), (c)) +#define V_strcmp(s1, s2) _V_strcmp (__FILE__, __LINE__, (s1), (s2)) +#define V_wcscmp(s1, s2) _V_wcscmp (__FILE__, __LINE__, (s1), (s2)) +#define V_strstr(s1, search ) _V_strstr (__FILE__, __LINE__, (s1), (search) ) +#define V_wcslen(pwch) _V_wcslen (__FILE__, __LINE__, (pwch)) +#define V_wcslower(start) _V_wcslower (__FILE__, __LINE__, (start)) +#define V_wcsupr(start) _V_wcsupr (__FILE__, __LINE__, (start)) + +#else + + +inline void V_memset(void* dest, int fill, int count) { memset(dest, fill, count); } +inline void V_memcpy(void* dest, const void* src, int count) { memcpy(dest, src, count); } +inline void V_memmove(void* dest, const void* src, int count) { memmove(dest, src, count); } +inline int V_memcmp(const void* m1, const void* m2, int count) { return memcmp(m1, m2, count); } +inline int V_strlen(const char* str) { return (int)strlen(str); } +inline void V_strcpy(char* dest, const char* src) { strcpy(dest, src); } +inline int V_wcslen(const wchar_t* pwch) { return (int)wcslen(pwch); } +inline char* V_strrchr(const char* s, char c) { return (char*)strrchr(s, c); } +inline int V_strcmp(const char* s1, const char* s2) { return strcmp(s1, s2); } +inline int V_wcscmp(const wchar_t* s1, const wchar_t* s2) { return wcscmp(s1, s2); } +inline char* V_strstr(const char* s1, const char* search) { return (char*)strstr(s1, search); } +inline wchar_t* V_wcslower(wchar_t* start) { return _wcslwr(start); } +inline wchar_t* V_wcsupr(wchar_t* start) { return _wcsupr(start); } + +#endif + +int V_atoi(const char* str); +int64 V_atoi64(const char* str); +uint64 V_atoui64(const char* str); +float V_atof(const char* str); +char* V_stristr(char* pStr, const char* pSearch); +const char* V_stristr(const char* pStr, const char* pSearch); +const char* V_strnistr(const char* pStr, const char* pSearch, int n); +const char* V_strnchr(const char* pStr, char c, int n); +inline int V_strcasecmp(const char* s1, const char* s2) { return V_stricmp(s1, s2); } +inline int V_strncasecmp(const char* s1, const char* s2, int n) { return V_strnicmp(s1, s2, n); } +void V_qsort_s(void* base, size_t num, size_t width, int(__cdecl* compare)(void*, const void*, + const void*), void* context); + + +const char* StringAfterPrefix(const char* str, const char* prefix); +const char* StringAfterPrefixCaseSensitive(const char* str, const char* prefix); +inline bool StringHasPrefix(const char* str, const char* prefix) { return StringAfterPrefix(str, prefix) != NULL; } +inline bool StringHasPrefixCaseSensitive(const char* str, const char* prefix) { return StringAfterPrefixCaseSensitive(str, prefix) != NULL; } + + +void V_normalizeFloatString(char* pFloat); + +inline bool V_isdigit(char c) +{ + return c >= '0' && c <= '9'; +} + +inline bool V_isalpha(char c) { return isalpha((unsigned char)c) != 0; } +inline bool V_isalnum(char c) { return isalnum((unsigned char)c) != 0; } +inline bool V_isprint(char c) { return isprint((unsigned char)c) != 0; } +inline bool V_isxdigit(char c) { return isxdigit((unsigned char)c) != 0; } +inline bool V_ispunct(char c) { return ispunct((unsigned char)c) != 0; } +inline bool V_isgraph(char c) { return isgraph((unsigned char)c) != 0; } +inline bool V_isupper(char c) { return isupper((unsigned char)c) != 0; } +inline bool V_islower(char c) { return islower((unsigned char)c) != 0; } +inline bool V_iscntrl(char c) { return iscntrl((unsigned char)c) != 0; } +inline bool V_isspace(char c) { return isspace((unsigned char)c) != 0; } + +void V_strncpy(OUT_Z_CAP(maxLenInChars) char* pDest, const char* pSrc, int maxLenInChars); + +template void V_strcpy_safe(OUT_Z_ARRAY char(&pDest)[maxLenInChars], const char* pSrc) +{ + V_strncpy(pDest, pSrc, (int)maxLenInChars); +} + +void V_wcsncpy(OUT_Z_BYTECAP(maxLenInBytes) wchar_t* pDest, wchar_t const* pSrc, int maxLenInBytes); +template void V_wcscpy_safe(OUT_Z_ARRAY wchar_t(&pDest)[maxLenInChars], wchar_t const* pSrc) +{ + V_wcsncpy(pDest, pSrc, maxLenInChars * sizeof(*pDest)); +} + +#define COPY_ALL_CHARACTERS -1 +char* V_strncat(INOUT_Z_CAP(cchDest) char* pDest, const char* pSrc, size_t cchDest, int max_chars_to_copy = COPY_ALL_CHARACTERS); +template char* V_strcat_safe(INOUT_Z_ARRAY char(&pDest)[cchDest], const char* pSrc, int nMaxCharsToCopy = COPY_ALL_CHARACTERS) +{ + return V_strncat(pDest, pSrc, (int)cchDest, nMaxCharsToCopy); +} + +wchar_t* V_wcsncat(INOUT_Z_CAP(cchDest) wchar_t* pDest, const wchar_t* pSrc, size_t cchDest, int nMaxCharsToCopy = COPY_ALL_CHARACTERS); +template wchar_t* V_wcscat_safe(INOUT_Z_ARRAY wchar_t(&pDest)[cchDest], const wchar_t* pSrc, int nMaxCharsToCopy = COPY_ALL_CHARACTERS) +{ + return V_wcsncat(pDest, pSrc, (int)cchDest, nMaxCharsToCopy); +} + +char* V_strnlwr(INOUT_Z_CAP(cchBuf) char* pBuf, size_t cchBuf); +template char* V_strlwr_safe(INOUT_Z_ARRAY char(&pBuf)[cchDest]) +{ + return _V_strnlwr(pBuf, (int)cchDest); +} + + +#ifdef _WIN32 +#ifndef _VA_LIST_DEFINED + +#ifdef _M_ALPHA + +struct va_list +{ + char* a0; + int offset; +}; + +#else + +typedef char* va_list; + +#endif + +#define _VA_LIST_DEFINED + +#endif + +#elif POSIX +#include +#endif + +#ifdef _WIN32 +#define CORRECT_PATH_SEPARATOR '\\' +#define CORRECT_PATH_SEPARATOR_S "\\" +#define INCORRECT_PATH_SEPARATOR '/' +#define INCORRECT_PATH_SEPARATOR_S "/" +#elif POSIX +#define CORRECT_PATH_SEPARATOR '/' +#define CORRECT_PATH_SEPARATOR_S "/" +#define INCORRECT_PATH_SEPARATOR '\\' +#define INCORRECT_PATH_SEPARATOR_S "\\" +#endif + +int V_vsnprintf(OUT_Z_CAP(maxLenInCharacters) char* pDest, int maxLenInCharacters, PRINTF_FORMAT_STRING const char* pFormat, va_list params); +template int V_vsprintf_safe(OUT_Z_ARRAY char(&pDest)[maxLenInCharacters], PRINTF_FORMAT_STRING const char* pFormat, va_list params) { return V_vsnprintf(pDest, maxLenInCharacters, pFormat, params); } + +int V_snprintf(OUT_Z_CAP(maxLenInChars) char* pDest, int maxLenInChars, PRINTF_FORMAT_STRING const char* pFormat, ...) FMTFUNCTION(3, 4); +template int V_sprintf_safe(OUT_Z_ARRAY char(&pDest)[maxLenInChars], PRINTF_FORMAT_STRING const char* pFormat, ...) FMTFUNCTION(2, 3); +template int V_sprintf_safe(OUT_Z_ARRAY char(&pDest)[maxLenInChars], PRINTF_FORMAT_STRING const char* pFormat, ...) +{ + va_list params; + va_start(params, pFormat); + int result = V_vsnprintf(pDest, maxLenInChars, pFormat, params); + va_end(params); + return result; +} + +int V_vsnwprintf(OUT_Z_CAP(maxLenInCharacters) wchar_t* pDest, int maxLenInCharacters, PRINTF_FORMAT_STRING const wchar_t* pFormat, va_list params); +template int V_vswprintf_safe(OUT_Z_ARRAY wchar_t(&pDest)[maxLenInCharacters], PRINTF_FORMAT_STRING const wchar_t* pFormat, va_list params) { return V_vsnwprintf(pDest, maxLenInCharacters, pFormat, params); } +int V_vsnprintfRet(OUT_Z_CAP(maxLenInCharacters) char* pDest, int maxLenInCharacters, PRINTF_FORMAT_STRING const char* pFormat, va_list params, bool* pbTruncated); +template int V_vsprintfRet_safe(OUT_Z_ARRAY char(&pDest)[maxLenInCharacters], PRINTF_FORMAT_STRING const char* pFormat, va_list params, bool* pbTruncated) { return V_vsnprintfRet(pDest, maxLenInCharacters, pFormat, params, pbTruncated); } + +int V_snwprintf(OUT_Z_CAP(maxLenInCharacters) wchar_t* pDest, int maxLenInCharacters, PRINTF_FORMAT_STRING const wchar_t* pFormat, ...); +template int V_swprintf_safe(OUT_Z_ARRAY wchar_t(&pDest)[maxLenInChars], PRINTF_FORMAT_STRING const wchar_t* pFormat, ...) +{ + va_list params; + va_start(params, pFormat); + int result = V_vsnwprintf(pDest, maxLenInChars, pFormat, params); + va_end(params); + return result; +} + +char* V_pretifymem(float value, int digitsafterdecimal = 2, bool usebinaryonek = false); + +char* V_pretifynum(int64 value); + +int V_UTF8ToUnicode(const char* pUTF8, OUT_Z_BYTECAP(cubDestSizeInBytes) wchar_t* pwchDest, int cubDestSizeInBytes); +int V_UnicodeToUTF8(const wchar_t* pUnicode, OUT_Z_BYTECAP(cubDestSizeInBytes) char* pUTF8, int cubDestSizeInBytes); +int V_UCS2ToUnicode(const ucs2* pUCS2, OUT_Z_BYTECAP(cubDestSizeInBytes) wchar_t* pUnicode, int cubDestSizeInBytes); +int V_UCS2ToUTF8(const ucs2* pUCS2, OUT_Z_BYTECAP(cubDestSizeInBytes) char* pUTF8, int cubDestSizeInBytes); +int V_UnicodeToUCS2(const wchar_t* pUnicode, int cubSrcInBytes, OUT_Z_BYTECAP(cubDestSizeInBytes) char* pUCS2, int cubDestSizeInBytes); +int V_UTF8ToUCS2(const char* pUTF8, int cubSrcInBytes, OUT_Z_BYTECAP(cubDestSizeInBytes) ucs2* pUCS2, int cubDestSizeInBytes); + +bool Q_StripPrecedingAndTrailingWhitespace(char* pch); +bool Q_StripPrecedingAndTrailingWhitespaceW(wchar_t* pwch); + +bool Q_AggressiveStripPrecedingAndTrailingWhitespace(char* pch); +bool Q_AggressiveStripPrecedingAndTrailingWhitespaceW(wchar_t* pwch); + +unsigned char V_nibble(char c); +void V_hextobinary(char const* in, int numchars, byte* out, int maxoutputbytes); +void V_binarytohex(const byte* in, int inputbytes, char* out, int outsize); + +void V_FileBase(const char* in, char* out, int maxlen); +void V_StripTrailingSlash(char* ppath); +void V_StripExtension(const char* in, char* out, int outLen); +void V_DefaultExtension(char* path, const char* extension, int pathStringLength); +void V_SetExtension(char* path, const char* extension, int pathStringLength); +void V_StripFilename(char* path); +bool V_StripLastDir(char* dirName, int maxlen); +const char* V_UnqualifiedFileName(const char* in); +void V_ComposeFileName(const char* path, const char* filename, char* dest, int destSize); + +bool V_ExtractFilePath(const char* path, char* dest, int destSize); +void V_ExtractFileExtension(const char* path, char* dest, int destSize); + +const char* V_GetFileExtension(const char* path); + +const char* V_GetFileName(const char* path); + +bool V_RemoveDotSlashes(char* pFilename, char separator = CORRECT_PATH_SEPARATOR, bool bRemoveDoubleSlashes = true); + +void V_MakeAbsolutePath(char* pOut, int outLen, const char* pPath, const char* pStartingDir = NULL); + +bool V_MakeRelativePath(const char* pFullPath, const char* pDirectory, char* pRelativePath, int nBufLen); + +void V_FixupPathName(OUT_Z_CAP(nOutLen) char* pOut, size_t nOutLen, const char* pPath); + +void V_AppendSlash(INOUT_Z_CAP(strSize) char* pStr, int strSize); + +bool V_IsAbsolutePath(IN_Z const char* pPath); + +bool V_StrSubst(IN_Z const char* pIn, IN_Z const char* pMatch, const char* pReplaceWith, + OUT_Z_CAP(outLen) char* pOut, int outLen, bool bCaseSensitive = false); + +void V_SplitString(IN_Z const char* pString, IN_Z const char* pSeparator, CUtlVector >& outStrings); + +void V_SplitString2(IN_Z const char* pString, const char** pSeparators, int nSeparators, CUtlVector >& outStrings); + +bool V_GetCurrentDirectory(OUT_Z_CAP(maxLen) char* pOut, int maxLen); + +bool V_SetCurrentDirectory(const char* pDirName); + + +void V_StrSlice(const char* pStr, int firstChar, int lastCharNonInclusive, OUT_Z_CAP(outSize) char* pOut, int outSize); + +void V_StrLeft(const char* pStr, int nChars, OUT_Z_CAP(outSize) char* pOut, int outSize); + +void V_StrRight(const char* pStr, int nChars, OUT_Z_CAP(outSize) char* pOut, int outSize); + +char* V_AddBackSlashesToSpecialChars(char const* pSrc); + +void V_FixSlashes(char* pname, char separator = CORRECT_PATH_SEPARATOR); + +void V_FixDoubleSlashes(char* pStr); + +void V_strtowcs(const char* pString, int nInSize, OUT_Z_BYTECAP(nOutSizeInBytes) wchar_t* pWString, int nOutSizeInBytes); +void V_wcstostr(const wchar_t* pWString, int nInSize, OUT_Z_CAP(nOutSizeInBytes) char* pString, int nOutSizeInBytes); + +inline void V_strcat(INOUT_Z_CAP(cchDest) char* dest, const char* src, int cchDest) +{ + V_strncat(dest, src, cchDest, COPY_ALL_CHARACTERS); +} + +inline void V_wcscat(INOUT_Z_CAP(cchDest) wchar_t* dest, const wchar_t* src, int cchDest) +{ + V_wcsncat(dest, src, cchDest, COPY_ALL_CHARACTERS); +} + +template < class NameArray > +int V_GenerateUniqueNameIndex(const char* prefix, const NameArray& nameArray, int startindex = 0) +{ + if (prefix == NULL) + return 0; + + int freeindex = startindex; + + int nNames = nameArray.Count(); + for (int i = 0; i < nNames; ++i) + { + const char* pName = nameArray[i]; + if (!pName) + continue; + + const char* pIndexStr = StringAfterPrefix(pName, prefix); + if (pIndexStr) + { + int index = *pIndexStr ? atoi(pIndexStr) : 1; + if (index >= freeindex) + { + freeindex = index + 1; + } + } + } + + return freeindex; +} + +template < class NameArray > +bool V_GenerateUniqueName(OUT_Z_CAP(memsize) char* name, int memsize, const char* prefix, const NameArray& nameArray) +{ + if (name == NULL || memsize == 0) + return false; + + if (prefix == NULL) + { + name[0] = '\0'; + return false; + } + + int prefixLength = V_strlen(prefix); + if (prefixLength + 1 > memsize) + { + name[0] = '\0'; + return false; + } + + int i = V_GenerateUniqueNameIndex(prefix, nameArray); + if (i <= 0) + { + V_strncpy(name, prefix, memsize); + return true; + } + + int newlen = prefixLength + (int)log10((float)i) + 1; + if (newlen + 1 > memsize) + { + V_strncpy(name, prefix, memsize); + return false; + } + + V_snprintf(name, memsize, "%s%d", prefix, i); + return true; +} + + +class CStrAutoEncode +{ +public: + + explicit CStrAutoEncode(const char* pch) + { + m_pch = pch; + m_pwch = NULL; +#if !defined( WIN32 ) && !defined(_WIN32) + m_pucs2 = NULL; +#endif + m_bCreatedUTF16 = false; + } + + explicit CStrAutoEncode(const wchar_t* pwch) + { + m_pch = NULL; + m_pwch = pwch; +#if !defined( WIN32 ) && !defined(_WIN32) + m_pucs2 = NULL; +#endif + m_bCreatedUTF16 = true; + } + +#if !defined(WIN32) && !defined(_WINDOWS) && !defined(_WIN32) + explicit CStrAutoEncode(const ucs2* pwch) + { + m_pch = NULL; + m_pwch = NULL; + m_pucs2 = pwch; + m_bCreatedUTF16 = true; + } +#endif + + const char* ToString() + { + PopulateUTF8(); + return m_pch; + } + + char* ToStringWritable() + { + PopulateUTF8(); + return const_cast(m_pch); + } + + const wchar_t* ToWString() + { + PopulateUTF16(); + return m_pwch; + } + +#if !defined( WIN32 ) && !defined(_WIN32) + const ucs2* ToUCS2String() + { + PopulateUCS2(); + return m_pucs2; + } +#endif + + wchar_t* ToWStringWritable() + { + PopulateUTF16(); + return const_cast(m_pwch); + } + + ~CStrAutoEncode() + { + if (m_bCreatedUTF16) + { + delete[] m_pch; + } + else + { + delete[] m_pwch; + } + } + +private: + void PopulateUTF8() + { + if (!m_bCreatedUTF16) + return; + if (m_pwch == NULL) + return; + if (m_pch != NULL) + return; + + uint32 cbMax = 4 * static_cast(V_wcslen(m_pwch)) + 1; + char* pchTemp = new char[cbMax]; + if (V_UnicodeToUTF8(m_pwch, pchTemp, cbMax)) + { + uint32 cchAlloc = static_cast(V_strlen(pchTemp)) + 1; + char* pchHeap = new char[cchAlloc]; + V_strncpy(pchHeap, pchTemp, cchAlloc); + delete[] pchTemp; + m_pch = pchHeap; + } + else + { + delete[] pchTemp; + } + } + + void PopulateUTF16() + { + if (m_bCreatedUTF16) + return; + if (m_pch == NULL) + return; + if (m_pwch != NULL) + return; + + uint32 cchMax = static_cast(V_strlen(m_pch)) + 1; + wchar_t* pwchTemp = new wchar_t[cchMax]; + if (V_UTF8ToUnicode(m_pch, pwchTemp, cchMax * sizeof(wchar_t))) + { + uint32 cchAlloc = static_cast(V_wcslen(pwchTemp)) + 1; + wchar_t* pwchHeap = new wchar_t[cchAlloc]; + V_wcsncpy(pwchHeap, pwchTemp, cchAlloc * sizeof(wchar_t)); + delete[] pwchTemp; + m_pwch = pwchHeap; + } + else + { + delete[] pwchTemp; + } + } + +#if !defined( WIN32 ) && !defined(_WIN32) + void PopulateUCS2() + { + if (m_pch == NULL) + return; + if (m_pucs2 != NULL) + return; + + uint32 cchMax = static_cast(V_strlen(m_pch)) + 1; + ucs2* pwchTemp = new ucs2[cchMax]; + if (V_UTF8ToUCS2(m_pch, cchMax, pwchTemp, cchMax * sizeof(ucs2))) + { + uint32 cchAlloc = cchMax; + ucs2* pwchHeap = new ucs2[cchAlloc]; + memcpy(pwchHeap, pwchTemp, cchAlloc * sizeof(ucs2)); + delete[] pwchTemp; + m_pucs2 = pwchHeap; + } + else + { + delete[] pwchTemp; + } + } +#endif + + const char* m_pch; + const wchar_t* m_pwch; +#if !defined( WIN32 ) && !defined(_WIN32) + const ucs2* m_pucs2; +#endif + bool m_bCreatedUTF16; + +}; + +void Q_URLEncodeRaw(OUT_Z_CAP(nDestLen) char* pchDest, int nDestLen, const char* pchSource, int nSourceLen); + +size_t Q_URLDecodeRaw(OUT_CAP(nDecodeDestLen) char* pchDecodeDest, int nDecodeDestLen, const char* pchEncodedSource, int nEncodedSourceLen); + +void Q_URLEncode(OUT_Z_CAP(nDestLen) char* pchDest, int nDestLen, const char* pchSource, int nSourceLen); + +size_t Q_URLDecode(OUT_CAP(nDecodeDestLen) char* pchDecodeDest, int nDecodeDestLen, const char* pchEncodedSource, int nEncodedSourceLen); + + +#if !defined( VSTDLIB_BACKWARD_COMPAT ) + +#define Q_memset V_memset +#define Q_memcpy V_memcpy +#define Q_memmove V_memmove +#define Q_memcmp V_memcmp +#define Q_strlen V_strlen +#define Q_strcpy V_strcpy +#define Q_strrchr V_strrchr +#define Q_strcmp V_strcmp +#define Q_wcscmp V_wcscmp +#define Q_stricmp V_stricmp +#define Q_strstr V_strstr +#define Q_strupr V_strupr +#define Q_strlower V_strlower +#define Q_wcslen V_wcslen +#define Q_strncmp V_strncmp +#define Q_strcasecmp V_strcasecmp +#define Q_strncasecmp V_strncasecmp +#define Q_strnicmp V_strnicmp +#define Q_atoi V_atoi +#define Q_atoi64 V_atoi64 +#define Q_atoui64 V_atoui64 +#define Q_atof V_atof +#define Q_stristr V_stristr +#define Q_strnistr V_strnistr +#define Q_strnchr V_strnchr +#define Q_normalizeFloatString V_normalizeFloatString +#define Q_strncpy V_strncpy +#define Q_snprintf V_snprintf +#define Q_snwprintf V_snwprintf +#define Q_wcsncpy V_wcsncpy +#define Q_strncat V_strncat +#define Q_strnlwr V_strnlwr +#define Q_vsnprintf V_vsnprintf +#define Q_vsnprintfRet V_vsnprintfRet +#define Q_pretifymem V_pretifymem +#define Q_pretifynum V_pretifynum +#define Q_UTF8ToUnicode V_UTF8ToUnicode +#define Q_UnicodeToUTF8 V_UnicodeToUTF8 +#define Q_hextobinary V_hextobinary +#define Q_binarytohex V_binarytohex +#define Q_FileBase V_FileBase +#define Q_StripTrailingSlash V_StripTrailingSlash +#define Q_StripExtension V_StripExtension +#define Q_DefaultExtension V_DefaultExtension +#define Q_SetExtension V_SetExtension +#define Q_StripFilename V_StripFilename +#define Q_StripLastDir V_StripLastDir +#define Q_UnqualifiedFileName V_UnqualifiedFileName +#define Q_ComposeFileName V_ComposeFileName +#define Q_ExtractFilePath V_ExtractFilePath +#define Q_ExtractFileExtension V_ExtractFileExtension +#define Q_GetFileExtension V_GetFileExtension +#define Q_RemoveDotSlashes V_RemoveDotSlashes +#define Q_MakeAbsolutePath V_MakeAbsolutePath +#define Q_AppendSlash V_AppendSlash +#define Q_IsAbsolutePath V_IsAbsolutePath +#define Q_StrSubst V_StrSubst +#define Q_SplitString V_SplitString +#define Q_SplitString2 V_SplitString2 +#define Q_StrSlice V_StrSlice +#define Q_StrLeft V_StrLeft +#define Q_StrRight V_StrRight +#define Q_FixSlashes V_FixSlashes +#define Q_strtowcs V_strtowcs +#define Q_wcstostr V_wcstostr +#define Q_strcat V_strcat +#define Q_GenerateUniqueNameIndex V_GenerateUniqueNameIndex +#define Q_GenerateUniqueName V_GenerateUniqueName +#define Q_MakeRelativePath V_MakeRelativePath +#define Q_qsort_s V_qsort_s + +#endif + + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/studio.h b/SpyCustom/sdk/studio.h new file mode 100644 index 0000000..a0a880a --- /dev/null +++ b/SpyCustom/sdk/studio.h @@ -0,0 +1,2781 @@ +#ifndef STUDIO_H +#define STUDIO_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "basetypes.h" +#include "vector2d.h" +#include "vector.h" +#include "vector4d.h" +#include "compressed_vector.h" +#include "dbg.h" +#include "threadtools.h" +#include "mathlib.h" +#include "utlvector.h" +#include "utlhash.h" +#include "datamap.h" +#include "generichash.h" +#include "localflexcontroller.h" +#include "utlsymbol.h" + +#define STUDIO_ENABLE_PERF_COUNTERS + +#define STUDIO_SEQUENCE_ACTIVITY_LOOKUPS_ARE_SLOW 0 +#define STUDIO_SEQUENCE_ACTIVITY_LAZY_INITIALIZE 1 + +class IMaterial; +class IMesh; +class IMorph; +struct virtualmodel_t; +struct vertexFileHeader_t; +struct thinModelVertices_t; + +namespace OptimizedModel +{ + struct StripHeader_t; +} + + +#define STUDIO_VERSION 48 + +#ifndef _XBOX +#define MAXSTUDIOTRIANGLES 65536 +#define MAXSTUDIOVERTS 65536 +#define MAXSTUDIOFLEXVERTS 10000 +#else +#define MAXSTUDIOTRIANGLES 25000 +#define MAXSTUDIOVERTS 10000 +#define MAXSTUDIOFLEXVERTS 1000 +#endif +#define MAXSTUDIOSKINS 32 +#define MAXSTUDIOBONES 128 +#define MAXSTUDIOFLEXDESC 1024 +#define MAXSTUDIOFLEXCTRL 96 +#define MAXSTUDIOPOSEPARAM 24 +#define MAXSTUDIOBONECTRLS 4 +#define MAXSTUDIOANIMBLOCKS 256 + +#define MAXSTUDIOBONEBITS 7 + +#define MAX_NUM_BONES_PER_VERT 3 + +#define NEW_EVENT_STYLE ( 1 << 10 ) + +struct mstudiodata_t +{ + int count; + int offset; +}; + +#define STUDIO_PROC_AXISINTERP 1 +#define STUDIO_PROC_QUATINTERP 2 +#define STUDIO_PROC_AIMATBONE 3 +#define STUDIO_PROC_AIMATATTACH 4 +#define STUDIO_PROC_JIGGLE 5 + +struct mstudioaxisinterpbone_t +{ + DECLARE_BYTESWAP_DATADESC(); + int control; + int axis; + Vector pos[6]; + Quaternion quat[6]; + + mstudioaxisinterpbone_t() {} +private: + mstudioaxisinterpbone_t(const mstudioaxisinterpbone_t& vOther); +}; + + +struct mstudioquatinterpinfo_t +{ + DECLARE_BYTESWAP_DATADESC(); + float inv_tolerance; + Quaternion trigger; + Vector pos; + Quaternion quat; + + mstudioquatinterpinfo_t() {} +private: + mstudioquatinterpinfo_t(const mstudioquatinterpinfo_t& vOther); +}; + +struct mstudioquatinterpbone_t +{ + DECLARE_BYTESWAP_DATADESC(); + int control; + int numtriggers; + int triggerindex; + inline mstudioquatinterpinfo_t* pTrigger(int i) const { return (mstudioquatinterpinfo_t*)(((byte*)this) + triggerindex) + i; }; + + mstudioquatinterpbone_t() {} +private: + mstudioquatinterpbone_t(const mstudioquatinterpbone_t& vOther); +}; + + +#define JIGGLE_IS_FLEXIBLE 0x01 +#define JIGGLE_IS_RIGID 0x02 +#define JIGGLE_HAS_YAW_CONSTRAINT 0x04 +#define JIGGLE_HAS_PITCH_CONSTRAINT 0x08 +#define JIGGLE_HAS_ANGLE_CONSTRAINT 0x10 +#define JIGGLE_HAS_LENGTH_CONSTRAINT 0x20 +#define JIGGLE_HAS_BASE_SPRING 0x40 +#define JIGGLE_IS_BOING 0x80 + +struct mstudiojigglebone_t +{ + DECLARE_BYTESWAP_DATADESC(); + + int flags; + + float length; + float tipMass; + + float yawStiffness; + float yawDamping; + float pitchStiffness; + float pitchDamping; + float alongStiffness; + float alongDamping; + + float angleLimit; + + float minYaw; + float maxYaw; + float yawFriction; + float yawBounce; + + float minPitch; + float maxPitch; + float pitchFriction; + float pitchBounce; + + float baseMass; + float baseStiffness; + float baseDamping; + float baseMinLeft; + float baseMaxLeft; + float baseLeftFriction; + float baseMinUp; + float baseMaxUp; + float baseUpFriction; + float baseMinForward; + float baseMaxForward; + float baseForwardFriction; + + float boingImpactSpeed; + float boingImpactAngle; + float boingDampingRate; + float boingFrequency; + float boingAmplitude; + +private: +}; + +struct mstudioaimatbone_t +{ + DECLARE_BYTESWAP_DATADESC(); + + int parent; + int aim; + Vector aimvector; + Vector upvector; + Vector basepos; + + mstudioaimatbone_t() {} +private: + mstudioaimatbone_t(const mstudioaimatbone_t& vOther); +}; + +struct mstudiobone_t +{ + DECLARE_BYTESWAP_DATADESC(); + int sznameindex; + inline char* const pszName(void) const { return ((char*)this) + sznameindex; } + int parent; + int bonecontroller[6]; + + Vector pos; + Quaternion quat; + RadianEuler rot; + Vector posscale; + Vector rotscale; + + matrix3x4_t poseToBone; + Quaternion qAlignment; + int flags; + int proctype; + int procindex; + mutable int physicsbone; + inline void* pProcedure() const { if (procindex == 0) return NULL; else return (void*)(((byte*)this) + procindex); }; + int surfacepropidx; + inline char* const pszSurfaceProp(void) const { return ((char*)this) + surfacepropidx; } + int contents; + + int unused[8]; + + mstudiobone_t() {} +private: + mstudiobone_t(const mstudiobone_t& vOther); +}; + +struct mstudiolinearbone_t +{ + DECLARE_BYTESWAP_DATADESC(); + + int numbones; + + int flagsindex; + inline int flags(int i) const { Assert(i >= 0 && i < numbones); return *((int*)(((byte*)this) + flagsindex) + i); }; + inline int* pflags(int i) { Assert(i >= 0 && i < numbones); return ((int*)(((byte*)this) + flagsindex) + i); }; + + int parentindex; + inline int parent(int i) const { Assert(i >= 0 && i < numbones); return *((int*)(((byte*)this) + parentindex) + i); }; + + int posindex; + inline Vector pos(int i) const { Assert(i >= 0 && i < numbones); return *((Vector*)(((byte*)this) + posindex) + i); }; + + int quatindex; + inline Quaternion quat(int i) const { Assert(i >= 0 && i < numbones); return *((Quaternion*)(((byte*)this) + quatindex) + i); }; + + int rotindex; + inline RadianEuler rot(int i) const { Assert(i >= 0 && i < numbones); return *((RadianEuler*)(((byte*)this) + rotindex) + i); }; + + int posetoboneindex; + inline matrix3x4_t poseToBone(int i) const { Assert(i >= 0 && i < numbones); return *((matrix3x4_t*)(((byte*)this) + posetoboneindex) + i); }; + + int posscaleindex; + inline Vector posscale(int i) const { Assert(i >= 0 && i < numbones); return *((Vector*)(((byte*)this) + posscaleindex) + i); }; + + int rotscaleindex; + inline Vector rotscale(int i) const { Assert(i >= 0 && i < numbones); return *((Vector*)(((byte*)this) + rotscaleindex) + i); }; + + int qalignmentindex; + inline Quaternion qalignment(int i) const { Assert(i >= 0 && i < numbones); return *((Quaternion*)(((byte*)this) + qalignmentindex) + i); }; + + int unused[6]; + + mstudiolinearbone_t() {} +private: + mstudiolinearbone_t(const mstudiolinearbone_t& vOther); +}; + + +enum StudioBoneFlexComponent_t +{ + STUDIO_BONE_FLEX_INVALID = -1, + STUDIO_BONE_FLEX_TX = 0, + STUDIO_BONE_FLEX_TY = 1, + STUDIO_BONE_FLEX_TZ = 2 +}; + + +struct mstudioboneflexdrivercontrol_t +{ + DECLARE_BYTESWAP_DATADESC(); + + int m_nBoneComponent; + int m_nFlexControllerIndex; + float m_flMin; + float m_flMax; + + mstudioboneflexdrivercontrol_t() {} +private: + mstudioboneflexdrivercontrol_t(const mstudioboneflexdrivercontrol_t& vOther); +}; + + +struct mstudioboneflexdriver_t +{ + DECLARE_BYTESWAP_DATADESC(); + + int m_nBoneIndex; + int m_nControlCount; + int m_nControlIndex; + + inline mstudioboneflexdrivercontrol_t* pBoneFlexDriverControl(int i) const + { + Assert(i >= 0 && i < m_nControlCount); + return (mstudioboneflexdrivercontrol_t*)(((byte*)this) + m_nControlIndex) + i; + } + + int unused[3]; + + mstudioboneflexdriver_t() {} +private: + mstudioboneflexdriver_t(const mstudioboneflexdriver_t& vOther); +}; + + +#define BONE_CALCULATE_MASK 0x1F +#define BONE_PHYSICALLY_SIMULATED 0x01 +#define BONE_PHYSICS_PROCEDURAL 0x02 +#define BONE_ALWAYS_PROCEDURAL 0x04 +#define BONE_SCREEN_ALIGN_SPHERE 0x08 +#define BONE_SCREEN_ALIGN_CYLINDER 0x10 + +#define BONE_USED_MASK 0x0007FF00 +#define BONE_USED_BY_ANYTHING 0x0007FF00 +#define BONE_USED_BY_HITBOX 0x00000100 +#define BONE_USED_BY_ATTACHMENT 0x00000200 +#define BONE_USED_BY_VERTEX_MASK 0x0003FC00 +#define BONE_USED_BY_VERTEX_LOD0 0x00000400 +#define BONE_USED_BY_VERTEX_LOD1 0x00000800 +#define BONE_USED_BY_VERTEX_LOD2 0x00001000 +#define BONE_USED_BY_VERTEX_LOD3 0x00002000 +#define BONE_USED_BY_VERTEX_LOD4 0x00004000 +#define BONE_USED_BY_VERTEX_LOD5 0x00008000 +#define BONE_USED_BY_VERTEX_LOD6 0x00010000 +#define BONE_USED_BY_VERTEX_LOD7 0x00020000 +#define BONE_USED_BY_BONE_MERGE 0x00040000 + +#define BONE_USED_BY_VERTEX_AT_LOD(lod) ( BONE_USED_BY_VERTEX_LOD0 << (lod) ) +#define BONE_USED_BY_ANYTHING_AT_LOD(lod) ( ( BONE_USED_BY_ANYTHING & ~BONE_USED_BY_VERTEX_MASK ) | BONE_USED_BY_VERTEX_AT_LOD(lod) ) + +#define MAX_NUM_LODS 8 + +#define BONE_TYPE_MASK 0x00F00000 +#define BONE_FIXED_ALIGNMENT 0x00100000 + +#define BONE_HAS_SAVEFRAME_POS 0x00200000 +#define BONE_HAS_SAVEFRAME_ROT 0x00400000 + +struct mstudiobonecontroller_t +{ + DECLARE_BYTESWAP_DATADESC(); + int bone; + int type; + float start; + float end; + int rest; + int inputfield; + int unused[8]; +}; + +struct mstudiobbox_t +{ + DECLARE_BYTESWAP_DATADESC(); + int bone; + int group; + Vector bbmin; + Vector bbmax; + int szhitboxnameindex; + int unused[8]; + + const char* pszHitboxName() + { + if (szhitboxnameindex == 0) + return ""; + + return ((const char*)this) + szhitboxnameindex; + } + + mstudiobbox_t() {} + +private: + mstudiobbox_t(const mstudiobbox_t& vOther); +}; + +struct mstudiomodelgroup_t +{ + DECLARE_BYTESWAP_DATADESC(); + int szlabelindex; + inline char* const pszLabel(void) const { return ((char*)this) + szlabelindex; } + int sznameindex; + inline char* const pszName(void) const { return ((char*)this) + sznameindex; } +}; + +struct mstudiomodelgrouplookup_t +{ + int modelgroup; + int indexwithingroup; +}; + +struct mstudioevent_t +{ + DECLARE_BYTESWAP_DATADESC(); + float cycle; + int event; + int type; + inline const char* pszOptions(void) const { return options; } + char options[64]; + + int szeventindex; + inline char* const pszEventName(void) const { return ((char*)this) + szeventindex; } +}; + +#define ATTACHMENT_FLAG_WORLD_ALIGN 0x10000 + +struct mstudioattachment_t +{ + DECLARE_BYTESWAP_DATADESC(); + int sznameindex; + inline char* const pszName(void) const { return ((char*)this) + sznameindex; } + unsigned int flags; + int localbone; + matrix3x4_t local; + int unused[8]; +}; + +#define IK_SELF 1 +#define IK_WORLD 2 +#define IK_GROUND 3 +#define IK_RELEASE 4 +#define IK_ATTACHMENT 5 +#define IK_UNLATCH 6 + +struct mstudioikerror_t +{ + DECLARE_BYTESWAP_DATADESC(); + Vector pos; + Quaternion q; + + mstudioikerror_t() {} + +private: + mstudioikerror_t(const mstudioikerror_t& vOther); +}; + +union mstudioanimvalue_t; + +struct mstudiocompressedikerror_t +{ + DECLARE_BYTESWAP_DATADESC(); + float scale[6]; + short offset[6]; + inline mstudioanimvalue_t* pAnimvalue(int i) const { if (offset[i] > 0) return (mstudioanimvalue_t*)(((byte*)this) + offset[i]); else return NULL; }; + mstudiocompressedikerror_t() {} + +private: + mstudiocompressedikerror_t(const mstudiocompressedikerror_t& vOther); +}; + +struct mstudioikrule_t +{ + DECLARE_BYTESWAP_DATADESC(); + int index; + + int type; + int chain; + + int bone; + + int slot; + float height; + float radius; + float floor; + Vector pos; + Quaternion q; + + int compressedikerrorindex; + inline mstudiocompressedikerror_t* pCompressedError() const { return (mstudiocompressedikerror_t*)(((byte*)this) + compressedikerrorindex); }; + int unused2; + + int iStart; + int ikerrorindex; + inline mstudioikerror_t* pError(int i) const { return (ikerrorindex) ? (mstudioikerror_t*)(((byte*)this) + ikerrorindex) + (i - iStart) : NULL; }; + + float start; + float peak; + float tail; + float end; + + float unused3; + float contact; + float drop; + float top; + + int unused6; + int unused7; + int unused8; + + int szattachmentindex; + inline char* const pszAttachment(void) const { return ((char*)this) + szattachmentindex; } + + int unused[7]; + + mstudioikrule_t() {} + +private: + mstudioikrule_t(const mstudioikrule_t& vOther); +}; + + +struct mstudioiklock_t +{ + DECLARE_BYTESWAP_DATADESC(); + int chain; + float flPosWeight; + float flLocalQWeight; + int flags; + + int unused[4]; +}; + + +struct mstudiolocalhierarchy_t +{ + DECLARE_BYTESWAP_DATADESC(); + int iBone; + int iNewParent; + + float start; + float peak; + float tail; + float end; + + int iStart; + + int localanimindex; + inline mstudiocompressedikerror_t* pLocalAnim() const { return (mstudiocompressedikerror_t*)(((byte*)this) + localanimindex); }; + + int unused[4]; +}; + + + +union mstudioanimvalue_t +{ + struct + { + byte valid; + byte total; + } num; + short value; +}; + +struct mstudioanim_valueptr_t +{ + DECLARE_BYTESWAP_DATADESC(); + short offset[3]; + inline mstudioanimvalue_t* pAnimvalue(int i) const { if (offset[i] > 0) return (mstudioanimvalue_t*)(((byte*)this) + offset[i]); else return NULL; }; +}; + +#define STUDIO_ANIM_RAWPOS 0x01 +#define STUDIO_ANIM_RAWROT 0x02 +#define STUDIO_ANIM_ANIMPOS 0x04 +#define STUDIO_ANIM_ANIMROT 0x08 +#define STUDIO_ANIM_DELTA 0x10 +#define STUDIO_ANIM_RAWROT2 0x20 + + +struct mstudioanim_t +{ + DECLARE_BYTESWAP_DATADESC(); + byte bone; + byte flags; + + inline byte* pData(void) const { return (((byte*)this) + sizeof(struct mstudioanim_t)); }; + inline mstudioanim_valueptr_t* pRotV(void) const { return (mstudioanim_valueptr_t*)(pData()); }; + inline mstudioanim_valueptr_t* pPosV(void) const { return (mstudioanim_valueptr_t*)(pData()) + ((flags & STUDIO_ANIM_ANIMROT) != 0); }; + + inline Quaternion48* pQuat48(void) const { return (Quaternion48*)(pData()); }; + inline Quaternion64* pQuat64(void) const { return (Quaternion64*)(pData()); }; + inline Vector48* pPos(void) const { return (Vector48*)(pData() + ((flags & STUDIO_ANIM_RAWROT) != 0) * sizeof(*pQuat48()) + ((flags & STUDIO_ANIM_RAWROT2) != 0) * sizeof(*pQuat64())); }; + + short nextoffset; + inline mstudioanim_t* pNext(void) const { if (nextoffset != 0) return (mstudioanim_t*)(((byte*)this) + nextoffset); else return NULL; }; +}; + +struct mstudiomovement_t +{ + DECLARE_BYTESWAP_DATADESC(); + int endframe; + int motionflags; + float v0; + float v1; + float angle; + Vector vector; + Vector position; + + mstudiomovement_t() {} +private: + mstudiomovement_t(const mstudiomovement_t& vOther); +}; + +struct studiohdr_t; + +struct mstudioanimblock_t +{ + DECLARE_BYTESWAP_DATADESC(); + int datastart; + int dataend; +}; + +struct mstudioanimsections_t +{ + DECLARE_BYTESWAP_DATADESC(); + int animblock; + int animindex; +}; + +struct mstudioanimdesc_t +{ + DECLARE_BYTESWAP_DATADESC(); + int baseptr; + inline studiohdr_t* pStudiohdr(void) const { return (studiohdr_t*)(((byte*)this) + baseptr); } + + int sznameindex; + inline char* const pszName(void) const { return ((char*)this) + sznameindex; } + + float fps; + int flags; + + int numframes; + + int nummovements; + int movementindex; + inline mstudiomovement_t* const pMovement(int i) const { return (mstudiomovement_t*)(((byte*)this) + movementindex) + i; }; + + int unused1[6]; + + int animblock; + int animindex; + mstudioanim_t* pAnimBlock(int block, int index) const; + mstudioanim_t* pAnim(int* piFrame, float& flStall) const; + mstudioanim_t* pAnim(int* piFrame) const; + + int numikrules; + int ikruleindex; + int animblockikruleindex; + mstudioikrule_t* pIKRule(int i) const; + + int numlocalhierarchy; + int localhierarchyindex; + mstudiolocalhierarchy_t* pHierarchy(int i) const; + + int sectionindex; + int sectionframes; + inline mstudioanimsections_t* const pSection(int i) const { return (mstudioanimsections_t*)(((byte*)this) + sectionindex) + i; } + + short zeroframespan; + short zeroframecount; + int zeroframeindex; + byte* pZeroFrameData() const { if (zeroframeindex) return (((byte*)this) + zeroframeindex); else return NULL; }; + mutable float zeroframestalltime; + + mstudioanimdesc_t() {} +private: + mstudioanimdesc_t(const mstudioanimdesc_t& vOther); +}; + +struct mstudioikrule_t; + +struct mstudioautolayer_t +{ + DECLARE_BYTESWAP_DATADESC(); + short iSequence; + short iPose; + int flags; + float start; + float peak; + float tail; + float end; +}; + +struct mstudioactivitymodifier_t +{ + DECLARE_BYTESWAP_DATADESC(); + + int sznameindex; + inline char* pszName() { return (sznameindex) ? (char*)(((byte*)this) + sznameindex) : NULL; } +}; + +struct mstudioseqdesc_t +{ + DECLARE_BYTESWAP_DATADESC(); + int baseptr; + inline studiohdr_t* pStudiohdr(void) const { return (studiohdr_t*)(((byte*)this) + baseptr); } + + int szlabelindex; + inline char* const pszLabel(void) const { return ((char*)this) + szlabelindex; } + + int szactivitynameindex; + inline char* const pszActivityName(void) const { return ((char*)this) + szactivitynameindex; } + + int flags; + + int activity; + int actweight; + + int numevents; + int eventindex; + inline mstudioevent_t* pEvent(int i) const { Assert(i >= 0 && i < numevents); return (mstudioevent_t*)(((byte*)this) + eventindex) + i; }; + + Vector bbmin; + Vector bbmax; + + int numblends; + + int animindexindex; + + inline int anim(int x, int y) const + { + if (x >= groupsize[0]) + { + x = groupsize[0] - 1; + } + + if (y >= groupsize[1]) + { + y = groupsize[1] - 1; + } + + int offset = y * groupsize[0] + x; + short* blends = (short*)(((byte*)this) + animindexindex); + int value = (int)blends[offset]; + return value; + } + + int movementindex; + int groupsize[2]; + int paramindex[2]; + float paramstart[2]; + float paramend[2]; + int paramparent; + + float fadeintime; + float fadeouttime; + + int localentrynode; + int localexitnode; + int nodeflags; + + float entryphase; + float exitphase; + + float lastframe; + + int nextseq; + int pose; + + int numikrules; + + int numautolayers; + int autolayerindex; + inline mstudioautolayer_t* pAutolayer(int i) const { Assert(i >= 0 && i < numautolayers); return (mstudioautolayer_t*)(((byte*)this) + autolayerindex) + i; }; + + int weightlistindex; + inline float* pBoneweight(int i) const { return ((float*)(((byte*)this) + weightlistindex) + i); }; + inline float weight(int i) const { return *(pBoneweight(i)); }; + + int posekeyindex; + float* pPoseKey(int iParam, int iAnim) const { return (float*)(((byte*)this) + posekeyindex) + iParam * groupsize[0] + iAnim; } + float poseKey(int iParam, int iAnim) const { return *(pPoseKey(iParam, iAnim)); } + + int numiklocks; + int iklockindex; + inline mstudioiklock_t* pIKLock(int i) const { Assert(i >= 0 && i < numiklocks); return (mstudioiklock_t*)(((byte*)this) + iklockindex) + i; }; + + int keyvalueindex; + int keyvaluesize; + inline const char* KeyValueText(void) const { return keyvaluesize != 0 ? ((char*)this) + keyvalueindex : NULL; } + + int cycleposeindex; + + int activitymodifierindex; + int numactivitymodifiers; + inline mstudioactivitymodifier_t* pActivityModifier(int i) const { Assert(i >= 0 && i < numactivitymodifiers); return activitymodifierindex != 0 ? (mstudioactivitymodifier_t*)(((byte*)this) + activitymodifierindex) + i : NULL; }; + + int unused[5]; + + mstudioseqdesc_t() {} +private: + mstudioseqdesc_t(const mstudioseqdesc_t& vOther); +}; + + +struct mstudioposeparamdesc_t +{ + DECLARE_BYTESWAP_DATADESC(); + int sznameindex; + inline char* const pszName(void) const { return ((char*)this) + sznameindex; } + int flags; + float start; + float end; + float loop; +}; + +struct mstudioflexdesc_t +{ + DECLARE_BYTESWAP_DATADESC(); + int szFACSindex; + inline char* const pszFACS(void) const { return ((char*)this) + szFACSindex; } +}; + + + +struct mstudioflexcontroller_t +{ + DECLARE_BYTESWAP_DATADESC(); + int sztypeindex; + inline char* const pszType(void) const { return ((char*)this) + sztypeindex; } + int sznameindex; + inline char* const pszName(void) const { return ((char*)this) + sznameindex; } + mutable int localToGlobal; + float min; + float max; +}; + + +enum FlexControllerRemapType_t +{ + FLEXCONTROLLER_REMAP_PASSTHRU = 0, + FLEXCONTROLLER_REMAP_2WAY, + FLEXCONTROLLER_REMAP_NWAY, + FLEXCONTROLLER_REMAP_EYELID +}; + + +class CStudioHdr; +struct mstudioflexcontrollerui_t +{ + DECLARE_BYTESWAP_DATADESC(); + int sznameindex; + inline char* const pszName(void) const { return ((char*)this) + sznameindex; } + + int szindex0; + int szindex1; + int szindex2; + + inline const mstudioflexcontroller_t* pController(void) const + { + return !stereo ? (mstudioflexcontroller_t*)((char*)this + szindex0) : NULL; + } + inline char* const pszControllerName(void) const { return !stereo ? pController()->pszName() : NULL; } + inline int controllerIndex(const CStudioHdr& cStudioHdr) const; + + inline const mstudioflexcontroller_t* pLeftController(void) const + { + return stereo ? (mstudioflexcontroller_t*)((char*)this + szindex0) : NULL; + } + inline char* const pszLeftName(void) const { return stereo ? pLeftController()->pszName() : NULL; } + inline int leftIndex(const CStudioHdr& cStudioHdr) const; + + inline const mstudioflexcontroller_t* pRightController(void) const + { + return stereo ? (mstudioflexcontroller_t*)((char*)this + szindex1) : NULL; + } + inline char* const pszRightName(void) const { return stereo ? pRightController()->pszName() : NULL; } + inline int rightIndex(const CStudioHdr& cStudioHdr) const; + + inline const mstudioflexcontroller_t* pNWayValueController(void) const + { + return remaptype == FLEXCONTROLLER_REMAP_NWAY ? (mstudioflexcontroller_t*)((char*)this + szindex2) : NULL; + } + inline char* const pszNWayValueName(void) const { return remaptype == FLEXCONTROLLER_REMAP_NWAY ? pNWayValueController()->pszName() : NULL; } + inline int nWayValueIndex(const CStudioHdr& cStudioHdr) const; + + inline int Count() const { return (stereo ? 2 : 1) + (remaptype == FLEXCONTROLLER_REMAP_NWAY ? 1 : 0); } + inline const mstudioflexcontroller_t* pController(int index) const; + + unsigned char remaptype; + bool stereo; + byte unused[2]; +}; + + +struct mstudiovertanim_t +{ + DECLARE_BYTESWAP_DATADESC(); + unsigned short index; + byte speed; + byte side; + +protected: + union + { + short delta[3]; + float16 flDelta[3]; + }; + + union + { + short ndelta[3]; + float16 flNDelta[3]; + }; + +public: + inline void ConvertToFixed(float flVertAnimFixedPointScale) + { + delta[0] = flDelta[0].GetFloat() / flVertAnimFixedPointScale; + delta[1] = flDelta[1].GetFloat() / flVertAnimFixedPointScale; + delta[2] = flDelta[2].GetFloat() / flVertAnimFixedPointScale; + ndelta[0] = flNDelta[0].GetFloat() / flVertAnimFixedPointScale; + ndelta[1] = flNDelta[1].GetFloat() / flVertAnimFixedPointScale; + ndelta[2] = flNDelta[2].GetFloat() / flVertAnimFixedPointScale; + } + + inline Vector GetDeltaFixed(float flVertAnimFixedPointScale) + { + return Vector(delta[0] * flVertAnimFixedPointScale, delta[1] * flVertAnimFixedPointScale, delta[2] * flVertAnimFixedPointScale); + } + inline Vector GetNDeltaFixed(float flVertAnimFixedPointScale) + { + return Vector(ndelta[0] * flVertAnimFixedPointScale, ndelta[1] * flVertAnimFixedPointScale, ndelta[2] * flVertAnimFixedPointScale); + } + inline void GetDeltaFixed4DAligned(Vector4DAligned* vFillIn, float flVertAnimFixedPointScale) + { + vFillIn->Set(delta[0] * flVertAnimFixedPointScale, delta[1] * flVertAnimFixedPointScale, delta[2] * flVertAnimFixedPointScale, 0.0f); + } + inline void GetNDeltaFixed4DAligned(Vector4DAligned* vFillIn, float flVertAnimFixedPointScale) + { + vFillIn->Set(ndelta[0] * flVertAnimFixedPointScale, ndelta[1] * flVertAnimFixedPointScale, ndelta[2] * flVertAnimFixedPointScale, 0.0f); + } + inline Vector GetDeltaFloat() + { + return Vector(flDelta[0].GetFloat(), flDelta[1].GetFloat(), flDelta[2].GetFloat()); + } + inline Vector GetNDeltaFloat() + { + return Vector(flNDelta[0].GetFloat(), flNDelta[1].GetFloat(), flNDelta[2].GetFloat()); + } + inline void SetDeltaFixed(const Vector& vInput, float flVertAnimFixedPointScale) + { + delta[0] = vInput.x / flVertAnimFixedPointScale; + delta[1] = vInput.y / flVertAnimFixedPointScale; + delta[2] = vInput.z / flVertAnimFixedPointScale; + } + inline void SetNDeltaFixed(const Vector& vInputNormal, float flVertAnimFixedPointScale) + { + ndelta[0] = vInputNormal.x / flVertAnimFixedPointScale; + ndelta[1] = vInputNormal.y / flVertAnimFixedPointScale; + ndelta[2] = vInputNormal.z / flVertAnimFixedPointScale; + } + + inline void SetDeltaFloat(const Vector& vInput) + { + flDelta[0].SetFloat(vInput.x); + flDelta[1].SetFloat(vInput.y); + flDelta[2].SetFloat(vInput.z); + } + inline void SetNDeltaFloat(const Vector& vInputNormal) + { + flNDelta[0].SetFloat(vInputNormal.x); + flNDelta[1].SetFloat(vInputNormal.y); + flNDelta[2].SetFloat(vInputNormal.z); + } + + class CSortByIndex + { + public: + bool operator()(const mstudiovertanim_t& left, const mstudiovertanim_t& right)const + { + return left.index < right.index; + } + }; + friend class CSortByIndex; + + mstudiovertanim_t() {} +}; + + +struct mstudiovertanim_wrinkle_t : public mstudiovertanim_t +{ + DECLARE_BYTESWAP_DATADESC(); + + short wrinkledelta; + + inline void SetWrinkleFixed(float flWrinkle, float flVertAnimFixedPointScale) + { + int nWrinkleDeltaInt = flWrinkle / flVertAnimFixedPointScale; + wrinkledelta = clamp(nWrinkleDeltaInt, -32767, 32767); + } + + inline Vector4D GetDeltaFixed(float flVertAnimFixedPointScale) + { + return Vector4D(delta[0] * flVertAnimFixedPointScale, delta[1] * flVertAnimFixedPointScale, delta[2] * flVertAnimFixedPointScale, wrinkledelta * flVertAnimFixedPointScale); + } + + inline void GetDeltaFixed4DAligned(Vector4DAligned* vFillIn, float flVertAnimFixedPointScale) + { + vFillIn->Set(delta[0] * flVertAnimFixedPointScale, delta[1] * flVertAnimFixedPointScale, delta[2] * flVertAnimFixedPointScale, wrinkledelta * flVertAnimFixedPointScale); + } + + inline float GetWrinkleDeltaFixed(float flVertAnimFixedPointScale) + { + return wrinkledelta * flVertAnimFixedPointScale; + } +}; + + +enum StudioVertAnimType_t +{ + STUDIO_VERT_ANIM_NORMAL = 0, + STUDIO_VERT_ANIM_WRINKLE, +}; + +struct mstudioflex_t +{ + DECLARE_BYTESWAP_DATADESC(); + int flexdesc; + + float target0; + float target1; + float target2; + float target3; + + int numverts; + int vertindex; + + inline mstudiovertanim_t* pVertanim(int i) const { Assert(vertanimtype == STUDIO_VERT_ANIM_NORMAL); return (mstudiovertanim_t*)(((byte*)this) + vertindex) + i; }; + inline mstudiovertanim_wrinkle_t* pVertanimWrinkle(int i) const { Assert(vertanimtype == STUDIO_VERT_ANIM_WRINKLE); return (mstudiovertanim_wrinkle_t*)(((byte*)this) + vertindex) + i; }; + + inline byte* pBaseVertanim() const { return ((byte*)this) + vertindex; }; + inline int VertAnimSizeBytes() const { return (vertanimtype == STUDIO_VERT_ANIM_NORMAL) ? sizeof(mstudiovertanim_t) : sizeof(mstudiovertanim_wrinkle_t); } + + int flexpair; + unsigned char vertanimtype; + unsigned char unusedchar[3]; + int unused[6]; +}; + + +struct mstudioflexop_t +{ + DECLARE_BYTESWAP_DATADESC(); + int op; + union + { + int index; + float value; + } d; +}; + +struct mstudioflexrule_t +{ + DECLARE_BYTESWAP_DATADESC(); + int flex; + int numops; + int opindex; + inline mstudioflexop_t* iFlexOp(int i) const { return (mstudioflexop_t*)(((byte*)this) + opindex) + i; }; +}; + +struct mstudioboneweight_t +{ + DECLARE_BYTESWAP_DATADESC(); + float weight[MAX_NUM_BONES_PER_VERT]; + char bone[MAX_NUM_BONES_PER_VERT]; + byte numbones; + +}; + +struct mstudiovertex_t +{ + DECLARE_BYTESWAP_DATADESC(); + mstudioboneweight_t m_BoneWeights; + Vector m_vecPosition; + Vector m_vecNormal; + Vector2D m_vecTexCoord; + + mstudiovertex_t() {} + +private: + mstudiovertex_t(const mstudiovertex_t& vOther); +}; + +struct mstudiotexture_t +{ + DECLARE_BYTESWAP_DATADESC(); + int sznameindex; + inline char* const pszName(void) const { return ((char*)this) + sznameindex; } + int flags; + int used; + int unused1; + mutable IMaterial* material; + mutable void* clientmaterial; + + int unused[10]; +}; + +struct mstudioeyeball_t +{ + DECLARE_BYTESWAP_DATADESC(); + int sznameindex; + inline char* const pszName(void) const { return ((char*)this) + sznameindex; } + int bone; + Vector org; + float zoffset; + float radius; + Vector up; + Vector forward; + int texture; + + int unused1; + float iris_scale; + int unused2; + + int upperflexdesc[3]; + int lowerflexdesc[3]; + float uppertarget[3]; + float lowertarget[3]; + + int upperlidflexdesc; + int lowerlidflexdesc; + int unused[4]; + bool m_bNonFACS; + char unused3[3]; + int unused4[7]; + + mstudioeyeball_t() {} +private: + mstudioeyeball_t(const mstudioeyeball_t& vOther); +}; + + +struct mstudioiklink_t +{ + DECLARE_BYTESWAP_DATADESC(); + int bone; + Vector kneeDir; + Vector unused0; + + mstudioiklink_t() {} +private: + mstudioiklink_t(const mstudioiklink_t& vOther); +}; + +struct mstudioikchain_t +{ + DECLARE_BYTESWAP_DATADESC(); + int sznameindex; + inline char* const pszName(void) const { return ((char*)this) + sznameindex; } + int linktype; + int numlinks; + int linkindex; + inline mstudioiklink_t* pLink(int i) const { return (mstudioiklink_t*)(((byte*)this) + linkindex) + i; }; +}; + + +struct mstudioiface_t +{ + unsigned short a, b, c; +}; + + +struct mstudiomodel_t; + +struct mstudio_modelvertexdata_t +{ + DECLARE_BYTESWAP_DATADESC(); + Vector* Position(int i) const; + Vector* Normal(int i) const; + Vector4D* TangentS(int i) const; + Vector2D* Texcoord(int i) const; + mstudioboneweight_t* BoneWeights(int i) const; + mstudiovertex_t* Vertex(int i) const; + bool HasTangentData(void) const; + int GetGlobalVertexIndex(int i) const; + int GetGlobalTangentIndex(int i) const; + + const void* pVertexData; + const void* pTangentData; +}; + +struct mstudio_meshvertexdata_t +{ + DECLARE_BYTESWAP_DATADESC(); + Vector* Position(int i) const; + Vector* Normal(int i) const; + Vector4D* TangentS(int i) const; + Vector2D* Texcoord(int i) const; + mstudioboneweight_t* BoneWeights(int i) const; + mstudiovertex_t* Vertex(int i) const; + bool HasTangentData(void) const; + int GetModelVertexIndex(int i) const; + int GetGlobalVertexIndex(int i) const; + + const mstudio_modelvertexdata_t* modelvertexdata; + + int numLODVertexes[MAX_NUM_LODS]; +}; + +struct mstudiomesh_t +{ + DECLARE_BYTESWAP_DATADESC(); + int material; + + int modelindex; + mstudiomodel_t* pModel() const; + + int numvertices; + int vertexoffset; + + const mstudio_meshvertexdata_t* GetVertexData(void* pModelData = NULL); + const thinModelVertices_t* GetThinVertexData(void* pModelData = NULL); + + int numflexes; + int flexindex; + inline mstudioflex_t* pFlex(int i) const { return (mstudioflex_t*)(((byte*)this) + flexindex) + i; }; + + int materialtype; + int materialparam; + + int meshid; + + Vector center; + + mstudio_meshvertexdata_t vertexdata; + + int unused[8]; + + mstudiomesh_t() {} +private: + mstudiomesh_t(const mstudiomesh_t& vOther); +}; + +struct mstudiomodel_t +{ + DECLARE_BYTESWAP_DATADESC(); + inline const char* pszName(void) const { return name; } + char name[64]; + + int type; + + float boundingradius; + + int nummeshes; + int meshindex; + inline mstudiomesh_t* pMesh(int i) const { return (mstudiomesh_t*)(((byte*)this) + meshindex) + i; }; + + int numvertices; + int vertexindex; + int tangentsindex; + + const vertexFileHeader_t* CacheVertexData(void* pModelData); + + const mstudio_modelvertexdata_t* GetVertexData(void* pModelData = NULL); + const thinModelVertices_t* GetThinVertexData(void* pModelData = NULL); + + int numattachments; + int attachmentindex; + + int numeyeballs; + int eyeballindex; + inline mstudioeyeball_t* pEyeball(int i) { return (mstudioeyeball_t*)(((byte*)this) + eyeballindex) + i; }; + + mstudio_modelvertexdata_t vertexdata; + + int unused[8]; +}; + +inline bool mstudio_modelvertexdata_t::HasTangentData(void) const +{ + return (pTangentData != NULL); +} + +inline int mstudio_modelvertexdata_t::GetGlobalVertexIndex(int i) const +{ + mstudiomodel_t* modelptr = (mstudiomodel_t*)((byte*)this - offsetof(mstudiomodel_t, vertexdata)); + Assert((modelptr->vertexindex % sizeof(mstudiovertex_t)) == 0); + return (i + (modelptr->vertexindex / sizeof(mstudiovertex_t))); +} + +inline int mstudio_modelvertexdata_t::GetGlobalTangentIndex(int i) const +{ + mstudiomodel_t* modelptr = (mstudiomodel_t*)((byte*)this - offsetof(mstudiomodel_t, vertexdata)); + Assert((modelptr->tangentsindex % sizeof(Vector4D)) == 0); + return (i + (modelptr->tangentsindex / sizeof(Vector4D))); +} + +inline mstudiovertex_t* mstudio_modelvertexdata_t::Vertex(int i) const +{ + return (mstudiovertex_t*)pVertexData + GetGlobalVertexIndex(i); +} + +inline Vector* mstudio_modelvertexdata_t::Position(int i) const +{ + return &Vertex(i)->m_vecPosition; +} + +inline Vector* mstudio_modelvertexdata_t::Normal(int i) const +{ + return &Vertex(i)->m_vecNormal; +} + +inline Vector4D* mstudio_modelvertexdata_t::TangentS(int i) const +{ + return (Vector4D*)pTangentData + GetGlobalTangentIndex(i); +} + +inline Vector2D* mstudio_modelvertexdata_t::Texcoord(int i) const +{ + return &Vertex(i)->m_vecTexCoord; +} + +inline mstudioboneweight_t* mstudio_modelvertexdata_t::BoneWeights(int i) const +{ + return &Vertex(i)->m_BoneWeights; +} + +inline mstudiomodel_t* mstudiomesh_t::pModel() const +{ + return (mstudiomodel_t*)(((byte*)this) + modelindex); +} + +inline bool mstudio_meshvertexdata_t::HasTangentData(void) const +{ + return modelvertexdata->HasTangentData(); +} + +inline const mstudio_meshvertexdata_t* mstudiomesh_t::GetVertexData(void* pModelData) +{ + this->pModel()->GetVertexData(pModelData); + vertexdata.modelvertexdata = &(this->pModel()->vertexdata); + + if (!vertexdata.modelvertexdata->pVertexData) + return NULL; + + return &vertexdata; +} + +inline const thinModelVertices_t* mstudiomesh_t::GetThinVertexData(void* pModelData) +{ + return this->pModel()->GetThinVertexData(pModelData); +} + +inline int mstudio_meshvertexdata_t::GetModelVertexIndex(int i) const +{ + mstudiomesh_t* meshptr = (mstudiomesh_t*)((byte*)this - offsetof(mstudiomesh_t, vertexdata)); + return meshptr->vertexoffset + i; +} + +inline int mstudio_meshvertexdata_t::GetGlobalVertexIndex(int i) const +{ + return modelvertexdata->GetGlobalVertexIndex(GetModelVertexIndex(i)); +} + +inline Vector* mstudio_meshvertexdata_t::Position(int i) const +{ + return modelvertexdata->Position(GetModelVertexIndex(i)); +}; + +inline Vector* mstudio_meshvertexdata_t::Normal(int i) const +{ + return modelvertexdata->Normal(GetModelVertexIndex(i)); +}; + +inline Vector4D* mstudio_meshvertexdata_t::TangentS(int i) const +{ + return modelvertexdata->TangentS(GetModelVertexIndex(i)); +} + +inline Vector2D* mstudio_meshvertexdata_t::Texcoord(int i) const +{ + return modelvertexdata->Texcoord(GetModelVertexIndex(i)); +}; + +inline mstudioboneweight_t* mstudio_meshvertexdata_t::BoneWeights(int i) const +{ + return modelvertexdata->BoneWeights(GetModelVertexIndex(i)); +}; + +inline mstudiovertex_t* mstudio_meshvertexdata_t::Vertex(int i) const +{ + return modelvertexdata->Vertex(GetModelVertexIndex(i)); +} + +enum studiomeshgroupflags_t +{ + MESHGROUP_IS_FLEXED = 0x1, + MESHGROUP_IS_HWSKINNED = 0x2, + MESHGROUP_IS_DELTA_FLEXED = 0x4 +}; + + +struct studiomeshgroup_t +{ + IMesh* m_pMesh; + int m_NumStrips; + int m_Flags; + OptimizedModel::StripHeader_t* m_pStripData; + unsigned short* m_pGroupIndexToMeshIndex; + int m_NumVertices; + int* m_pUniqueTris; + unsigned short* m_pIndices; + bool m_MeshNeedsRestore; + short m_ColorMeshID; + IMorph* m_pMorph; + + inline unsigned short MeshIndex(int i) const { return m_pGroupIndexToMeshIndex[m_pIndices[i]]; } +}; + + +struct studiomeshdata_t +{ + int m_NumGroup; + studiomeshgroup_t* m_pMeshGroup; +}; + +struct studioloddata_t +{ + studiomeshdata_t* m_pMeshData; + float m_SwitchPoint; + int numMaterials; + IMaterial** ppMaterials; + int* pMaterialFlags; + + int* m_pHWMorphDecalBoneRemap; + int m_nDecalBoneCount; +}; + +struct studiohwdata_t +{ + int m_RootLOD; + int m_NumLODs; + studioloddata_t* m_pLODs; + int m_NumStudioMeshes; + + inline float LODMetric(float unitSphereSize) const { return (unitSphereSize != 0.0f) ? (100.0f / unitSphereSize) : 0.0f; } + inline int GetLODForMetric(float lodMetric) const + { + if (!m_NumLODs) + return 0; + + int numLODs = (m_pLODs[m_NumLODs - 1].m_SwitchPoint < 0.0f) ? m_NumLODs - 1 : m_NumLODs; + + for (int i = m_RootLOD; i < numLODs - 1; i++) + { + if (m_pLODs[i + 1].m_SwitchPoint > lodMetric) + return i; + } + + return numLODs - 1; + } +}; + +struct mstudiobodyparts_t +{ + DECLARE_BYTESWAP_DATADESC(); + int sznameindex; + inline char* const pszName(void) const { return ((char*)this) + sznameindex; } + int nummodels; + int base; + int modelindex; + inline mstudiomodel_t* pModel(int i) const { return (mstudiomodel_t*)(((byte*)this) + modelindex) + i; }; +}; + + +struct mstudiomouth_t +{ + DECLARE_BYTESWAP_DATADESC(); + int bone; + Vector forward; + int flexdesc; + + mstudiomouth_t() {} +private: + mstudiomouth_t(const mstudiomouth_t& vOther); +}; + +struct mstudiohitboxset_t +{ + DECLARE_BYTESWAP_DATADESC(); + int sznameindex; + inline char* const pszName(void) const { return ((char*)this) + sznameindex; } + int numhitboxes; + int hitboxindex; + inline mstudiobbox_t* pHitbox(int i) const { return (mstudiobbox_t*)(((byte*)this) + hitboxindex) + i; }; +}; + + +struct mstudiosrcbonetransform_t +{ + DECLARE_BYTESWAP_DATADESC(); + + int sznameindex; + inline const char* pszName(void) const { return ((char*)this) + sznameindex; } + matrix3x4_t pretransform; + matrix3x4_t posttransform; +}; + + +class virtualgroup_t +{ +public: + virtualgroup_t(void) { cache = NULL; }; + void* cache; + const studiohdr_t* GetStudioHdr(void) const; + + CUtlVector< int > boneMap; + CUtlVector< int > masterBone; + CUtlVector< int > masterSeq; + CUtlVector< int > masterAnim; + CUtlVector< int > masterAttachment; + CUtlVector< int > masterPose; + CUtlVector< int > masterNode; +}; + +struct virtualsequence_t +{ +#ifdef _XBOX + short flags; + short activity; + short group; + short index; +#else + int flags; + int activity; + int group; + int index; +#endif +}; + +struct virtualgeneric_t +{ +#ifdef _XBOX + short group; + short index; +#else + int group; + int index; +#endif +}; + + +struct virtualmodel_t +{ + void AppendSequences(int group, const studiohdr_t* pStudioHdr); + void AppendAnimations(int group, const studiohdr_t* pStudioHdr); + void AppendAttachments(int ground, const studiohdr_t* pStudioHdr); + void AppendPoseParameters(int group, const studiohdr_t* pStudioHdr); + void AppendBonemap(int group, const studiohdr_t* pStudioHdr); + void AppendNodes(int group, const studiohdr_t* pStudioHdr); + void AppendTransitions(int group, const studiohdr_t* pStudioHdr); + void AppendIKLocks(int group, const studiohdr_t* pStudioHdr); + void AppendModels(int group, const studiohdr_t* pStudioHdr); + void UpdateAutoplaySequences(const studiohdr_t* pStudioHdr); + + virtualgroup_t* pAnimGroup(int animation) { return &m_group[m_anim[animation].group]; } + virtualgroup_t* pSeqGroup(int sequence) + { + if ((unsigned)sequence >= (unsigned)m_seq.Count()) + { + Assert(0); + return 0; + } + return &m_group[m_seq[sequence].group]; + } + + CThreadFastMutex m_Lock; + + CUtlVector< virtualsequence_t > m_seq; + CUtlVector< virtualgeneric_t > m_anim; + CUtlVector< virtualgeneric_t > m_attachment; + CUtlVector< virtualgeneric_t > m_pose; + CUtlVector< virtualgroup_t > m_group; + CUtlVector< virtualgeneric_t > m_node; + CUtlVector< virtualgeneric_t > m_iklock; + CUtlVector< unsigned short > m_autoplaySequences; +}; + +struct thinModelVertices_t +{ + void Init(int numBoneInfluences, Vector* positions, unsigned short* normals, float* boneWeights, char* boneIndices) + { + Assert(positions != NULL); + Assert(normals != NULL); + Assert((numBoneInfluences >= 0) && (numBoneInfluences <= 3)); + Assert(numBoneInfluences > 0 ? !!boneIndices : !boneIndices); + Assert(numBoneInfluences > 1 ? !!boneWeights : !boneWeights); + m_numBoneInfluences = numBoneInfluences; + m_vecPositions = positions; + m_vecNormals = normals; + m_boneWeights = boneWeights; + m_boneIndices = boneIndices; + } + + void SetPosition(int vertIndex, const Vector& position) + { + Assert(m_vecPositions); + m_vecPositions[vertIndex] = position; + } + + void SetNormal(int vertIndex, const Vector& normal) + { + Assert(m_vecNormals); + unsigned int packedNormal; + PackNormal_UBYTE4(normal.x, normal.y, normal.z, &packedNormal); + m_vecNormals[vertIndex] = (unsigned short)(0x0000FFFF & packedNormal); + } + + void SetBoneWeights(int vertIndex, const mstudioboneweight_t& boneWeights) + { + Assert((m_numBoneInfluences >= 1) && (m_numBoneInfluences <= 3)); + Assert((boneWeights.numbones >= 1) && (boneWeights.numbones <= m_numBoneInfluences)); + int numStoredWeights = max(0, (m_numBoneInfluences - 1)); + float* pBaseWeight = m_boneWeights + vertIndex * numStoredWeights; + char* pBaseIndex = m_boneIndices + vertIndex * m_numBoneInfluences; + for (int i = 0; i < m_numBoneInfluences; i++) + { + pBaseIndex[i] = boneWeights.bone[i]; + } + for (int i = 0; i < numStoredWeights; i++) + { + pBaseWeight[i] = boneWeights.weight[i]; + } + } + + void GetMeshPosition(mstudiomesh_t* pMesh, int meshIndex, Vector* pPosition) const + { + Assert(pMesh); + GetPosition(pMesh->vertexdata.GetGlobalVertexIndex(meshIndex), pPosition); + } + + void GetMeshNormal(mstudiomesh_t* pMesh, int meshIndex, Vector* pNormal) const + { + Assert(pMesh); + GetNormal(pMesh->vertexdata.GetGlobalVertexIndex(meshIndex), pNormal); + } + + void GetMeshBoneWeights(mstudiomesh_t* pMesh, int meshIndex, mstudioboneweight_t* pBoneWeights) const + { + Assert(pMesh); + GetBoneWeights(pMesh->vertexdata.GetGlobalVertexIndex(meshIndex), pBoneWeights); + } + + void GetModelPosition(mstudiomodel_t* pModel, int modelIndex, Vector* pPosition) const + { + Assert(pModel); + GetPosition(pModel->vertexdata.GetGlobalVertexIndex(modelIndex), pPosition); + } + + void GetModelNormal(mstudiomodel_t* pModel, int modelIndex, Vector* pNormal) const + { + Assert(pModel); + GetNormal(pModel->vertexdata.GetGlobalVertexIndex(modelIndex), pNormal); + } + + void GetModelBoneWeights(mstudiomodel_t* pModel, int modelIndex, mstudioboneweight_t* pBoneWeights) const + { + Assert(pModel); + GetBoneWeights(pModel->vertexdata.GetGlobalVertexIndex(modelIndex), pBoneWeights); + } + +private: + void GetPosition(int vertIndex, Vector* pPosition) const + { + Assert(pPosition); + Assert(m_vecPositions); + *pPosition = m_vecPositions[vertIndex]; + } + + void GetNormal(int vertIndex, Vector* pNormal) const + { + Assert(pNormal); + Assert(m_vecNormals); + unsigned int packedNormal = 0x0000FFFF & m_vecNormals[vertIndex]; + UnpackNormal_UBYTE4(&packedNormal, pNormal->Base()); + } + + void GetBoneWeights(int vertIndex, mstudioboneweight_t* pBoneWeights) const + { + Assert(pBoneWeights); + Assert((m_numBoneInfluences <= 1) || (m_boneWeights != NULL)); + Assert((m_numBoneInfluences <= 0) || (m_boneIndices != NULL)); + int numStoredWeights = max(0, (m_numBoneInfluences - 1)); + float* pBaseWeight = m_boneWeights + vertIndex * numStoredWeights; + char* pBaseIndex = m_boneIndices + vertIndex * m_numBoneInfluences; + float sum = 0.0f; + for (int i = 0; i < MAX_NUM_BONES_PER_VERT; i++) + { + if (i < (m_numBoneInfluences - 1)) + pBoneWeights->weight[i] = pBaseWeight[i]; + else + pBoneWeights->weight[i] = 1.0f - sum; + sum += pBoneWeights->weight[i]; + + pBoneWeights->bone[i] = (i < m_numBoneInfluences) ? pBaseIndex[i] : 0; + } + + pBoneWeights->numbones = m_numBoneInfluences ? m_numBoneInfluences : 1; + } + + int m_numBoneInfluences; + float* m_boneWeights; + char* m_boneIndices; + Vector* m_vecPositions; + unsigned short* m_vecNormals; +}; + +#define MODEL_VERTEX_FILE_ID (('V'<<24)+('S'<<16)+('D'<<8)+'I') +#define MODEL_VERTEX_FILE_VERSION 4 +#define MODEL_VERTEX_FILE_THIN_ID (('V'<<24)+('C'<<16)+('D'<<8)+'I') + +struct vertexFileHeader_t +{ + DECLARE_BYTESWAP_DATADESC(); + int id; + int version; + int checksum; + int numLODs; + int numLODVertexes[MAX_NUM_LODS]; + int numFixups; + int fixupTableStart; + int vertexDataStart; + int tangentDataStart; + +public: + + const mstudiovertex_t* GetVertexData() const + { + if ((id == MODEL_VERTEX_FILE_ID) && (vertexDataStart != 0)) + return (mstudiovertex_t*)(vertexDataStart + (byte*)this); + else + return NULL; + } + const Vector4D* GetTangentData() const + { + if ((id == MODEL_VERTEX_FILE_ID) && (tangentDataStart != 0)) + return (Vector4D*)(tangentDataStart + (byte*)this); + else + return NULL; + } + const thinModelVertices_t* GetThinVertexData() const + { + if ((id == MODEL_VERTEX_FILE_THIN_ID) && (vertexDataStart != 0)) + return (thinModelVertices_t*)(vertexDataStart + (byte*)this); + else + return NULL; + } +}; + +inline const mstudio_modelvertexdata_t* mstudiomodel_t::GetVertexData(void* pModelData) +{ + const vertexFileHeader_t* pVertexHdr = CacheVertexData(pModelData); + if (!pVertexHdr) + { + vertexdata.pVertexData = NULL; + vertexdata.pTangentData = NULL; + return NULL; + } + + vertexdata.pVertexData = pVertexHdr->GetVertexData(); + vertexdata.pTangentData = pVertexHdr->GetTangentData(); + + if (!vertexdata.pVertexData) + return NULL; + + return &vertexdata; +} + +inline const thinModelVertices_t* mstudiomodel_t::GetThinVertexData(void* pModelData) +{ + const vertexFileHeader_t* pVertexHdr = CacheVertexData(pModelData); + if (!pVertexHdr) + return NULL; + + return pVertexHdr->GetThinVertexData(); +} + +struct vertexFileFixup_t +{ + DECLARE_BYTESWAP_DATADESC(); + int lod; + int sourceVertexID; + int numVertexes; +}; + +#define STUDIOHDR_FLAGS_AUTOGENERATED_HITBOX 0x00000001 + +#define STUDIOHDR_FLAGS_USES_ENV_CUBEMAP 0x00000002 + +#define STUDIOHDR_FLAGS_FORCE_OPAQUE 0x00000004 + +#define STUDIOHDR_FLAGS_TRANSLUCENT_TWOPASS 0x00000008 + +#define STUDIOHDR_FLAGS_STATIC_PROP 0x00000010 + +#define STUDIOHDR_FLAGS_USES_FB_TEXTURE 0x00000020 + +#define STUDIOHDR_FLAGS_HASSHADOWLOD 0x00000040 + +#define STUDIOHDR_FLAGS_USES_BUMPMAPPING 0x00000080 + +#define STUDIOHDR_FLAGS_USE_SHADOWLOD_MATERIALS 0x00000100 + +#define STUDIOHDR_FLAGS_OBSOLETE 0x00000200 + +#define STUDIOHDR_FLAGS_UNUSED 0x00000400 + +#define STUDIOHDR_FLAGS_NO_FORCED_FADE 0x00000800 + +#define STUDIOHDR_FLAGS_FORCE_PHONEME_CROSSFADE 0x00001000 + +#define STUDIOHDR_FLAGS_CONSTANT_DIRECTIONAL_LIGHT_DOT 0x00002000 + +#define STUDIOHDR_FLAGS_FLEXES_CONVERTED 0x00004000 + +#define STUDIOHDR_FLAGS_BUILT_IN_PREVIEW_MODE 0x00008000 + +#define STUDIOHDR_FLAGS_AMBIENT_BOOST 0x00010000 + +#define STUDIOHDR_FLAGS_DO_NOT_CAST_SHADOWS 0x00020000 + +#define STUDIOHDR_FLAGS_CAST_TEXTURE_SHADOWS 0x00040000 + + +#define STUDIOHDR_FLAGS_VERT_ANIM_FIXED_POINT_SCALE 0x00200000 + +struct studiohdr2_t +{ + DECLARE_BYTESWAP_DATADESC(); + int numsrcbonetransform; + int srcbonetransformindex; + + int illumpositionattachmentindex; + inline int IllumPositionAttachmentIndex() const { return illumpositionattachmentindex; } + + float flMaxEyeDeflection; + inline float MaxEyeDeflection() const { return flMaxEyeDeflection != 0.0f ? flMaxEyeDeflection : 0.866f; } + + int linearboneindex; + inline mstudiolinearbone_t* pLinearBones() const { return (linearboneindex) ? (mstudiolinearbone_t*)(((byte*)this) + linearboneindex) : NULL; } + + int sznameindex; + inline char* pszName() { return (sznameindex) ? (char*)(((byte*)this) + sznameindex) : NULL; } + + int m_nBoneFlexDriverCount; + int m_nBoneFlexDriverIndex; + inline mstudioboneflexdriver_t* pBoneFlexDriver(int i) const { Assert(i >= 0 && i < m_nBoneFlexDriverCount); return (mstudioboneflexdriver_t*)(((byte*)this) + m_nBoneFlexDriverIndex) + i; } + + int reserved[56]; +}; + +struct studiohdr_t +{ + DECLARE_BYTESWAP_DATADESC(); + int id; + int version; + int checksum; + inline const char* pszName(void) const { if (studiohdr2index && pStudioHdr2()->pszName()) return pStudioHdr2()->pszName(); else return name; } + char name[64]; + int length; + Vector eyeposition; + Vector illumposition; + Vector hull_min; + Vector hull_max; + Vector view_bbmin; + Vector view_bbmax; + int flags; + int numbones; + int boneindex; + inline mstudiobone_t* pBone(int i) const { Assert(i >= 0 && i < numbones); return (mstudiobone_t*)(((byte*)this) + boneindex) + i; }; + int RemapSeqBone(int iSequence, int iLocalBone) const; + int RemapAnimBone(int iAnim, int iLocalBone) const; + int numbonecontrollers; + int bonecontrollerindex; + inline mstudiobonecontroller_t* pBonecontroller(int i) const { Assert(i >= 0 && i < numbonecontrollers); return (mstudiobonecontroller_t*)(((byte*)this) + bonecontrollerindex) + i; }; + int numhitboxsets; + int hitboxsetindex; + + mstudiohitboxset_t* pHitboxSet(int i) const + { + Assert(i >= 0 && i < numhitboxsets); + return (mstudiohitboxset_t*)(((byte*)this) + hitboxsetindex) + i; + }; + + inline mstudiobbox_t* pHitbox(int i, int set) const + { + mstudiohitboxset_t const* s = pHitboxSet(set); + if (!s) + return NULL; + + return s->pHitbox(i); + }; + + inline int iHitboxCount(int set) const + { + mstudiohitboxset_t const* s = pHitboxSet(set); + if (!s) + return 0; + + return s->numhitboxes; + }; + + + int numlocalanim; + int localanimindex; + inline mstudioanimdesc_t* pLocalAnimdesc(int i) const { if (i < 0 || i >= numlocalanim) i = 0; return (mstudioanimdesc_t*)(((byte*)this) + localanimindex) + i; }; + + int numlocalseq; + int localseqindex; + inline mstudioseqdesc_t* pLocalSeqdesc(int i) const { if (i < 0 || i >= numlocalseq) i = 0; return (mstudioseqdesc_t*)(((byte*)this) + localseqindex) + i; }; + + bool SequencesAvailable() const; + int GetNumSeq() const; + mstudioanimdesc_t& pAnimdesc(int i) const; + mstudioseqdesc_t& pSeqdesc(int i) const; + int iRelativeAnim(int baseseq, int relanim) const; + int iRelativeSeq(int baseseq, int relseq) const; + + mutable int activitylistversion; + mutable int eventsindexed; + int GetSequenceActivity(int iSequence); + void SetSequenceActivity(int iSequence, int iActivity); + int GetActivityListVersion(void); + void SetActivityListVersion(int version) const; + int GetEventListVersion(void); + void SetEventListVersion(int version); + + int numtextures; + int textureindex; + inline mstudiotexture_t* pTexture(int i) const { Assert(i >= 0 && i < numtextures); return (mstudiotexture_t*)(((byte*)this) + textureindex) + i; }; + + + int numcdtextures; + int cdtextureindex; + inline char* pCdtexture(int i) const { return (((char*)this) + *((int*)(((byte*)this) + cdtextureindex) + i)); }; + + int numskinref; + int numskinfamilies; + int skinindex; + inline short* pSkinref(int i) const { return (short*)(((byte*)this) + skinindex) + i; }; + + int numbodyparts; + int bodypartindex; + inline mstudiobodyparts_t* pBodypart(int i) const { return (mstudiobodyparts_t*)(((byte*)this) + bodypartindex) + i; }; + + int numlocalattachments; + int localattachmentindex; + inline mstudioattachment_t* pLocalAttachment(int i) const { Assert(i >= 0 && i < numlocalattachments); return (mstudioattachment_t*)(((byte*)this) + localattachmentindex) + i; }; + int GetNumAttachments(void) const; + const mstudioattachment_t& pAttachment(int i) const; + int GetAttachmentBone(int i); + void SetAttachmentBone(int iAttachment, int iBone); + + int numlocalnodes; + int localnodeindex; + int localnodenameindex; + inline char* pszLocalNodeName(int iNode) const { Assert(iNode >= 0 && iNode < numlocalnodes); return (((char*)this) + *((int*)(((byte*)this) + localnodenameindex) + iNode)); } + inline byte* pLocalTransition(int i) const { Assert(i >= 0 && i < (numlocalnodes* numlocalnodes)); return (byte*)(((byte*)this) + localnodeindex) + i; }; + + int EntryNode(int iSequence); + int ExitNode(int iSequence); + char* pszNodeName(int iNode); + int GetTransition(int iFrom, int iTo) const; + + int numflexdesc; + int flexdescindex; + inline mstudioflexdesc_t* pFlexdesc(int i) const { Assert(i >= 0 && i < numflexdesc); return (mstudioflexdesc_t*)(((byte*)this) + flexdescindex) + i; }; + + int numflexcontrollers; + int flexcontrollerindex; + inline mstudioflexcontroller_t* pFlexcontroller(LocalFlexController_t i) const { Assert(numflexcontrollers == 0 || (i >= 0 && i < numflexcontrollers)); return (mstudioflexcontroller_t*)(((byte*)this) + flexcontrollerindex) + i; }; + + int numflexrules; + int flexruleindex; + inline mstudioflexrule_t* pFlexRule(int i) const { Assert(i >= 0 && i < numflexrules); return (mstudioflexrule_t*)(((byte*)this) + flexruleindex) + i; }; + + int numikchains; + int ikchainindex; + inline mstudioikchain_t* pIKChain(int i) const { Assert(i >= 0 && i < numikchains); return (mstudioikchain_t*)(((byte*)this) + ikchainindex) + i; }; + + int nummouths; + int mouthindex; + inline mstudiomouth_t* pMouth(int i) const { Assert(i >= 0 && i < nummouths); return (mstudiomouth_t*)(((byte*)this) + mouthindex) + i; }; + + int numlocalposeparameters; + int localposeparamindex; + inline mstudioposeparamdesc_t* pLocalPoseParameter(int i) const { Assert(i >= 0 && i < numlocalposeparameters); return (mstudioposeparamdesc_t*)(((byte*)this) + localposeparamindex) + i; }; + int GetNumPoseParameters(void) const; + const mstudioposeparamdesc_t& pPoseParameter(int i); + int GetSharedPoseParameter(int iSequence, int iLocalPose) const; + + int surfacepropindex; + inline char* const pszSurfaceProp(void) const { return ((char*)this) + surfacepropindex; } + + int keyvalueindex; + int keyvaluesize; + inline const char* KeyValueText(void) const { return keyvaluesize != 0 ? ((char*)this) + keyvalueindex : NULL; } + + int numlocalikautoplaylocks; + int localikautoplaylockindex; + inline mstudioiklock_t* pLocalIKAutoplayLock(int i) const { Assert(i >= 0 && i < numlocalikautoplaylocks); return (mstudioiklock_t*)(((byte*)this) + localikautoplaylockindex) + i; }; + + int GetNumIKAutoplayLocks(void) const; + const mstudioiklock_t& pIKAutoplayLock(int i); + int CountAutoplaySequences() const; + int CopyAutoplaySequences(unsigned short* pOut, int outCount) const; + int GetAutoplayList(unsigned short** pOut) const; + + float mass; + int contents; + + int numincludemodels; + int includemodelindex; + inline mstudiomodelgroup_t* pModelGroup(int i) const { Assert(i >= 0 && i < numincludemodels); return (mstudiomodelgroup_t*)(((byte*)this) + includemodelindex) + i; }; + const studiohdr_t* FindModel(void** cache, char const* modelname) const; + + mutable void* virtualModel; + virtualmodel_t* GetVirtualModel(void) const; + + int szanimblocknameindex; + inline char* const pszAnimBlockName(void) const { return ((char*)this) + szanimblocknameindex; } + int numanimblocks; + int animblockindex; + inline mstudioanimblock_t* pAnimBlock(int i) const { Assert(i > 0 && i < numanimblocks); return (mstudioanimblock_t*)(((byte*)this) + animblockindex) + i; }; + mutable void* animblockModel; + byte* GetAnimBlock(int i) const; + + int bonetablebynameindex; + inline const byte* GetBoneTableSortedByName() const { return (byte*)this + bonetablebynameindex; } + + void* pVertexBase; + void* pIndexBase; + + byte constdirectionallightdot; + + byte rootLOD; + + byte numAllowedRootLODs; + + byte unused[1]; + + int unused4; + + int numflexcontrollerui; + int flexcontrolleruiindex; + mstudioflexcontrollerui_t* pFlexControllerUI(int i) const { Assert(i >= 0 && i < numflexcontrollerui); return (mstudioflexcontrollerui_t*)(((byte*)this) + flexcontrolleruiindex) + i; } + + float flVertAnimFixedPointScale; + inline float VertAnimFixedPointScale() const { return (flags & STUDIOHDR_FLAGS_VERT_ANIM_FIXED_POINT_SCALE) ? flVertAnimFixedPointScale : 1.0f / 4096.0f; } + + int unused3[1]; + + int studiohdr2index; + studiohdr2_t* pStudioHdr2() const { return (studiohdr2_t*)(((byte*)this) + studiohdr2index); } + + int NumSrcBoneTransforms() const { return studiohdr2index ? pStudioHdr2()->numsrcbonetransform : 0; } + const mstudiosrcbonetransform_t* SrcBoneTransform(int i) const { Assert(i >= 0 && i < NumSrcBoneTransforms()); return (mstudiosrcbonetransform_t*)(((byte*)this) + pStudioHdr2()->srcbonetransformindex) + i; } + + inline int IllumPositionAttachmentIndex() const { return studiohdr2index ? pStudioHdr2()->IllumPositionAttachmentIndex() : 0; } + + inline float MaxEyeDeflection() const { return studiohdr2index ? pStudioHdr2()->MaxEyeDeflection() : 0.866f; } + + inline mstudiolinearbone_t* pLinearBones() const { return studiohdr2index ? pStudioHdr2()->pLinearBones() : NULL; } + + inline int BoneFlexDriverCount() const { return studiohdr2index ? pStudioHdr2()->m_nBoneFlexDriverCount : 0; } + inline const mstudioboneflexdriver_t* BoneFlexDriver(int i) const { Assert(i >= 0 && i < BoneFlexDriverCount()); return studiohdr2index ? pStudioHdr2()->pBoneFlexDriver(i) : NULL; } + + int unused2[1]; + + studiohdr_t() {} + +private: + studiohdr_t(const studiohdr_t& vOther); + + friend struct virtualmodel_t; +}; + + + +class IDataCache; +class IMDLCache; + +class CStudioHdr +{ +public: + CStudioHdr(void); + CStudioHdr(const studiohdr_t* pStudioHdr, IMDLCache* mdlcache = NULL); + ~CStudioHdr() { Term(); } + + void Init(const studiohdr_t* pStudioHdr, IMDLCache* mdlcache = NULL); + void Term(); + +public: + inline bool IsVirtual(void) { return (m_pVModel != NULL); }; + inline bool IsValid(void) { return (m_pStudioHdr != NULL); }; + inline bool IsReadyForAccess(void) const { return (m_pStudioHdr != NULL); }; + inline virtualmodel_t* GetVirtualModel(void) const { return m_pVModel; }; + inline const studiohdr_t* GetRenderHdr(void) const { return m_pStudioHdr; }; + const studiohdr_t* pSeqStudioHdr(int sequence); + const studiohdr_t* pAnimStudioHdr(int animation); + +private: + mutable const studiohdr_t* m_pStudioHdr; + mutable virtualmodel_t* m_pVModel; + + const virtualmodel_t* ResetVModel(const virtualmodel_t* pVModel) const; + const studiohdr_t* GroupStudioHdr(int group); + mutable CUtlVector< const studiohdr_t* > m_pStudioHdrCache; + + mutable int m_nFrameUnlockCounter; + int* m_pFrameUnlockCounter; + CThreadFastMutex m_FrameUnlockCounterMutex; + +public: + inline int numbones(void) const { return m_pStudioHdr->numbones; }; + inline mstudiobone_t* pBone(int i) const { return m_pStudioHdr->pBone(i); }; + int RemapAnimBone(int iAnim, int iLocalBone) const; + int RemapSeqBone(int iSequence, int iLocalBone) const; + + bool SequencesAvailable() const; + int GetNumSeq(void) const; + mstudioanimdesc_t& pAnimdesc(int i); + mstudioseqdesc_t& pSeqdesc(int iSequence); + int iRelativeAnim(int baseseq, int relanim) const; + int iRelativeSeq(int baseseq, int relseq) const; + + int GetSequenceActivity(int iSequence); + void SetSequenceActivity(int iSequence, int iActivity); + int GetActivityListVersion(void); + void SetActivityListVersion(int version); + int GetEventListVersion(void); + void SetEventListVersion(int version); + + int GetNumAttachments(void) const; + const mstudioattachment_t& pAttachment(int i); + int GetAttachmentBone(int i); + void SetAttachmentBone(int iAttachment, int iBone); + + int EntryNode(int iSequence); + int ExitNode(int iSequence); + char* pszNodeName(int iNode); + int GetTransition(int iFrom, int iTo) const; + + int GetNumPoseParameters(void) const; + const mstudioposeparamdesc_t& pPoseParameter(int i); + int GetSharedPoseParameter(int iSequence, int iLocalPose) const; + + int GetNumIKAutoplayLocks(void) const; + const mstudioiklock_t& pIKAutoplayLock(int i); + + inline int CountAutoplaySequences() const { return m_pStudioHdr->CountAutoplaySequences(); }; + inline int CopyAutoplaySequences(unsigned short* pOut, int outCount) const { return m_pStudioHdr->CopyAutoplaySequences(pOut, outCount); }; + inline int GetAutoplayList(unsigned short** pOut) const { return m_pStudioHdr->GetAutoplayList(pOut); }; + + inline int GetNumBoneControllers(void) const { return m_pStudioHdr->numbonecontrollers; }; + inline mstudiobonecontroller_t* pBonecontroller(int i) const { return m_pStudioHdr->pBonecontroller(i); }; + + inline int numikchains() const { return m_pStudioHdr->numikchains; }; + inline int GetNumIKChains(void) const { return m_pStudioHdr->numikchains; }; + inline mstudioikchain_t* pIKChain(int i) const { return m_pStudioHdr->pIKChain(i); }; + + inline int numflexrules() const { return m_pStudioHdr->numflexrules; }; + inline mstudioflexrule_t* pFlexRule(int i) const { return m_pStudioHdr->pFlexRule(i); }; + + inline int numflexdesc() const { return m_pStudioHdr->numflexdesc; }; + inline mstudioflexdesc_t* pFlexdesc(int i) const { return m_pStudioHdr->pFlexdesc(i); }; + + inline LocalFlexController_t numflexcontrollers() const { return (LocalFlexController_t)m_pStudioHdr->numflexcontrollers; }; + inline mstudioflexcontroller_t* pFlexcontroller(LocalFlexController_t i) const { return m_pStudioHdr->pFlexcontroller(i); }; + + inline int numflexcontrollerui() const { return m_pStudioHdr->numflexcontrollerui; }; + inline mstudioflexcontrollerui_t* pFlexcontrollerUI(int i) const { return m_pStudioHdr->pFlexControllerUI(i); }; + + inline const char* pszName() const { return m_pStudioHdr->pszName(); }; + + inline int numbonecontrollers() const { return m_pStudioHdr->numbonecontrollers; }; + + inline int numhitboxsets() const { return m_pStudioHdr->numhitboxsets; }; + inline mstudiohitboxset_t* pHitboxSet(int i) const { return m_pStudioHdr->pHitboxSet(i); }; + + inline mstudiobbox_t* pHitbox(int i, int set) const { return m_pStudioHdr->pHitbox(i, set); }; + inline int iHitboxCount(int set) const { return m_pStudioHdr->iHitboxCount(set); }; + + inline int numbodyparts() const { return m_pStudioHdr->numbodyparts; }; + inline mstudiobodyparts_t* pBodypart(int i) const { return m_pStudioHdr->pBodypart(i); }; + + inline int numskinfamilies() const { return m_pStudioHdr->numskinfamilies; } + + inline Vector eyeposition() const { return m_pStudioHdr->eyeposition; }; + + inline int flags() const { return m_pStudioHdr->flags; }; + + inline char* const pszSurfaceProp(void) const { return m_pStudioHdr->pszSurfaceProp(); }; + + inline float mass() const { return m_pStudioHdr->mass; }; + inline int contents() const { return m_pStudioHdr->contents; } + + inline const byte* GetBoneTableSortedByName() const { return m_pStudioHdr->GetBoneTableSortedByName(); }; + + inline Vector illumposition() const { return m_pStudioHdr->illumposition; }; + + inline Vector hull_min() const { return m_pStudioHdr->hull_min; }; + inline Vector hull_max() const { return m_pStudioHdr->hull_max; }; + + inline Vector view_bbmin() const { return m_pStudioHdr->view_bbmin; }; + inline Vector view_bbmax() const { return m_pStudioHdr->view_bbmax; }; + + inline int numtextures() const { return m_pStudioHdr->numtextures; }; + + inline int IllumPositionAttachmentIndex() const { return m_pStudioHdr->IllumPositionAttachmentIndex(); } + + inline float MaxEyeDeflection() const { return m_pStudioHdr->MaxEyeDeflection(); } + + inline mstudiolinearbone_t* pLinearBones() const { return m_pStudioHdr->pLinearBones(); } + + inline int BoneFlexDriverCount() const { return m_pStudioHdr->BoneFlexDriverCount(); } + inline const mstudioboneflexdriver_t* BoneFlexDriver(int i) const { return m_pStudioHdr->BoneFlexDriver(i); } + + inline float VertAnimFixedPointScale() const { return m_pStudioHdr->VertAnimFixedPointScale(); } + +public: + int IsSequenceLooping(int iSequence); + float GetSequenceCycleRate(int iSequence); + + void RunFlexRules(const float* src, float* dest); + + +public: + inline int boneFlags(int iBone) const { return m_boneFlags[iBone]; } + inline int boneParent(int iBone) const { return m_boneParent[iBone]; } + +private: + CUtlVector< int > m_boneFlags; + CUtlVector< int > m_boneParent; + +public: + + class CActivityToSequenceMapping + { + public: + struct SequenceTuple + { + short seqnum; + short weight; + CUtlSymbol* pActivityModifiers; + int iNumActivityModifiers; + }; + + struct HashValueType + { + int activityIdx; + + int startingIdx; + int count; + int totalWeight; + + HashValueType(int _actIdx, int _stIdx, int _ct, int _tW) : + activityIdx(_actIdx), startingIdx(_stIdx), count(_ct), totalWeight(_tW) {} + + HashValueType() : activityIdx(-1), startingIdx(-1), count(-1), totalWeight(-1) + { + AssertMsg(false, "Don't use default HashValueType()!"); + } + + + class HashFuncs + { + public: + HashFuncs(int) {} + + bool operator()(const HashValueType& lhs, const HashValueType& rhs) const + { + return lhs.activityIdx == rhs.activityIdx; + } + + unsigned int operator()(const HashValueType& item) const + { + return HashInt(item.activityIdx); + } + }; + }; + + typedef CUtlHash ActivityToValueIdxHash; + + CActivityToSequenceMapping(void) + : m_pSequenceTuples(NULL), m_iSequenceTuplesCount(0), m_ActToSeqHash(8, 0, 0), m_expectedPStudioHdr(NULL), m_expectedVModel(NULL) +#if STUDIO_SEQUENCE_ACTIVITY_LAZY_INITIALIZE + , m_bIsInitialized(false) +#endif + {}; + + ~CActivityToSequenceMapping() + { + if (m_pSequenceTuples != NULL) + { + if (m_pSequenceTuples->pActivityModifiers != NULL) + { + delete[] m_pSequenceTuples->pActivityModifiers; + } + delete[] m_pSequenceTuples; + } + } + + const SequenceTuple* GetSequences(int forActivity, int* outSequenceCount, int* outTotalWeight); + + int NumSequencesForActivity(int forActivity); + +#if STUDIO_SEQUENCE_ACTIVITY_LAZY_INITIALIZE + inline bool IsInitialized(void) { return m_bIsInitialized; } +#endif + + private: + + void Initialize(CStudioHdr* pstudiohdr); + + void Reinitialize(CStudioHdr* pstudiohdr); + + int SelectWeightedSequence(CStudioHdr* pstudiohdr, int activity, int curSequence); + + int SelectWeightedSequenceFromModifiers(CStudioHdr* pstudiohdr, int activity, CUtlSymbol* pActivityModifiers, int iModifierCount); + + SequenceTuple* m_pSequenceTuples; + unsigned int m_iSequenceTuplesCount; +#if STUDIO_SEQUENCE_ACTIVITY_LAZY_INITIALIZE + bool m_bIsInitialized; +#endif + + ActivityToValueIdxHash m_ActToSeqHash; + + const void* m_expectedPStudioHdr; + const void* m_expectedVModel; + + bool ValidateAgainst(const CStudioHdr* RESTRICT pstudiohdr); + void SetValidationPair(const CStudioHdr* RESTRICT pstudiohdr); + + friend class CStudioHdr; + }; + + CActivityToSequenceMapping m_ActivityToSequence; + + inline int SelectWeightedSequence(int activity, int curSequence) + { +#if STUDIO_SEQUENCE_ACTIVITY_LAZY_INITIALIZE + if (!m_ActivityToSequence.IsInitialized()) + { + m_ActivityToSequence.Initialize(this); + } +#endif + return m_ActivityToSequence.SelectWeightedSequence(this, activity, curSequence); + } + + inline int SelectWeightedSequenceFromModifiers(int activity, CUtlSymbol* pActivityModifiers, int iModifierCount) + { +#if STUDIO_SEQUENCE_ACTIVITY_LAZY_INITIALIZE + if (!m_ActivityToSequence.IsInitialized()) + { + m_ActivityToSequence.Initialize(this); + } +#endif + return m_ActivityToSequence.SelectWeightedSequenceFromModifiers(this, activity, pActivityModifiers, iModifierCount); + } + + inline bool HaveSequenceForActivity(int activity) + { +#if STUDIO_SEQUENCE_ACTIVITY_LAZY_INITIALIZE + if (!m_ActivityToSequence.IsInitialized()) + { + m_ActivityToSequence.Initialize(this); + } +#endif + return (m_ActivityToSequence.NumSequencesForActivity(activity) > 0); + } + + inline void ReinitializeSequenceMapping(void) + { + m_ActivityToSequence.Reinitialize(this); + } + +#ifdef STUDIO_ENABLE_PERF_COUNTERS +public: + inline void ClearPerfCounters(void) + { + m_nPerfAnimatedBones = 0; + m_nPerfUsedBones = 0; + m_nPerfAnimationLayers = 0; + }; + + mutable int m_nPerfAnimatedBones; + mutable int m_nPerfUsedBones; + mutable int m_nPerfAnimationLayers; +#endif + + +}; + +struct flexweight_t +{ + DECLARE_BYTESWAP_DATADESC(); + int key; + float weight; + float influence; +}; + +struct flexsetting_t +{ + DECLARE_BYTESWAP_DATADESC(); + int nameindex; + + inline char* pszName(void) const + { + return (char*)(((byte*)this) + nameindex); + } + + int obsolete1; + + int numsettings; + int index; + + int obsolete2; + + int settingindex; + + inline int psetting(byte* base, int i, flexweight_t** weights) const; +}; + + +struct flexsettinghdr_t +{ + DECLARE_BYTESWAP_DATADESC(); + int id; + int version; + + inline const char* pszName(void) const { return name; } + char name[64]; + int length; + + int numflexsettings; + int flexsettingindex; + inline flexsetting_t* pSetting(int i) const { return (flexsetting_t*)(((byte*)this) + flexsettingindex) + i; }; + int nameindex; + + int numindexes; + int indexindex; + + inline flexsetting_t* pIndexedSetting(int index) const + { + if (index < 0 || index >= numindexes) + { + return NULL; + } + + int i = *((int*)(((byte*)this) + indexindex) + index); + + if (i == -1) + { + return NULL; + } + + return pSetting(i); + } + + int numkeys; + int keynameindex; + inline char* pLocalName(int i) const { return (char*)(((byte*)this) + *((int*)(((byte*)this) + keynameindex) + i)); }; + + int keymappingindex; + inline int* pLocalToGlobal(int i) const { return (int*)(((byte*)this) + keymappingindex) + i; }; + inline int LocalToGlobal(int i) const { return *pLocalToGlobal(i); }; +}; + +inline int flexsetting_t::psetting(byte* base, int i, flexweight_t** weights) const +{ + *weights = (flexweight_t*)(((byte*)this) + settingindex) + i; + return numsettings; +}; + + +inline int mstudioflexcontrollerui_t::controllerIndex(const CStudioHdr& cStudioHdr) const +{ + return !stereo ? pController() - cStudioHdr.pFlexcontroller((LocalFlexController_t)0) : -1; +} + + +inline int mstudioflexcontrollerui_t::rightIndex(const CStudioHdr& cStudioHdr) const +{ + return stereo ? pRightController() - cStudioHdr.pFlexcontroller((LocalFlexController_t)0) : -1; +} + + +inline int mstudioflexcontrollerui_t::leftIndex(const CStudioHdr& cStudioHdr) const +{ + return stereo ? pLeftController() - cStudioHdr.pFlexcontroller((LocalFlexController_t)0) : -1; +} + + +inline int mstudioflexcontrollerui_t::nWayValueIndex(const CStudioHdr& cStudioHdr) const +{ + return remaptype == FLEXCONTROLLER_REMAP_NWAY ? pNWayValueController() - cStudioHdr.pFlexcontroller((LocalFlexController_t)0) : -1; +} + + +inline const mstudioflexcontroller_t* mstudioflexcontrollerui_t::pController(int index) const +{ + if (index < 0 || index > Count()) + return NULL; + + if (remaptype == FLEXCONTROLLER_REMAP_NWAY) + { + if (stereo) + return (mstudioflexcontroller_t*)((char*)this) + *(&szindex0 + index); + + if (index == 0) + return pController(); + + if (index == 1) + return pNWayValueController(); + + return NULL; + } + + if (index > 1) + return NULL; + + if (stereo) + return (mstudioflexcontroller_t*)((char*)this) + *(&szindex0 + index); + + if (index > 0) + return NULL; + + return pController(); +} + + +#define STUDIO_CONST 1 +#define STUDIO_FETCH1 2 +#define STUDIO_FETCH2 3 +#define STUDIO_ADD 4 +#define STUDIO_SUB 5 +#define STUDIO_MUL 6 +#define STUDIO_DIV 7 +#define STUDIO_NEG 8 +#define STUDIO_EXP 9 +#define STUDIO_OPEN 10 +#define STUDIO_CLOSE 11 +#define STUDIO_COMMA 12 +#define STUDIO_MAX 13 +#define STUDIO_MIN 14 +#define STUDIO_2WAY_0 15 +#define STUDIO_2WAY_1 16 +#define STUDIO_NWAY 17 +#define STUDIO_COMBO 18 +#define STUDIO_DOMINATE 19 +#define STUDIO_DME_LOWER_EYELID 20 +#define STUDIO_DME_UPPER_EYELID 21 + +#define STUDIO_X 0x00000001 +#define STUDIO_Y 0x00000002 +#define STUDIO_Z 0x00000004 +#define STUDIO_XR 0x00000008 +#define STUDIO_YR 0x00000010 +#define STUDIO_ZR 0x00000020 + +#define STUDIO_LX 0x00000040 +#define STUDIO_LY 0x00000080 +#define STUDIO_LZ 0x00000100 +#define STUDIO_LXR 0x00000200 +#define STUDIO_LYR 0x00000400 +#define STUDIO_LZR 0x00000800 + +#define STUDIO_LINEAR 0x00001000 + +#define STUDIO_TYPES 0x0003FFFF +#define STUDIO_RLOOP 0x00040000 + +#define STUDIO_LOOPING 0x0001 +#define STUDIO_SNAP 0x0002 +#define STUDIO_DELTA 0x0004 +#define STUDIO_AUTOPLAY 0x0008 +#define STUDIO_POST 0x0010 +#define STUDIO_ALLZEROS 0x0020 +#define STUDIO_CYCLEPOSE 0x0080 +#define STUDIO_REALTIME 0x0100 +#define STUDIO_LOCAL 0x0200 +#define STUDIO_HIDDEN 0x0400 +#define STUDIO_OVERRIDE 0x0800 +#define STUDIO_ACTIVITY 0x1000 +#define STUDIO_EVENT 0x2000 +#define STUDIO_WORLD 0x4000 +#define STUDIO_AL_POST 0x0010 +#define STUDIO_AL_SPLINE 0x0040 +#define STUDIO_AL_XFADE 0x0080 +#define STUDIO_AL_NOBLEND 0x0200 +#define STUDIO_AL_LOCAL 0x1000 +#define STUDIO_AL_POSE 0x4000 + + +inline bool Studio_ConvertStudioHdrToNewVersion(studiohdr_t* pStudioHdr) +{ + COMPILE_TIME_ASSERT(STUDIO_VERSION == 48); + + int version = pStudioHdr->version; + if (version == STUDIO_VERSION) + return true; + + bool bResult = true; + if (version < 46) + { + for (int i = 0; i < pStudioHdr->numlocalanim; i++) + { + mstudioanimdesc_t* pAnim = (mstudioanimdesc_t*)pStudioHdr->pLocalAnimdesc(i); + + if (pAnim->sectionframes != 0) + { + memset(&(pAnim->numframes), 0, (byte*)(pAnim + 1) - (byte*)&(pAnim->numframes)); + + pAnim->numframes = 1; + pAnim->animblock = -1; + bResult = false; + } + } + } + + if (version < 47) + { + if (pStudioHdr->unused4 != 0) + { + pStudioHdr->unused4 = 0; + bResult = false; + } + for (int i = 0; i < pStudioHdr->numlocalanim; i++) + { + mstudioanimdesc_t* pAnim = (mstudioanimdesc_t*)pStudioHdr->pLocalAnimdesc(i); + pAnim->zeroframeindex = 0; + pAnim->zeroframespan = 0; + } + } + else if (version == 47) + { + for (int i = 0; i < pStudioHdr->numlocalanim; i++) + { + mstudioanimdesc_t* pAnim = (mstudioanimdesc_t*)pStudioHdr->pLocalAnimdesc(i); + if (pAnim->zeroframeindex != 0) + { + pAnim->zeroframeindex = 0; + pAnim->zeroframespan = 0; + bResult = false; + } + } + } + + pStudioHdr->version = STUDIO_VERSION; + + return bResult; +} + +inline void Studio_SetRootLOD(studiohdr_t* pStudioHdr, int rootLOD) +{ + if (pStudioHdr->numAllowedRootLODs > 0 && + rootLOD >= pStudioHdr->numAllowedRootLODs) + { + rootLOD = pStudioHdr->numAllowedRootLODs - 1; + } + + Assert(rootLOD >= 0 && rootLOD < MAX_NUM_LODS); + Clamp(rootLOD, 0, MAX_NUM_LODS - 1); + + int vertexindex = 0; + int tangentsindex = 0; + int bodyPartID; + for (bodyPartID = 0; bodyPartID < pStudioHdr->numbodyparts; bodyPartID++) + { + mstudiobodyparts_t* pBodyPart = pStudioHdr->pBodypart(bodyPartID); + int modelID; + for (modelID = 0; modelID < pBodyPart->nummodels; modelID++) + { + mstudiomodel_t* pModel = pBodyPart->pModel(modelID); + int totalMeshVertexes = 0; + int meshID; + for (meshID = 0; meshID < pModel->nummeshes; meshID++) + { + mstudiomesh_t* pMesh = pModel->pMesh(meshID); + + pMesh->numvertices = pMesh->vertexdata.numLODVertexes[rootLOD]; + pMesh->vertexoffset = totalMeshVertexes; + totalMeshVertexes += pMesh->numvertices; + } + + pModel->numvertices = totalMeshVertexes; + pModel->vertexindex = vertexindex; + pModel->tangentsindex = tangentsindex; + + vertexindex += totalMeshVertexes * sizeof(mstudiovertex_t); + tangentsindex += totalMeshVertexes * sizeof(Vector4D); + } + } + + pStudioHdr->rootLOD = rootLOD; +} + +inline int Studio_VertexDataSize(const vertexFileHeader_t* pVvdHdr, int rootLOD, bool bNeedsTangentS) +{ + int numVertexes = pVvdHdr->numLODVertexes[rootLOD] + 1; + int dataLength = pVvdHdr->vertexDataStart + numVertexes * sizeof(mstudiovertex_t); + if (bNeedsTangentS) + { + dataLength += numVertexes * sizeof(Vector4D); + } + + return dataLength; +} + +inline int Studio_LoadVertexes(const vertexFileHeader_t* pTempVvdHdr, vertexFileHeader_t* pNewVvdHdr, int rootLOD, bool bNeedsTangentS) +{ + int i; + int target; + int numVertexes; + vertexFileFixup_t* pFixupTable; + + numVertexes = pTempVvdHdr->numLODVertexes[rootLOD]; + + memcpy((void*)pNewVvdHdr, (void*)pTempVvdHdr, pTempVvdHdr->vertexDataStart); + + for (i = 0; i < rootLOD; i++) + { + pNewVvdHdr->numLODVertexes[i] = pNewVvdHdr->numLODVertexes[rootLOD]; + } + + if (bNeedsTangentS) + { + pNewVvdHdr->tangentDataStart = pNewVvdHdr->vertexDataStart + numVertexes * sizeof(mstudiovertex_t); + } + else + { + pNewVvdHdr->tangentDataStart = 0; + } + + if (!pNewVvdHdr->numFixups) + { + memcpy( + (byte*)pNewVvdHdr + pNewVvdHdr->vertexDataStart, + (byte*)pTempVvdHdr + pTempVvdHdr->vertexDataStart, + numVertexes * sizeof(mstudiovertex_t)); + + if (bNeedsTangentS) + { + memcpy( + (byte*)pNewVvdHdr + pNewVvdHdr->tangentDataStart, + (byte*)pTempVvdHdr + pTempVvdHdr->tangentDataStart, + numVertexes * sizeof(Vector4D)); + } + + return numVertexes; + } + + target = 0; + pFixupTable = (vertexFileFixup_t*)((byte*)pTempVvdHdr + pTempVvdHdr->fixupTableStart); + for (i = 0; i < pTempVvdHdr->numFixups; i++) + { + if (pFixupTable[i].lod < rootLOD) + { + continue; + } + + memcpy( + (mstudiovertex_t*)((byte*)pNewVvdHdr + pNewVvdHdr->vertexDataStart) + target, + (mstudiovertex_t*)((byte*)pTempVvdHdr + pTempVvdHdr->vertexDataStart) + pFixupTable[i].sourceVertexID, + pFixupTable[i].numVertexes * sizeof(mstudiovertex_t)); + + if (bNeedsTangentS) + { + memcpy( + (Vector4D*)((byte*)pNewVvdHdr + pNewVvdHdr->tangentDataStart) + target, + (Vector4D*)((byte*)pTempVvdHdr + pTempVvdHdr->tangentDataStart) + pFixupTable[i].sourceVertexID, + pFixupTable[i].numVertexes * sizeof(Vector4D)); + } + + target += pFixupTable[i].numVertexes; + } + + pNewVvdHdr->numFixups = 0; + + return target; +} + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/tempentity.h b/SpyCustom/sdk/tempentity.h new file mode 100644 index 0000000..1d22f57 --- /dev/null +++ b/SpyCustom/sdk/tempentity.h @@ -0,0 +1,31 @@ +#ifndef TEMPENTITY_H +#define TEMPENTITY_H +#ifdef _WIN32 +#pragma once +#endif + +#define TE_EXPLFLAG_NONE 0x0 +#define TE_EXPLFLAG_NOADDITIVE 0x1 +#define TE_EXPLFLAG_DLIGHT 0x2 +#define TE_EXPLFLAG_NOSOUND 0x4 +#define TE_EXPLFLAG_NOPARTICLES 0x8 +#define TE_EXPLFLAG_DRAWALPHA 0x10 +#define TE_EXPLFLAG_ROTATE 0x20 +#define TE_EXPLFLAG_NOFIREBALL 0x40 +#define TE_EXPLFLAG_NOFIREBALLSMOKE 0x80 +#define TE_EXPLFLAG_ICE 0x100 +#define TE_EXPLFLAG_SCALEPARTICLES 0x200 + +#define TE_BEAMPOINTS 0 +#define TE_SPRITE 1 +#define TE_BEAMDISK 2 +#define TE_BEAMCYLINDER 3 +#define TE_BEAMFOLLOW 4 +#define TE_BEAMRING 5 +#define TE_BEAMSPLINE 6 +#define TE_BEAMRINGPOINT 7 +#define TE_BEAMLASER 8 +#define TE_BEAMTESLA 9 + + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/texture_group_names.h b/SpyCustom/sdk/texture_group_names.h new file mode 100644 index 0000000..b289143 --- /dev/null +++ b/SpyCustom/sdk/texture_group_names.h @@ -0,0 +1,36 @@ +#ifndef TEXTURE_GROUP_NAMES_H +#define TEXTURE_GROUP_NAMES_H +#ifdef _WIN32 +#pragma once +#endif + +#define TEXTURE_GROUP_LIGHTMAP "Lightmaps" +#define TEXTURE_GROUP_WORLD "World textures" +#define TEXTURE_GROUP_MODEL "Model textures" +#define TEXTURE_GROUP_VGUI "VGUI textures" +#define TEXTURE_GROUP_PARTICLE "Particle textures" +#define TEXTURE_GROUP_DECAL "Decal textures" +#define TEXTURE_GROUP_SKYBOX "SkyBox textures" +#define TEXTURE_GROUP_CLIENT_EFFECTS "ClientEffect textures" +#define TEXTURE_GROUP_OTHER "Other textures" +#define TEXTURE_GROUP_PRECACHED "Precached" +#define TEXTURE_GROUP_CUBE_MAP "CubeMap textures" +#define TEXTURE_GROUP_RENDER_TARGET "RenderTargets" +#define TEXTURE_GROUP_RUNTIME_COMPOSITE "Runtime Composite" +#define TEXTURE_GROUP_UNACCOUNTED "Unaccounted textures" +#define TEXTURE_GROUP_STATIC_INDEX_BUFFER "Static Indices" +#define TEXTURE_GROUP_STATIC_VERTEX_BUFFER_DISP "Displacement Verts" +#define TEXTURE_GROUP_STATIC_VERTEX_BUFFER_COLOR "Lighting Verts" +#define TEXTURE_GROUP_STATIC_VERTEX_BUFFER_WORLD "World Verts" +#define TEXTURE_GROUP_STATIC_VERTEX_BUFFER_MODELS "Model Verts" +#define TEXTURE_GROUP_STATIC_VERTEX_BUFFER_OTHER "Other Verts" +#define TEXTURE_GROUP_DYNAMIC_INDEX_BUFFER "Dynamic Indices" +#define TEXTURE_GROUP_DYNAMIC_VERTEX_BUFFER "Dynamic Verts" +#define TEXTURE_GROUP_DEPTH_BUFFER "DepthBuffer" +#define TEXTURE_GROUP_VIEW_MODEL "ViewModel" +#define TEXTURE_GROUP_PIXEL_SHADERS "Pixel Shaders" +#define TEXTURE_GROUP_VERTEX_SHADERS "Vertex Shaders" +#define TEXTURE_GROUP_RENDER_TARGET_SURFACE "RenderTarget Surfaces" +#define TEXTURE_GROUP_MORPH_TARGETS "Morph Targets" + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/threadtools.h b/SpyCustom/sdk/threadtools.h new file mode 100644 index 0000000..54bcc93 --- /dev/null +++ b/SpyCustom/sdk/threadtools.h @@ -0,0 +1,1402 @@ +#ifndef THREADTOOLS_H +#define THREADTOOLS_H + +#include + +#include "platform.h" +#include "dbg.h" +#include "vcrmode.h" + +#ifdef PLATFORM_WINDOWS_PC +#include +#endif + +#ifdef POSIX +#include +#include +#define WAIT_OBJECT_0 0 +#define WAIT_TIMEOUT 0x00000102 +#define WAIT_FAILED -1 +#define THREAD_PRIORITY_HIGHEST 2 +#endif + +#if defined( _WIN32 ) +#pragma once +#pragma warning(push) +#pragma warning(disable:4251) +#endif + +#ifndef _RETAIL +#define THREAD_MUTEX_TRACING_SUPPORTED +#if defined(_WIN32) && defined(_DEBUG) +#define THREAD_MUTEX_TRACING_ENABLED +#endif +#endif + +#ifdef _WIN32 +typedef void* HANDLE; +#endif + +const unsigned TT_INFINITE = 0xffffffff; + +#ifndef NO_THREAD_LOCAL + +#ifndef THREAD_LOCAL +#ifdef _WIN32 +#define THREAD_LOCAL __declspec(thread) +#elif POSIX +#define THREAD_LOCAL __thread +#endif +#endif + +#endif + +typedef unsigned long ThreadId_t; + +FORWARD_DECLARE_HANDLE(ThreadHandle_t); +typedef unsigned (*ThreadFunc_t)(void* pParam); + +PLATFORM_OVERLOAD ThreadHandle_t CreateSimpleThread(ThreadFunc_t, void* pParam, ThreadId_t* pID, unsigned stackSize = 0); +PLATFORM_INTERFACE ThreadHandle_t CreateSimpleThread(ThreadFunc_t, void* pParam, unsigned stackSize = 0); +PLATFORM_INTERFACE bool ReleaseThreadHandle(ThreadHandle_t); + + +PLATFORM_INTERFACE void ThreadSleep(unsigned duration = 0); +PLATFORM_INTERFACE uint ThreadGetCurrentId(); +PLATFORM_INTERFACE ThreadHandle_t ThreadGetCurrentHandle(); +PLATFORM_INTERFACE int ThreadGetPriority(ThreadHandle_t hThread = NULL); +PLATFORM_INTERFACE bool ThreadSetPriority(ThreadHandle_t hThread, int priority); +inline bool ThreadSetPriority(int priority) { return ThreadSetPriority(NULL, priority); } +PLATFORM_INTERFACE bool ThreadInMainThread(); +PLATFORM_INTERFACE void DeclareCurrentThreadIsMainThread(); + +typedef int (*ThreadedLoadLibraryFunc_t)(); +PLATFORM_INTERFACE void SetThreadedLoadLibraryFunc(ThreadedLoadLibraryFunc_t func); +PLATFORM_INTERFACE ThreadedLoadLibraryFunc_t GetThreadedLoadLibraryFunc(); + +#if defined( _WIN32 ) && !defined( _WIN64 ) && !defined( _X360 ) +extern "C" unsigned long __declspec(dllimport) __stdcall GetCurrentThreadId(); +#define ThreadGetCurrentId GetCurrentThreadId +#endif + +inline void ThreadPause() +{ +#if defined( PLATFORM_WINDOWS_PC ) + _mm_pause(); +#elif POSIX + __asm __volatile("pause"); +#elif defined( _X360 ) +#else +#error "implement me" +#endif +} + +PLATFORM_INTERFACE bool ThreadJoin(ThreadHandle_t, unsigned timeout = TT_INFINITE); +PLATFORM_INTERFACE void ThreadDetach(ThreadHandle_t); + +PLATFORM_INTERFACE void ThreadSetDebugName(ThreadId_t id, const char* pszName); +inline void ThreadSetDebugName(const char* pszName) { ThreadSetDebugName((ThreadId_t)-1, pszName); } + +PLATFORM_INTERFACE void ThreadSetAffinity(ThreadHandle_t hThread, int nAffinityMask); + +enum ThreadWaitResult_t +{ + TW_FAILED = 0xffffffff, + TW_TIMEOUT = 0x00000102, +}; + +#ifdef _WIN32 +PLATFORM_INTERFACE int ThreadWaitForObjects(int nEvents, const HANDLE* pHandles, bool bWaitAll = true, unsigned timeout = TT_INFINITE); +inline int ThreadWaitForObject(HANDLE handle, bool bWaitAll = true, unsigned timeout = TT_INFINITE) { return ThreadWaitForObjects(1, &handle, bWaitAll, timeout); } +#endif + +#ifdef _WIN32 +#define NOINLINE +#elif POSIX +#define NOINLINE __attribute__ ((noinline)) +#endif + +#if defined( _X360 ) || defined( _PS3 ) +#define ThreadMemoryBarrier() __lwsync() + +#elif defined(_MSC_VER) +#if _MSC_VER < 1500 +#pragma intrinsic(_ReadWriteBarrier) +#endif +#define ThreadMemoryBarrier() _ReadWriteBarrier() +#elif defined(GNUC) +#define ThreadMemoryBarrier() asm volatile("" ::: "memory") +#else +#error Every platform needs to define ThreadMemoryBarrier to at least prevent compiler reordering +#endif + +#if defined(_WIN32) && !defined(_X360) +#if ( _MSC_VER >= 1310 ) +#define USE_INTRINSIC_INTERLOCKED +#endif +#endif + +#ifdef USE_INTRINSIC_INTERLOCKED +extern "C" +{ + long __cdecl _InterlockedIncrement(volatile long*); + long __cdecl _InterlockedDecrement(volatile long*); + long __cdecl _InterlockedExchange(volatile long*, long); + long __cdecl _InterlockedExchangeAdd(volatile long*, long); + long __cdecl _InterlockedCompareExchange(volatile long*, long, long); +} + +#pragma intrinsic( _InterlockedCompareExchange ) +#pragma intrinsic( _InterlockedDecrement ) +#pragma intrinsic( _InterlockedExchange ) +#pragma intrinsic( _InterlockedExchangeAdd ) +#pragma intrinsic( _InterlockedIncrement ) + +inline long ThreadInterlockedIncrement(long volatile* p) { Assert((size_t)p % 4 == 0); return _InterlockedIncrement(p); } +inline long ThreadInterlockedDecrement(long volatile* p) { Assert((size_t)p % 4 == 0); return _InterlockedDecrement(p); } +inline long ThreadInterlockedExchange(long volatile* p, long value) { Assert((size_t)p % 4 == 0); return _InterlockedExchange(p, value); } +inline long ThreadInterlockedExchangeAdd(long volatile* p, long value) { Assert((size_t)p % 4 == 0); return _InterlockedExchangeAdd(p, value); } +inline long ThreadInterlockedCompareExchange(long volatile* p, long value, long comperand) { Assert((size_t)p % 4 == 0); return _InterlockedCompareExchange(p, value, comperand); } +inline bool ThreadInterlockedAssignIf(long volatile* p, long value, long comperand) { Assert((size_t)p % 4 == 0); return (_InterlockedCompareExchange(p, value, comperand) == comperand); } +#else +PLATFORM_INTERFACE long ThreadInterlockedIncrement(long volatile*); +PLATFORM_INTERFACE long ThreadInterlockedDecrement(long volatile*); +PLATFORM_INTERFACE long ThreadInterlockedExchange(long volatile*, long value); +PLATFORM_INTERFACE long ThreadInterlockedExchangeAdd(long volatile*, long value); +PLATFORM_INTERFACE long ThreadInterlockedCompareExchange(long volatile*, long value, long comperand); +PLATFORM_INTERFACE bool ThreadInterlockedAssignIf(long volatile*, long value, long comperand); +#endif + +inline unsigned ThreadInterlockedExchangeSubtract(long volatile* p, long value) { return ThreadInterlockedExchangeAdd((long volatile*)p, -value); } + +#if defined( USE_INTRINSIC_INTERLOCKED ) && !defined( _WIN64 ) +#define TIPTR() +inline void* ThreadInterlockedExchangePointer(void* volatile* p, void* value) { return (void*)_InterlockedExchange(reinterpret_cast(p), reinterpret_cast(value)); } +inline void* ThreadInterlockedCompareExchangePointer(void* volatile* p, void* value, void* comperand) { return (void*)_InterlockedCompareExchange(reinterpret_cast(p), reinterpret_cast(value), reinterpret_cast(comperand)); } +inline bool ThreadInterlockedAssignPointerIf(void* volatile* p, void* value, void* comperand) { return (_InterlockedCompareExchange(reinterpret_cast(p), reinterpret_cast(value), reinterpret_cast(comperand)) == reinterpret_cast(comperand)); } +#else +PLATFORM_INTERFACE void* ThreadInterlockedExchangePointer(void* volatile*, void* value) NOINLINE; +PLATFORM_INTERFACE void* ThreadInterlockedCompareExchangePointer(void* volatile*, void* value, void* comperand) NOINLINE; +PLATFORM_INTERFACE bool ThreadInterlockedAssignPointerIf(void* volatile*, void* value, void* comperand) NOINLINE; +#endif + +inline void const* ThreadInterlockedExchangePointerToConst(void const* volatile* p, void const* value) { return ThreadInterlockedExchangePointer(const_cast (p), const_cast (value)); } +inline void const* ThreadInterlockedCompareExchangePointerToConst(void const* volatile* p, void const* value, void const* comperand) { return ThreadInterlockedCompareExchangePointer(const_cast (p), const_cast (value), const_cast (comperand)); } +inline bool ThreadInterlockedAssignPointerToConstIf(void const* volatile* p, void const* value, void const* comperand) { return ThreadInterlockedAssignPointerIf(const_cast (p), const_cast (value), const_cast (comperand)); } + +#if defined( PLATFORM_64BITS ) +#if defined (_WIN32) +typedef __m128i int128; +inline int128 int128_zero() { return _mm_setzero_si128(); } +#else +typedef __int128_t int128; +#define int128_zero() 0 +#endif + +PLATFORM_INTERFACE bool ThreadInterlockedAssignIf128(volatile int128* pDest, const int128& value, const int128& comperand) NOINLINE; + +#endif + +PLATFORM_INTERFACE int64 ThreadInterlockedIncrement64(int64 volatile*) NOINLINE; +PLATFORM_INTERFACE int64 ThreadInterlockedDecrement64(int64 volatile*) NOINLINE; +PLATFORM_INTERFACE int64 ThreadInterlockedCompareExchange64(int64 volatile*, int64 value, int64 comperand) NOINLINE; +PLATFORM_INTERFACE int64 ThreadInterlockedExchange64(int64 volatile*, int64 value) NOINLINE; +PLATFORM_INTERFACE int64 ThreadInterlockedExchangeAdd64(int64 volatile*, int64 value) NOINLINE; +PLATFORM_INTERFACE bool ThreadInterlockedAssignIf64(volatile int64* pDest, int64 value, int64 comperand) NOINLINE; + +inline unsigned ThreadInterlockedExchangeSubtract(unsigned volatile* p, unsigned value) { return ThreadInterlockedExchangeAdd((long volatile*)p, value); } +inline unsigned ThreadInterlockedIncrement(unsigned volatile* p) { return ThreadInterlockedIncrement((long volatile*)p); } +inline unsigned ThreadInterlockedDecrement(unsigned volatile* p) { return ThreadInterlockedDecrement((long volatile*)p); } +inline unsigned ThreadInterlockedExchange(unsigned volatile* p, unsigned value) { return ThreadInterlockedExchange((long volatile*)p, value); } +inline unsigned ThreadInterlockedExchangeAdd(unsigned volatile* p, unsigned value) { return ThreadInterlockedExchangeAdd((long volatile*)p, value); } +inline unsigned ThreadInterlockedCompareExchange(unsigned volatile* p, unsigned value, unsigned comperand) { return ThreadInterlockedCompareExchange((long volatile*)p, value, comperand); } +inline bool ThreadInterlockedAssignIf(unsigned volatile* p, unsigned value, unsigned comperand) { return ThreadInterlockedAssignIf((long volatile*)p, value, comperand); } + +inline int ThreadInterlockedExchangeSubtract(int volatile* p, int value) { return ThreadInterlockedExchangeAdd((long volatile*)p, value); } +inline int ThreadInterlockedIncrement(int volatile* p) { return ThreadInterlockedIncrement((long volatile*)p); } +inline int ThreadInterlockedDecrement(int volatile* p) { return ThreadInterlockedDecrement((long volatile*)p); } +inline int ThreadInterlockedExchange(int volatile* p, int value) { return ThreadInterlockedExchange((long volatile*)p, value); } +inline int ThreadInterlockedExchangeAdd(int volatile* p, int value) { return ThreadInterlockedExchangeAdd((long volatile*)p, value); } +inline int ThreadInterlockedCompareExchange(int volatile* p, int value, int comperand) { return ThreadInterlockedCompareExchange((long volatile*)p, value, comperand); } +inline bool ThreadInterlockedAssignIf(int volatile* p, int value, int comperand) { return ThreadInterlockedAssignIf((long volatile*)p, value, comperand); } + +#if defined(_WIN32) && defined(THREAD_PROFILER) +PLATFORM_INTERFACE void ThreadNotifySyncPrepare(void* p); +PLATFORM_INTERFACE void ThreadNotifySyncCancel(void* p); +PLATFORM_INTERFACE void ThreadNotifySyncAcquired(void* p); +PLATFORM_INTERFACE void ThreadNotifySyncReleasing(void* p); +#else +#define ThreadNotifySyncPrepare(p) ((void)0) +#define ThreadNotifySyncCancel(p) ((void)0) +#define ThreadNotifySyncAcquired(p) ((void)0) +#define ThreadNotifySyncReleasing(p) ((void)0) +#endif + +#ifndef NO_THREAD_LOCAL + +#if defined(_LINUX) && !defined(OSX) +#define PLAT_COMPILER_SUPPORTED_THREADLOCALS 1 +#define CTHREADLOCALINTEGER( typ ) __thread int +#define CTHREADLOCALINT __thread int +#define CTHREADLOCALPTR( typ ) __thread typ * +#define CTHREADLOCAL( typ ) __thread typ +#define GETLOCAL( x ) ( x ) +#endif + +#if defined(WIN32) || defined(OSX) +#ifndef __AFXTLS_H__ +#define CTHREADLOCALINT CThreadLocalInt +#define CTHREADLOCALINTEGER( typ ) CThreadLocalInt +#define CTHREADLOCALPTR( typ ) CThreadLocalPtr +#define CTHREADLOCAL( typ ) CThreadLocal +#define GETLOCAL( x ) ( x.Get() ) +#endif +#endif + +#endif + +#ifndef __AFXTLS_H__ +#ifndef NO_THREAD_LOCAL + +class PLATFORM_CLASS CThreadLocalBase +{ +public: + CThreadLocalBase(); + ~CThreadLocalBase(); + + void* Get() const; + void Set(void*); + +private: +#ifdef _WIN32 + uint32 m_index; +#elif POSIX + pthread_key_t m_index; +#endif +}; + +#ifndef __AFXTLS_H__ + +template +class CThreadLocal : public CThreadLocalBase +{ +public: + CThreadLocal() + { + COMPILE_TIME_ASSERT(sizeof(T) == sizeof(void*)); + } + + T Get() const + { + return reinterpret_cast(CThreadLocalBase::Get()); + } + + void Set(T val) + { + CThreadLocalBase::Set(reinterpret_cast(val)); + } +}; + +#endif + +template +class CThreadLocalInt : public CThreadLocal +{ +public: + CThreadLocalInt() + { + COMPILE_TIME_ASSERT(sizeof(T) >= sizeof(int)); + } + + operator int() const { return (int)this->Get(); } + int operator=(int i) { this->Set((intp)i); return i; } + + int operator++() { T i = this->Get(); this->Set(++i); return (int)i; } + int operator++(int) { T i = this->Get(); this->Set(i + 1); return (int)i; } + + int operator--() { T i = this->Get(); this->Set(--i); return (int)i; } + int operator--(int) { T i = this->Get(); this->Set(i - 1); return (int)i; } +}; + + +template +class CThreadLocalPtr : private CThreadLocalBase +{ +public: + CThreadLocalPtr() {} + + operator const void* () const { return (T*)Get(); } + operator void* () { return (T*)Get(); } + + operator const T* () const { return (T*)Get(); } + operator const T* () { return (T*)Get(); } + operator T* () { return (T*)Get(); } + + int operator=(int i) { AssertMsg(i == 0, "Only NULL allowed on integer assign"); Set(NULL); return 0; } + T* operator=(T* p) { Set(p); return p; } + + bool operator !() const { return (!Get()); } + bool operator!=(int i) const { AssertMsg(i == 0, "Only NULL allowed on integer compare"); return (Get() != NULL); } + bool operator==(int i) const { AssertMsg(i == 0, "Only NULL allowed on integer compare"); return (Get() == NULL); } + bool operator==(const void* p) const { return (Get() == p); } + bool operator!=(const void* p) const { return (Get() != p); } + bool operator==(const T* p) const { return operator==((void*)p); } + bool operator!=(const T* p) const { return operator!=((void*)p); } + + T* operator->() { return (T*)Get(); } + T& operator *() { return *((T*)Get()); } + + const T* operator->() const { return (T*)Get(); } + const T& operator *() const { return *((T*)Get()); } + + const T& operator[](int i) const { return *((T*)Get() + i); } + T& operator[](int i) { return *((T*)Get() + i); } + +private: + CThreadLocalPtr(T* pFrom); + CThreadLocalPtr(const CThreadLocalPtr& from); + T** operator &(); + T* const* operator &() const; + void operator=(const CThreadLocalPtr& from); + bool operator==(const CThreadLocalPtr& p) const; + bool operator!=(const CThreadLocalPtr& p) const; +}; + +#endif +#endif + +template +class CInterlockedIntT +{ +public: + CInterlockedIntT() : m_value(0) { COMPILE_TIME_ASSERT(sizeof(T) == sizeof(long)); } + CInterlockedIntT(T value) : m_value(value) {} + + T GetRaw() const { return m_value; } + + operator T() const { return m_value; } + + bool operator!() const { return (m_value == 0); } + bool operator==(T rhs) const { return (m_value == rhs); } + bool operator!=(T rhs) const { return (m_value != rhs); } + + T operator++() { return (T)ThreadInterlockedIncrement((long*)&m_value); } + T operator++(int) { return operator++() - 1; } + + T operator--() { return (T)ThreadInterlockedDecrement((long*)&m_value); } + T operator--(int) { return operator--() + 1; } + + bool AssignIf(T conditionValue, T newValue) { return ThreadInterlockedAssignIf((long*)&m_value, (long)newValue, (long)conditionValue); } + + T operator=(T newValue) { ThreadInterlockedExchange((long*)&m_value, newValue); return m_value; } + + void operator+=(T add) { ThreadInterlockedExchangeAdd((long*)&m_value, (long)add); } + void operator-=(T subtract) { operator+=(-subtract); } + void operator*=(T multiplier) { + T original, result; + do + { + original = m_value; + result = original * multiplier; + } while (!AssignIf(original, result)); + } + void operator/=(T divisor) { + T original, result; + do + { + original = m_value; + result = original / divisor; + } while (!AssignIf(original, result)); + } + + T operator+(T rhs) const { return m_value + rhs; } + T operator-(T rhs) const { return m_value - rhs; } + +private: + volatile T m_value; +}; + +typedef CInterlockedIntT CInterlockedInt; +typedef CInterlockedIntT CInterlockedUInt; + +template +class CInterlockedPtr +{ +public: + CInterlockedPtr() : m_value(0) {} + CInterlockedPtr(T* value) : m_value(value) {} + + operator T* () const { return m_value; } + + bool operator!() const { return (m_value == 0); } + bool operator==(T* rhs) const { return (m_value == rhs); } + bool operator!=(T* rhs) const { return (m_value != rhs); } + +#if defined( PLATFORM_64BITS ) + T* operator++() { return ((T*)ThreadInterlockedExchangeAdd64((int64*)&m_value, sizeof(T))) + 1; } + T* operator++(int) { return (T*)ThreadInterlockedExchangeAdd64((int64*)&m_value, sizeof(T)); } + + T* operator--() { return ((T*)ThreadInterlockedExchangeAdd64((int64*)&m_value, -sizeof(T))) - 1; } + T* operator--(int) { return (T*)ThreadInterlockedExchangeAdd64((int64*)&m_value, -sizeof(T)); } + + bool AssignIf(T* conditionValue, T* newValue) { return ThreadInterlockedAssignPointerToConstIf((void const**)&m_value, (void const*)newValue, (void const*)conditionValue); } + + T* operator=(T* newValue) { ThreadInterlockedExchangePointerToConst((void const**)&m_value, (void const*)newValue); return newValue; } + + void operator+=(int add) { ThreadInterlockedExchangeAdd64((int64*)&m_value, add * sizeof(T)); } +#else + T* operator++() { return ((T*)ThreadInterlockedExchangeAdd((long*)&m_value, sizeof(T))) + 1; } + T* operator++(int) { return (T*)ThreadInterlockedExchangeAdd((long*)&m_value, sizeof(T)); } + + T* operator--() { return ((T*)ThreadInterlockedExchangeAdd((long*)&m_value, -sizeof(T))) - 1; } + T* operator--(int) { return (T*)ThreadInterlockedExchangeAdd((long*)&m_value, -sizeof(T)); } + + bool AssignIf(T* conditionValue, T* newValue) { return ThreadInterlockedAssignPointerToConstIf((void const**)&m_value, (void const*)newValue, (void const*)conditionValue); } + + T* operator=(T* newValue) { ThreadInterlockedExchangePointerToConst((void const**)&m_value, (void const*)newValue); return newValue; } + + void operator+=(int add) { ThreadInterlockedExchangeAdd((long*)&m_value, add * sizeof(T)); } +#endif + + void operator-=(int subtract) { operator+=(-subtract); } + + T* operator+(int rhs) const { return m_value + rhs; } + T* operator-(int rhs) const { return m_value - rhs; } + T* operator+(unsigned rhs) const { return m_value + rhs; } + T* operator-(unsigned rhs) const { return m_value - rhs; } + size_t operator-(T* p) const { return m_value - p; } + size_t operator-(const CInterlockedPtr& p) const { return m_value - p.m_value; } + +private: + T* volatile m_value; +}; + +class PLATFORM_CLASS CThreadMutex +{ +public: + CThreadMutex(); + ~CThreadMutex(); + + void Lock(); + void Lock() const { (const_cast(this))->Lock(); } + void Unlock(); + void Unlock() const { (const_cast(this))->Unlock(); } + + bool TryLock(); + bool TryLock() const { return (const_cast(this))->TryLock(); } + + bool AssertOwnedByCurrentThread(); + + void SetTrace(bool); + +private: + CThreadMutex(const CThreadMutex&); + CThreadMutex& operator=(const CThreadMutex&); + +#if defined( _WIN32 ) +#ifdef _WIN64 +#define TT_SIZEOF_CRITICALSECTION 40 +#else +#ifndef _X360 +#define TT_SIZEOF_CRITICALSECTION 24 +#else +#define TT_SIZEOF_CRITICALSECTION 28 +#endif +#endif + byte m_CriticalSection[TT_SIZEOF_CRITICALSECTION]; +#elif defined(POSIX) + pthread_mutex_t m_Mutex; + pthread_mutexattr_t m_Attr; +#else +#error +#endif + +#ifdef THREAD_MUTEX_TRACING_SUPPORTED + uint m_currentOwnerID; + uint16 m_lockCount; + bool m_bTrace; +#endif +}; + +#if !defined(THREAD_PROFILER) + +class CThreadFastMutex +{ +public: + CThreadFastMutex() + : m_ownerID(0), + m_depth(0) + { + } + +private: + FORCEINLINE bool TryLockInline(const uint32 threadId) volatile + { + if (threadId != m_ownerID && !ThreadInterlockedAssignIf((volatile long*)&m_ownerID, (long)threadId, 0)) + return false; + + ThreadMemoryBarrier(); + ++m_depth; + return true; + } + + bool TryLock(const uint32 threadId) volatile + { + return TryLockInline(threadId); + } + + PLATFORM_CLASS void Lock(const uint32 threadId, unsigned nSpinSleepTime) volatile; + +public: + bool TryLock() volatile + { +#ifdef _DEBUG + if (m_depth == INT_MAX) + DebuggerBreak(); + + if (m_depth < 0) + DebuggerBreak(); +#endif + return TryLockInline(ThreadGetCurrentId()); + } + +#ifndef _DEBUG + FORCEINLINE +#endif + void Lock(unsigned int nSpinSleepTime = 0) volatile + { + const uint32 threadId = ThreadGetCurrentId(); + + if (!TryLockInline(threadId)) + { + ThreadPause(); + Lock(threadId, nSpinSleepTime); + } +#ifdef _DEBUG + if (m_ownerID != ThreadGetCurrentId()) + DebuggerBreak(); + + if (m_depth == INT_MAX) + DebuggerBreak(); + + if (m_depth < 0) + DebuggerBreak(); +#endif + } + +#ifndef _DEBUG + FORCEINLINE +#endif + void Unlock() volatile + { +#ifdef _DEBUG + if (m_ownerID != ThreadGetCurrentId()) + DebuggerBreak(); + + if (m_depth <= 0) + DebuggerBreak(); +#endif + + --m_depth; + if (!m_depth) + { + ThreadMemoryBarrier(); + ThreadInterlockedExchange(&m_ownerID, 0); + } + } + +#ifdef WIN32 + bool TryLock() const volatile { return (const_cast(this))->TryLock(); } + void Lock(unsigned nSpinSleepTime = 1) const volatile { (const_cast(this))->Lock(nSpinSleepTime); } + void Unlock() const volatile { (const_cast(this))->Unlock(); } +#endif + bool AssertOwnedByCurrentThread() { return true; } + void SetTrace(bool) {} + + uint32 GetOwnerId() const { return m_ownerID; } + int GetDepth() const { return m_depth; } +private: + volatile uint32 m_ownerID; + int m_depth; +}; + +class ALIGN128 CAlignedThreadFastMutex : public CThreadFastMutex +{ +public: + CAlignedThreadFastMutex() + { + Assert((size_t)this % 128 == 0 && sizeof(*this) == 128); + } + +private: + uint8 pad[128 - sizeof(CThreadFastMutex)]; +} ALIGN128_POST; + +#else +typedef CThreadMutex CThreadFastMutex; +#endif + +class CThreadNullMutex +{ +public: + static void Lock() {} + static void Unlock() {} + + static bool TryLock() { return true; } + static bool AssertOwnedByCurrentThread() { return true; } + static void SetTrace(bool b) {} + + static uint32 GetOwnerId() { return 0; } + static int GetDepth() { return 0; } +}; + +template +class CThreadConditionalMutex : public BaseClass +{ +public: + void Lock() { if (*pCondition) BaseClass::Lock(); } + void Lock() const { if (*pCondition) BaseClass::Lock(); } + void Unlock() { if (*pCondition) BaseClass::Unlock(); } + void Unlock() const { if (*pCondition) BaseClass::Unlock(); } + + bool TryLock() { if (*pCondition) return BaseClass::TryLock(); else return true; } + bool TryLock() const { if (*pCondition) return BaseClass::TryLock(); else return true; } + bool AssertOwnedByCurrentThread() { if (*pCondition) return BaseClass::AssertOwnedByCurrentThread(); else return true; } + void SetTrace(bool b) { if (*pCondition) BaseClass::SetTrace(b); } +}; + +template +class CThreadTerminalMutex : public BaseClass +{ +public: + bool TryLock() { if (!BaseClass::TryLock()) { DebuggerBreak(); return false; } return true; } + bool TryLock() const { if (!BaseClass::TryLock()) { DebuggerBreak(); return false; } return true; } + void Lock() { if (!TryLock()) BaseClass::Lock(); } + void Lock() const { if (!TryLock()) BaseClass::Lock(); } + +}; + +template +class CAutoLockT +{ +public: + FORCEINLINE CAutoLockT(MUTEX_TYPE& lock) + : m_lock(lock) + { + m_lock.Lock(); + } + + FORCEINLINE CAutoLockT(const MUTEX_TYPE& lock) + : m_lock(const_cast(lock)) + { + m_lock.Lock(); + } + + FORCEINLINE ~CAutoLockT() + { + m_lock.Unlock(); + } + + +private: + MUTEX_TYPE& m_lock; + + CAutoLockT(const CAutoLockT&); + CAutoLockT& operator=(const CAutoLockT&); +}; + +typedef CAutoLockT CAutoLock; + +template struct CAutoLockTypeDeducer {}; +template <> struct CAutoLockTypeDeducer { typedef CThreadMutex Type_t; }; +template <> struct CAutoLockTypeDeducer { typedef CThreadNullMutex Type_t; }; +#if !defined(THREAD_PROFILER) +template <> struct CAutoLockTypeDeducer { typedef CThreadFastMutex Type_t; }; +template <> struct CAutoLockTypeDeducer { typedef CAlignedThreadFastMutex Type_t; }; +#endif + +#define AUTO_LOCK_( type, mutex ) \ + CAutoLockT< type > UNIQUE_ID( static_cast( mutex ) ) + +#if defined(GNUC) + +template T strip_cv_quals_for_mutex(T&); +template T strip_cv_quals_for_mutex(const T&); +template T strip_cv_quals_for_mutex(volatile T&); +template T strip_cv_quals_for_mutex(const volatile T&); + +#define AUTO_LOCK( mutex ) \ + AUTO_LOCK_( typeof(::strip_cv_quals_for_mutex(mutex)), mutex ) + +#else + +#define AUTO_LOCK( mutex ) \ + AUTO_LOCK_( CAutoLockTypeDeducer::Type_t, mutex ) + +#endif + +#define AUTO_LOCK_FM( mutex ) \ + AUTO_LOCK_( CThreadFastMutex, mutex ) + +#define LOCAL_THREAD_LOCK_( tag ) \ + ; \ + static CThreadFastMutex autoMutex_##tag; \ + AUTO_LOCK( autoMutex_##tag ) + +#define LOCAL_THREAD_LOCK() \ + LOCAL_THREAD_LOCK_(_) + +class PLATFORM_CLASS CThreadSyncObject +{ +public: + ~CThreadSyncObject(); + + bool operator!() const; + +#ifdef _WIN32 + operator HANDLE() { return GetHandle(); } + const HANDLE GetHandle() const { return m_hSyncObject; } +#endif + bool Wait(uint32 dwTimeout = TT_INFINITE); + +protected: + CThreadSyncObject(); + void AssertUseable(); + +#ifdef _WIN32 + HANDLE m_hSyncObject; + bool m_bCreatedHandle; +#elif defined(POSIX) + pthread_mutex_t m_Mutex; + pthread_cond_t m_Condition; + bool m_bInitalized; + int m_cSet; + bool m_bManualReset; + bool m_bWakeForEvent; +#else +#error "Implement me" +#endif + +private: + CThreadSyncObject(const CThreadSyncObject&); + CThreadSyncObject& operator=(const CThreadSyncObject&); +}; + + +#if defined( _WIN32 ) + +class PLATFORM_CLASS CThreadSemaphore : public CThreadSyncObject +{ +public: + CThreadSemaphore(long initialValue, long maxValue); + + bool Release(long releaseCount = 1, long* pPreviousCount = NULL); + +private: + CThreadSemaphore(const CThreadSemaphore&); + CThreadSemaphore& operator=(const CThreadSemaphore&); +}; + + +class PLATFORM_CLASS CThreadFullMutex : public CThreadSyncObject +{ +public: + CThreadFullMutex(bool bEstablishInitialOwnership = false, const char* pszName = NULL); + + bool Release(); + + void Lock() { Wait(); } + void Lock(unsigned timeout) { Wait(timeout); } + void Unlock() { Release(); } + bool AssertOwnedByCurrentThread() { return true; } + void SetTrace(bool) {} + +private: + CThreadFullMutex(const CThreadFullMutex&); + CThreadFullMutex& operator=(const CThreadFullMutex&); +}; +#endif + + +class PLATFORM_CLASS CThreadEvent : public CThreadSyncObject +{ +public: + CThreadEvent(bool fManualReset = false); +#ifdef WIN32 + CThreadEvent(HANDLE hHandle); +#endif + bool Set(); + + bool Reset(); + + bool Check(); + + bool Wait(uint32 dwTimeout = TT_INFINITE); + +private: + CThreadEvent(const CThreadEvent&); + CThreadEvent& operator=(const CThreadEvent&); +}; + +class CThreadManualEvent : public CThreadEvent +{ +public: + CThreadManualEvent() + : CThreadEvent(true) + { + } +}; + +inline int ThreadWaitForEvents(int nEvents, CThreadEvent* const* pEvents, bool bWaitAll = true, unsigned timeout = TT_INFINITE) +{ +#ifdef POSIX + Assert(nEvents == 1); + if (pEvents[0]->Wait(timeout)) + return WAIT_OBJECT_0; + else + return WAIT_TIMEOUT; +#else + HANDLE handles[64]; + for (unsigned int i = 0; i < min(nEvents, ARRAYSIZE(handles)); i++) + handles[i] = pEvents[i]->GetHandle(); + return ThreadWaitForObjects(nEvents, handles, bWaitAll, timeout); +#endif +} + +class PLATFORM_CLASS CThreadRWLock +{ +public: + CThreadRWLock(); + + void LockForRead(); + void UnlockRead(); + void LockForWrite(); + void UnlockWrite(); + + void LockForRead() const { const_cast(this)->LockForRead(); } + void UnlockRead() const { const_cast(this)->UnlockRead(); } + void LockForWrite() const { const_cast(this)->LockForWrite(); } + void UnlockWrite() const { const_cast(this)->UnlockWrite(); } + +private: + void WaitForRead(); + +#ifdef WIN32 + CThreadFastMutex m_mutex; +#else + CThreadMutex m_mutex; +#endif + CThreadEvent m_CanWrite; + CThreadEvent m_CanRead; + + int m_nWriters; + int m_nActiveReaders; + int m_nPendingReaders; +}; + +class ALIGN8 PLATFORM_CLASS CThreadSpinRWLock +{ +public: + CThreadSpinRWLock() { COMPILE_TIME_ASSERT(sizeof(LockInfo_t) == sizeof(int64)); Assert((intp)this % 8 == 0); memset(this, 0, sizeof(*this)); } + + bool TryLockForWrite(); + bool TryLockForRead(); + + void LockForRead(); + void UnlockRead(); + void LockForWrite(); + void UnlockWrite(); + + bool TryLockForWrite() const { return const_cast(this)->TryLockForWrite(); } + bool TryLockForRead() const { return const_cast(this)->TryLockForRead(); } + void LockForRead() const { const_cast(this)->LockForRead(); } + void UnlockRead() const { const_cast(this)->UnlockRead(); } + void LockForWrite() const { const_cast(this)->LockForWrite(); } + void UnlockWrite() const { const_cast(this)->UnlockWrite(); } + +private: + struct LockInfo_t + { + uint32 m_writerId; + int m_nReaders; + }; + + bool AssignIf(const LockInfo_t& newValue, const LockInfo_t& comperand); + bool TryLockForWrite(const uint32 threadId); + void SpinLockForWrite(const uint32 threadId); + + volatile LockInfo_t m_lockInfo; + CInterlockedInt m_nWriters; +} ALIGN8_POST; + +class PLATFORM_CLASS CThread +{ +public: + CThread(); + virtual ~CThread(); + + const char* GetName(); + void SetName(const char*); + + size_t CalcStackDepth(void* pStackVariable) { return ((byte*)m_pStackBase - (byte*)pStackVariable); } + + virtual bool Start(unsigned nBytesStack = 0); + + bool IsAlive(); + + bool Join(unsigned timeout = TT_INFINITE); + +#ifdef _WIN32 + HANDLE GetThreadHandle(); + uint GetThreadId(); +#elif defined( LINUX ) + uint GetThreadId(); +#endif + + int GetResult(); + + void Stop(int exitCode = 0); + + int GetPriority() const; + + bool SetPriority(int); + + void SuspendCooperative(); + + void ResumeCooperative(); + + void BWaitForThreadSuspendCooperative(); + +#ifndef LINUX + unsigned int Suspend(); + + unsigned int Resume(); +#endif + + bool Terminate(int exitCode = 0); + + static CThread* GetCurrentCThread(); + +#ifdef Yield +#undef Yield +#endif + static void Yield(); + + static void Sleep(unsigned duration); + +protected: + + virtual bool Init(); + + virtual int Run() = 0; + + virtual void OnExit(); + + void Cleanup(); + + bool WaitForCreateComplete(CThreadEvent* pEvent); + + typedef unsigned(__stdcall* ThreadProc_t)(void*); + virtual ThreadProc_t GetThreadProc(); + virtual bool IsThreadRunning(); + + CThreadMutex m_Lock; + +#ifdef WIN32 + ThreadHandle_t GetThreadID() const { return (ThreadHandle_t)m_hThread; } +#else + ThreadId_t GetThreadID() const { return (ThreadId_t)m_threadId; } +#endif + +private: + enum Flags + { + SUPPORT_STOP_PROTOCOL = 1 << 0 + }; + + struct ThreadInit_t + { + CThread* pThread; + CThreadEvent* pInitCompleteEvent; + bool* pfInitSuccess; + }; + + static unsigned __stdcall ThreadProc(void* pv); + + CThread(const CThread&); + CThread& operator=(const CThread&); + +#ifdef _WIN32 + HANDLE m_hThread; + ThreadId_t m_threadId; +#elif defined(POSIX) + pthread_t m_threadId; +#endif + CInterlockedInt m_nSuspendCount; + CThreadEvent m_SuspendEvent; + CThreadEvent m_SuspendEventSignal; + int m_result; + char m_szName[32]; + void* m_pStackBase; + unsigned m_flags; +}; + +class PLATFORM_CLASS CValidatableThread : public CThread +{ +public: + CValidatableThread() + { + m_bSleepForValidate = false; + m_bSleepingForValidate = false; + } + +#ifdef DBGFLAG_VALIDATE + virtual void SleepForValidate() { m_bSleepForValidate = true; } + bool BSleepingForValidate() { return m_bSleepingForValidate; } + virtual void WakeFromValidate() { m_bSleepForValidate = false; } +#endif +protected: + bool m_bSleepForValidate; + bool m_bSleepingForValidate; +}; + + +enum WTCallResult_t +{ + WTCR_FAIL = -1, + WTCR_TIMEOUT = -2, + WTCR_THREAD_GONE = -3, +}; + +class CFunctor; +class PLATFORM_CLASS CWorkerThread : public CThread +{ +public: + CWorkerThread(); + + int CallWorker(unsigned, unsigned timeout = TT_INFINITE, bool fBoostWorkerPriorityToMaster = true, CFunctor* pParamFunctor = NULL); + + int CallMaster(unsigned, unsigned timeout = TT_INFINITE); + + bool WaitForCall(unsigned dwTimeout, unsigned* pResult = NULL); + bool WaitForCall(unsigned* pResult = NULL); + + bool PeekCall(unsigned* pParam = NULL, CFunctor** ppParamFunctor = NULL); + + void Reply(unsigned); + + int WaitForReply(unsigned timeout = TT_INFINITE); + + CThreadEvent& GetCallHandle(); + unsigned GetCallParam(CFunctor** ppParamFunctor = NULL) const; + + int BoostPriority(); + +protected: +#ifndef _WIN32 +#define __stdcall +#endif + typedef uint32(__stdcall* WaitFunc_t)(int nEvents, CThreadEvent* const* pEvents, int bWaitAll, uint32 timeout); + + int Call(unsigned, unsigned timeout, bool fBoost, WaitFunc_t = NULL, CFunctor* pParamFunctor = NULL); + int WaitForReply(unsigned timeout, WaitFunc_t); + +private: + CWorkerThread(const CWorkerThread&); + CWorkerThread& operator=(const CWorkerThread&); + + CThreadEvent m_EventSend; + CThreadEvent m_EventComplete; + + unsigned m_Param; + CFunctor* m_pParamFunctor; + int m_ReturnVal; +}; + + +template class CMessageQueue +{ + CThreadEvent SignalEvent; + CThreadMutex QueueAccessMutex; + + struct MsgNode + { + MsgNode* Next; + T Data; + }; + + MsgNode* Head; + MsgNode* Tail; + +public: + CMessageQueue(void) + { + Head = Tail = NULL; + } + + bool MessageWaiting(void) + { + return (Head != NULL); + } + + void WaitMessage(T* pMsg) + { + for (;;) + { + while (!MessageWaiting()) + SignalEvent.Wait(); + QueueAccessMutex.Lock(); + if (!Head) + { + QueueAccessMutex.Unlock(); + continue; + } + *(pMsg) = Head->Data; + MsgNode* remove_this = Head; + Head = Head->Next; + if (!Head) + Tail = NULL; + QueueAccessMutex.Unlock(); + delete remove_this; + break; + } + } + + void QueueMessage(T const& Msg) + { + MsgNode* new1 = new MsgNode; + new1->Data = Msg; + new1->Next = NULL; + QueueAccessMutex.Lock(); + if (Tail) + { + Tail->Next = new1; + Tail = new1; + } + else + { + Head = new1; + Tail = new1; + } + SignalEvent.Set(); + QueueAccessMutex.Unlock(); + } +}; + + +#ifdef _WIN32 +typedef struct _RTL_CRITICAL_SECTION RTL_CRITICAL_SECTION; +typedef RTL_CRITICAL_SECTION CRITICAL_SECTION; + +#ifndef _X360 +extern "C" +{ + void __declspec(dllimport) __stdcall InitializeCriticalSection(CRITICAL_SECTION*); + void __declspec(dllimport) __stdcall EnterCriticalSection(CRITICAL_SECTION*); + void __declspec(dllimport) __stdcall LeaveCriticalSection(CRITICAL_SECTION*); + void __declspec(dllimport) __stdcall DeleteCriticalSection(CRITICAL_SECTION*); +}; +#endif + +inline void CThreadMutex::Lock() +{ +#ifdef THREAD_MUTEX_TRACING_ENABLED + uint thisThreadID = ThreadGetCurrentId(); + if (m_bTrace && m_currentOwnerID && (m_currentOwnerID != thisThreadID)) + Msg("Thread %u about to wait for lock %p owned by %u\n", ThreadGetCurrentId(), (CRITICAL_SECTION*)&m_CriticalSection, m_currentOwnerID); +#endif + + VCRHook_EnterCriticalSection((CRITICAL_SECTION*)&m_CriticalSection); + +#ifdef THREAD_MUTEX_TRACING_ENABLED + if (m_lockCount == 0) + { + m_currentOwnerID = thisThreadID; + if (m_bTrace) + Msg("Thread %u now owns lock %p\n", m_currentOwnerID, (CRITICAL_SECTION*)&m_CriticalSection); + } + m_lockCount++; +#endif +} + +inline void CThreadMutex::Unlock() +{ +#ifdef THREAD_MUTEX_TRACING_ENABLED + AssertMsg(m_lockCount >= 1, "Invalid unlock of thread lock"); + m_lockCount--; + if (m_lockCount == 0) + { + if (m_bTrace) + Msg("Thread %u releasing lock %p\n", m_currentOwnerID, (CRITICAL_SECTION*)&m_CriticalSection); + m_currentOwnerID = 0; + } +#endif + LeaveCriticalSection((CRITICAL_SECTION*)&m_CriticalSection); +} + +inline bool CThreadMutex::AssertOwnedByCurrentThread() +{ +#ifdef THREAD_MUTEX_TRACING_ENABLED + if (ThreadGetCurrentId() == m_currentOwnerID) + return true; + AssertMsg3(0, "Expected thread %u as owner of lock %p, but %u owns", ThreadGetCurrentId(), (CRITICAL_SECTION*)&m_CriticalSection, m_currentOwnerID); + return false; +#else + return true; +#endif +} + +inline void CThreadMutex::SetTrace(bool bTrace) +{ +#ifdef THREAD_MUTEX_TRACING_ENABLED + m_bTrace = bTrace; +#endif +} + +#elif defined(POSIX) + +inline CThreadMutex::CThreadMutex() +{ + pthread_mutexattr_init(&m_Attr); + pthread_mutexattr_settype(&m_Attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&m_Mutex, &m_Attr); +} + +inline CThreadMutex::~CThreadMutex() +{ + pthread_mutex_destroy(&m_Mutex); +} + +inline void CThreadMutex::Lock() +{ + pthread_mutex_lock(&m_Mutex); +} + +inline void CThreadMutex::Unlock() +{ + pthread_mutex_unlock(&m_Mutex); +} + +inline bool CThreadMutex::AssertOwnedByCurrentThread() +{ + return true; +} + +inline void CThreadMutex::SetTrace(bool fTrace) +{ +} + +#endif + +inline CThreadRWLock::CThreadRWLock() + : m_CanRead(true), + m_nWriters(0), + m_nActiveReaders(0), + m_nPendingReaders(0) +{ +} + +inline void CThreadRWLock::LockForRead() +{ + m_mutex.Lock(); + if (m_nWriters) + { + WaitForRead(); + } + m_nActiveReaders++; + m_mutex.Unlock(); +} + +inline void CThreadRWLock::UnlockRead() +{ + m_mutex.Lock(); + m_nActiveReaders--; + if (m_nActiveReaders == 0 && m_nWriters != 0) + { + m_CanWrite.Set(); + } + m_mutex.Unlock(); +} + + +inline bool CThreadSpinRWLock::AssignIf(const LockInfo_t& newValue, const LockInfo_t& comperand) +{ + return ThreadInterlockedAssignIf64((int64*)&m_lockInfo, *((int64*)&newValue), *((int64*)&comperand)); +} + +inline bool CThreadSpinRWLock::TryLockForWrite(const uint32 threadId) +{ + if (m_lockInfo.m_nReaders > 0 || (m_lockInfo.m_writerId && m_lockInfo.m_writerId != threadId)) + { + return false; + } + + static const LockInfo_t oldValue = { 0, 0 }; + LockInfo_t newValue = { threadId, 0 }; + const bool bSuccess = AssignIf(newValue, oldValue); +#if defined(_X360) + if (bSuccess) + { + } +#endif + return bSuccess; +} + +inline bool CThreadSpinRWLock::TryLockForWrite() +{ + m_nWriters++; + if (!TryLockForWrite(ThreadGetCurrentId())) + { + m_nWriters--; + return false; + } + return true; +} + +inline bool CThreadSpinRWLock::TryLockForRead() +{ + if (m_nWriters != 0) + { + return false; + } + LockInfo_t oldValue; + LockInfo_t newValue; + + oldValue.m_nReaders = m_lockInfo.m_nReaders; + oldValue.m_writerId = 0; + newValue.m_nReaders = oldValue.m_nReaders + 1; + newValue.m_writerId = 0; + + const bool bSuccess = AssignIf(newValue, oldValue); +#if defined(_X360) + if (bSuccess) + { + } +#endif + return bSuccess; +} + +inline void CThreadSpinRWLock::LockForWrite() +{ + const uint32 threadId = ThreadGetCurrentId(); + + m_nWriters++; + + if (!TryLockForWrite(threadId)) + { + ThreadPause(); + SpinLockForWrite(threadId); + } +} + +template FORCEINLINE T ReadVolatileMemory(T const* pPtr) +{ + volatile const T* pVolatilePtr = (volatile const T*)pPtr; + return *pVolatilePtr; +} + +#if defined( _WIN32 ) +#pragma warning(pop) +#endif + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/tier1.h b/SpyCustom/sdk/tier1.h new file mode 100644 index 0000000..fa8c490 --- /dev/null +++ b/SpyCustom/sdk/tier1.h @@ -0,0 +1,68 @@ + +#ifndef TIER1_H +#define TIER1_H + +#if defined( _WIN32 ) +#pragma once +#endif + +#include "iappsystem.h" +#include "convar.h" + + +void ConnectTier1Libraries(CreateInterfaceFn* pFactoryList, int nFactoryCount); +void DisconnectTier1Libraries(); + + +template< class IInterface, int ConVarFlag = 0 > +class CTier1AppSystem : public CTier0AppSystem< IInterface > +{ + typedef CTier0AppSystem< IInterface > BaseClass; + +public: + virtual bool Connect(CreateInterfaceFn factory) + { + if (!BaseClass::Connect(factory)) + return false; + + ConnectTier1Libraries(&factory, 1); + return true; + } + + virtual void Disconnect() + { + DisconnectTier1Libraries(); + BaseClass::Disconnect(); + } + + virtual InitReturnVal_t Init() + { + InitReturnVal_t nRetVal = BaseClass::Init(); + if (nRetVal != INIT_OK) + return nRetVal; + + if (g_pCVar) + { + ConVar_Register(ConVarFlag); + } + return INIT_OK; + } + + virtual void Shutdown() + { + if (g_pCVar) + { + ConVar_Unregister(); + } + BaseClass::Shutdown(); + } + + + virtual AppSystemTier_t GetTier() + { + return APP_SYSTEM_TIER1; + } +}; + + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/tier2.h b/SpyCustom/sdk/tier2.h new file mode 100644 index 0000000..fc7a44c --- /dev/null +++ b/SpyCustom/sdk/tier2.h @@ -0,0 +1,92 @@ + +#ifndef TIER2_H +#define TIER2_H + +#if defined( _WIN32 ) +#pragma once +#endif + +#include "tier1.h" + + +void ConnectTier2Libraries(CreateInterfaceFn* pFactoryList, int nFactoryCount); +void DisconnectTier2Libraries(); + + +void InitDefaultFileSystem(void); +void ShutdownDefaultFileSystem(void); + + +void InitCommandLineProgram(int& argc, char**& argv); + + +template< class IInterface, int ConVarFlag = 0 > +class CTier2AppSystem : public CTier1AppSystem< IInterface, ConVarFlag > +{ + typedef CTier1AppSystem< IInterface, ConVarFlag > BaseClass; + +public: + virtual bool Connect(CreateInterfaceFn factory) + { + if (!BaseClass::Connect(factory)) + return false; + + ConnectTier2Libraries(&factory, 1); + return true; + } + + virtual InitReturnVal_t Init() + { + InitReturnVal_t nRetVal = BaseClass::Init(); + if (nRetVal != INIT_OK) + return nRetVal; + + return INIT_OK; + } + + + virtual AppSystemTier_t GetTier() + { + return APP_SYSTEM_TIER2; + } + virtual void Shutdown() + { + BaseClass::Shutdown(); + } + + virtual void Disconnect() + { + DisconnectTier2Libraries(); + BaseClass::Disconnect(); + } +}; + + +enum FadeMode_t +{ + FADE_MODE_NONE = 0, + FADE_MODE_LOW, + FADE_MODE_MED, + FADE_MODE_HIGH, + FADE_MODE_360, + FADE_MODE_PS3, + FADE_MODE_LEVEL, + + FADE_MODE_COUNT, +}; + +struct FadeData_t +{ + float m_flPixelMin; + float m_flPixelMax; + float m_flWidth; + float m_flFadeDistScale; +}; + +extern FadeData_t g_aFadeData[FADE_MODE_COUNT]; + + +extern uint32 g_nResourceFrameCount; + + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/tier2_logging.h b/SpyCustom/sdk/tier2_logging.h new file mode 100644 index 0000000..3fa1d05 --- /dev/null +++ b/SpyCustom/sdk/tier2_logging.h @@ -0,0 +1,65 @@ +#ifndef TIER2_LOGGING_H +#define TIER2_LOGGING_H + +#if defined( COMPILER_MSVC ) +#pragma once +#endif + +#include "logging.h" + + +const int MAX_SIMULTANEOUS_LOGGING_FILE_COUNT = 16; +const int INVALID_LOGGING_FILE_HANDLE = -1; + +typedef int LoggingFileHandle_t; +typedef void* FileHandle_t; + +#define FILELOGGINGLISTENER_INTERFACE_VERSION "FileLoggingListener001" + +abstract_class IFileLoggingListener : public ILoggingListener +{ +public: + virtual void Log(const LoggingContext_t * pContext, const char* pMessage) = 0; + + virtual LoggingFileHandle_t BeginLoggingToFile(const char* pFilename, const char* pOptions, const char* pPathID = NULL) = 0; + virtual void EndLoggingToFile(LoggingFileHandle_t fileHandle) = 0; + + virtual void AssignLogChannel(LoggingChannelID_t channelID, LoggingFileHandle_t loggingFileHandle) = 0; + virtual void UnassignLogChannel(LoggingChannelID_t channelID) = 0; + virtual void AssignAllLogChannels(LoggingFileHandle_t loggingFileHandle) = 0; + virtual void UnassignAllLogChannels() = 0; +}; + +class CFileLoggingListener : public IFileLoggingListener +{ +public: + CFileLoggingListener(); + ~CFileLoggingListener(); + + virtual void Log(const LoggingContext_t* pContext, const char* pMessage); + + virtual LoggingFileHandle_t BeginLoggingToFile(const char* pFilename, const char* pOptions, const char* pPathID = NULL); + virtual void EndLoggingToFile(LoggingFileHandle_t fileHandle); + + virtual void AssignLogChannel(LoggingChannelID_t channelID, LoggingFileHandle_t loggingFileHandle); + virtual void UnassignLogChannel(LoggingChannelID_t channelID); + virtual void AssignAllLogChannels(LoggingFileHandle_t loggingFileHandle); + virtual void UnassignAllLogChannels(); + +private: + int GetUnusedFileInfo() const; + + struct FileInfo_t + { + FileHandle_t m_FileHandle; + + bool IsOpen() const { return m_FileHandle != 0; } + void Reset() { m_FileHandle = 0; } + }; + + FileInfo_t m_OpenFiles[MAX_SIMULTANEOUS_LOGGING_FILE_COUNT]; + + int m_FileIndices[MAX_LOGGING_CHANNEL_COUNT]; +}; + +#endif diff --git a/SpyCustom/sdk/tier3.h b/SpyCustom/sdk/tier3.h new file mode 100644 index 0000000..826b10b --- /dev/null +++ b/SpyCustom/sdk/tier3.h @@ -0,0 +1,45 @@ + +#ifndef TIER3_H +#define TIER3_H + +#if defined( _WIN32 ) +#pragma once +#endif + +#include "tier2.h" + + +void ConnectTier3Libraries(CreateInterfaceFn* pFactoryList, int nFactoryCount); +void DisconnectTier3Libraries(); + + +template< class IInterface, int ConVarFlag = 0 > +class CTier3AppSystem : public CTier2AppSystem< IInterface, ConVarFlag > +{ + typedef CTier2AppSystem< IInterface, ConVarFlag > BaseClass; + +public: + virtual bool Connect(CreateInterfaceFn factory) + { + if (!BaseClass::Connect(factory)) + return false; + + ConnectTier3Libraries(&factory, 1); + return true; + } + + virtual void Disconnect() + { + DisconnectTier3Libraries(); + BaseClass::Disconnect(); + } + + + virtual AppSystemTier_t GetTier() + { + return APP_SYSTEM_TIER3; + } +}; + + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/timedevent.h b/SpyCustom/sdk/timedevent.h new file mode 100644 index 0000000..a8f5a80 --- /dev/null +++ b/SpyCustom/sdk/timedevent.h @@ -0,0 +1,50 @@ +#ifndef TIMEDEVENT_H +#define TIMEDEVENT_H +#ifdef _WIN32 +#pragma once +#endif + +class TimedEvent +{ +public: + TimedEvent() + { + m_TimeBetweenEvents = -1; + m_fNextEvent = 0; + } + + inline void Init(float rate) + { + m_TimeBetweenEvents = 1.0f / rate; + m_fNextEvent = 0; + } + + inline void ResetRate(float rate) + { + m_TimeBetweenEvents = 1.0f / rate; + } + + inline bool NextEvent(float& curDelta) + { + Assert(m_TimeBetweenEvents != -1); + + if (curDelta >= m_fNextEvent) + { + curDelta -= m_fNextEvent; + + m_fNextEvent = m_TimeBetweenEvents; + return true; + } + else + { + m_fNextEvent -= curDelta; + return false; + } + } + +private: + float m_TimeBetweenEvents; + float m_fNextEvent; +}; + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/timeutils.h b/SpyCustom/sdk/timeutils.h new file mode 100644 index 0000000..e635872 --- /dev/null +++ b/SpyCustom/sdk/timeutils.h @@ -0,0 +1,149 @@ +#ifndef TIMEUTILS_H +#define TIMEUTILS_H +#ifdef _WIN32 +#pragma once +#endif + +#include +#include +#include "dbg.h" + +enum RoundStyle_t +{ + ROUND_NEAREST, + ROUND_DOWN, + ROUND_UP, +}; + +class DmeTime_t; + +class DmeFramerate_t +{ +public: + DmeFramerate_t(float fps); + DmeFramerate_t(int fps = 0); + DmeFramerate_t(const DmeFramerate_t& src) : m_num(src.m_num), m_den(src.m_den) {} + + void SetFramerate(float flFrameRate); + void SetFramerate(int fps); + void SetFramerateNTSC(int multiplier = 30); + + float GetFramesPerSecond() const; + DmeTime_t GetTimePerFrame() const; + + bool operator==(DmeFramerate_t f) const { return m_num == f.m_num && m_den == f.m_den; } + bool operator!=(DmeFramerate_t f) const { return m_num != f.m_num && m_den != f.m_den; } + bool operator< (DmeFramerate_t f) const { return m_num * (int)f.m_den < f.m_num* (int)m_den; } + bool operator> (DmeFramerate_t f) const { return m_num * (int)f.m_den > f.m_num * (int)m_den; } + bool operator<=(DmeFramerate_t f) const { return m_num * (int)f.m_den <= f.m_num * (int)m_den; } + bool operator>=(DmeFramerate_t f) const { return m_num * (int)f.m_den >= f.m_num * (int)m_den; } + + DmeFramerate_t operator*(int i) const { return DmeFramerate_t(m_num * i, m_den); } + DmeFramerate_t operator/(int i) const { return DmeFramerate_t(m_num, m_den * i); } + + DmeFramerate_t operator*=(int i) { Assert(abs(m_num * i) <= USHRT_MAX); m_num *= (unsigned short)i; return *this; } + DmeFramerate_t operator/=(int i) { Assert(abs(m_den * i) <= USHRT_MAX); m_den *= (unsigned short)i; return *this; } + +private: + DmeFramerate_t(int nNumerator, int nDenominator); + + unsigned short m_num; + unsigned short m_den; + + friend class DmeTime_t; +}; + +#define DMETIME_ZERO DmeTime_t(0) +#define DMETIME_MINDELTA DmeTime_t::MinTimeDelta() +#define DMETIME_MINTIME DmeTime_t::MinTime() +#define DMETIME_MAXTIME DmeTime_t::MaxTime() +#define DMETIME_INVALID DmeTime_t::InvalidTime() + +class DmeTime_t +{ +public: + DmeTime_t() : m_tms(INT_MIN) {} + explicit DmeTime_t(int tms) : m_tms(tms) {} + explicit DmeTime_t(float sec) : m_tms(RoundSecondsToTMS(sec)) {} + explicit DmeTime_t(double sec) : m_tms(RoundSecondsToTMS(sec)) {} + DmeTime_t(int frame, DmeFramerate_t framerate); + + + friend bool operator==(DmeTime_t a, DmeTime_t b) { return a.m_tms == b.m_tms; } + friend bool operator!=(DmeTime_t a, DmeTime_t b) { return a.m_tms != b.m_tms; } + friend bool operator< (DmeTime_t a, DmeTime_t b) { return a.m_tms < b.m_tms; } + friend bool operator> (DmeTime_t a, DmeTime_t b) { return a.m_tms > b.m_tms; } + friend bool operator<=(DmeTime_t a, DmeTime_t b) { return a.m_tms <= b.m_tms; } + friend bool operator>=(DmeTime_t a, DmeTime_t b) { return a.m_tms >= b.m_tms; } + + friend DmeTime_t operator%(DmeTime_t a, DmeTime_t b) { return DmeTime_t(a.m_tms % b.m_tms); } + friend DmeTime_t operator+(DmeTime_t a, DmeTime_t b) { return DmeTime_t(a.m_tms + b.m_tms); } + friend DmeTime_t operator-(DmeTime_t a, DmeTime_t b) { return DmeTime_t(a.m_tms - b.m_tms); } + + DmeTime_t operator-() const { return DmeTime_t(-m_tms); } + + DmeTime_t operator+=(DmeTime_t t) { m_tms += t.m_tms; return *this; } + DmeTime_t operator-=(DmeTime_t t) { m_tms -= t.m_tms; return *this; } + + friend DmeTime_t operator*(DmeTime_t t, float f) { t *= f; return t; } + friend DmeTime_t operator*(float f, DmeTime_t t) { t *= f; return t; } + friend DmeTime_t operator/(DmeTime_t t, float f) { t /= f; return t; } + friend float operator/(DmeTime_t n, DmeTime_t d) { return float(n.m_tms / double(d.m_tms)); } + + DmeTime_t operator*=(float f); + DmeTime_t operator/=(float f); + + DmeTime_t operator++() { ++m_tms; return *this; } + DmeTime_t operator--() { --m_tms; return *this; } + DmeTime_t operator++(int) { DmeTime_t t = *this; ++m_tms; return t; } + DmeTime_t operator--(int) { DmeTime_t t = *this; --m_tms; return t; } + + bool IsValid() const { return m_tms != INT_MIN; } + + static DmeTime_t InvalidTime() { return DmeTime_t(INT_MIN); } + static DmeTime_t MinTime() { return DmeTime_t(INT_MIN + 1); } + static DmeTime_t MaxTime() { return DmeTime_t(INT_MAX); } + static DmeTime_t MinTimeDelta() { return DmeTime_t(1); } + + + int GetTenthsOfMS() const { return m_tms; } + float GetSeconds() const { return m_tms * 0.0001f; } + void SetTenthsOfMS(int tms) { m_tms = tms; } + void SetSeconds(float sec) { m_tms = RoundSecondsToTMS(sec); } + + + void Clamp(DmeTime_t lo, DmeTime_t hi); + bool IsInRange(DmeTime_t lo, DmeTime_t hi) const; + + + friend float GetFractionOfTimeBetween(DmeTime_t t, DmeTime_t start, DmeTime_t end, bool bClamp); + friend float GetFractionOfTime(DmeTime_t t, DmeTime_t duration, bool bClamp); + friend int FrameForTime(DmeTime_t t, DmeFramerate_t framerate); + + + friend DmeTime_t abs(DmeTime_t t) { return t.m_tms >= 0 ? t : -t; } + + + int CurrentFrame(DmeFramerate_t framerate, RoundStyle_t roundStyle = ROUND_DOWN) const; + DmeTime_t TimeAtCurrentFrame(DmeFramerate_t framerate, RoundStyle_t roundStyle = ROUND_DOWN) const; + DmeTime_t TimeAtNextFrame(DmeFramerate_t framerate) const; + DmeTime_t TimeAtPrevFrame(DmeFramerate_t framerate) const; + +private: + explicit DmeTime_t(int64 tms) : m_tms(int(tms)) {} + + static int RoundSecondsToTMS(float sec); + static int RoundSecondsToTMS(double sec); + + int m_tms; +}; + +float GetFractionOfTimeBetween(DmeTime_t t, DmeTime_t start, DmeTime_t end, bool bClamp = false); +float GetFractionOfTime(DmeTime_t t, DmeTime_t duration, bool bClamp = false); + +class CUtlBuffer; +bool Serialize(CUtlBuffer& buf, const DmeTime_t& src); +bool Unserialize(CUtlBuffer& buf, DmeTime_t& dest); + + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/touchlink.h b/SpyCustom/sdk/touchlink.h new file mode 100644 index 0000000..6b710d7 --- /dev/null +++ b/SpyCustom/sdk/touchlink.h @@ -0,0 +1,29 @@ +#ifndef TOUCHLINK_H +#define TOUCHLINK_H +#ifdef _WIN32 +#pragma once +#endif + + +enum touchlink_flags_t +{ + FTOUCHLINK_START_TOUCH = 0x00000001, +}; + +struct touchlink_t +{ +#if defined( CLIENT_DLL ) + C_BaseEntity* entityTouched; +#else + EHANDLE entityTouched; +#endif + int touchStamp; + touchlink_t* nextLink; + touchlink_t* prevLink; + int flags; +}; + +#define TOUCHSTAMP_EVENT_DRIVEN -1 + + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/trace.h b/SpyCustom/sdk/trace.h new file mode 100644 index 0000000..17dda41 --- /dev/null +++ b/SpyCustom/sdk/trace.h @@ -0,0 +1,48 @@ +#ifndef TRACE_H +#define TRACE_H + +#ifdef _WIN32 +#pragma once +#endif + + +#include "mathlib.h" + +#define DISPSURF_FLAG_SURFACE (1<<0) +#define DISPSURF_FLAG_WALKABLE (1<<1) +#define DISPSURF_FLAG_BUILDABLE (1<<2) +#define DISPSURF_FLAG_SURFPROP1 (1<<3) +#define DISPSURF_FLAG_SURFPROP2 (1<<4) + +class CBaseTrace +{ +public: + + bool IsDispSurface(void) { return ((dispFlags & DISPSURF_FLAG_SURFACE) != 0); } + bool IsDispSurfaceWalkable(void) { return ((dispFlags & DISPSURF_FLAG_WALKABLE) != 0); } + bool IsDispSurfaceBuildable(void) { return ((dispFlags & DISPSURF_FLAG_BUILDABLE) != 0); } + bool IsDispSurfaceProp1(void) { return ((dispFlags & DISPSURF_FLAG_SURFPROP1) != 0); } + bool IsDispSurfaceProp2(void) { return ((dispFlags & DISPSURF_FLAG_SURFPROP2) != 0); } + +public: + + Vector startpos; + Vector endpos; + BYTE plane[20]; + + float fraction; + + int contents; + unsigned short dispFlags; + + bool allsolid; + bool startsolid; + + + CBaseTrace() {} + +private: + CBaseTrace(const CBaseTrace& vOther); +}; + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/tslist.h b/SpyCustom/sdk/tslist.h new file mode 100644 index 0000000..f153c4c --- /dev/null +++ b/SpyCustom/sdk/tslist.h @@ -0,0 +1,948 @@ +#ifndef TSLIST_H +#define TSLIST_H + +#if defined( _WIN32 ) +#pragma once +#pragma warning( push ) +#pragma warning( disable : 4700 ) +#endif + +#if defined( USE_NATIVE_SLIST ) && !defined( _X360 ) +#define WIN32_LEAN_AND_MEAN +#include +#endif + +#include "dbg.h" +#include "threadtools.h" +#include "memalloc.h" +#include "memdbgoff.h" + +#if defined( _X360 ) +#define USE_NATIVE_SLIST +#endif + +#if defined( PLATFORM_64BITS ) + +#if defined (PLATFORM_WINDOWS) +#else +typedef __int128_t int128; +#define int128_zero() 0 +#endif + +#define TSLIST_HEAD_ALIGNMENT 16 +#define TSLIST_NODE_ALIGNMENT 16 + +#ifdef POSIX +inline bool ThreadInterlockedAssignIf128(int128 volatile* pDest, const int128& value, const int128& comparand) +{ + int128 local_comparand = comparand; + return __sync_bool_compare_and_swap(pDest, local_comparand, value); +} +#endif + +inline bool ThreadInterlockedAssignIf64x128(volatile int128* pDest, const int128& value, const int128& comperand) +{ + return ThreadInterlockedAssignIf128(pDest, value, comperand); +} +#else +#define TSLIST_HEAD_ALIGNMENT 8 +#define TSLIST_NODE_ALIGNMENT 8 +inline bool ThreadInterlockedAssignIf64x128(volatile int64* pDest, const int64 value, const int64 comperand) +{ + return ThreadInterlockedAssignIf64(pDest, value, comperand); +} +#endif + +#ifdef _MSC_VER +#define TSLIST_HEAD_ALIGN DECL_ALIGN(TSLIST_HEAD_ALIGNMENT) +#define TSLIST_NODE_ALIGN DECL_ALIGN(TSLIST_NODE_ALIGNMENT) +#define TSLIST_HEAD_ALIGN_POST +#define TSLIST_NODE_ALIGN_POST +#elif defined( GNUC ) +#define TSLIST_HEAD_ALIGN +#define TSLIST_NODE_ALIGN +#define TSLIST_HEAD_ALIGN_POST DECL_ALIGN(TSLIST_HEAD_ALIGNMENT) +#define TSLIST_NODE_ALIGN_POST DECL_ALIGN(TSLIST_NODE_ALIGNMENT) +#elif defined( _PS3 ) +#define TSLIST_HEAD_ALIGNMENT 8 +#define TSLIST_NODE_ALIGNMENT 8 + +#define TSLIST_HEAD_ALIGN ALIGN8 +#define TSLIST_NODE_ALIGN ALIGN8 +#define TSLIST_HEAD_ALIGN_POST ALIGN8_POST +#define TSLIST_NODE_ALIGN_POST ALIGN8_POST + +#else +#error +#endif + +PLATFORM_INTERFACE bool RunTSQueueTests(int nListSize = 10000, int nTests = 1); +PLATFORM_INTERFACE bool RunTSListTests(int nListSize = 10000, int nTests = 1); + +#ifdef USE_NATIVE_SLIST +typedef SLIST_ENTRY TSLNodeBase_t; +typedef SLIST_HEADER TSLHead_t; +#else +struct TSLIST_NODE_ALIGN TSLNodeBase_t +{ + TSLNodeBase_t* Next; +} TSLIST_NODE_ALIGN_POST; + +union TSLIST_HEAD_ALIGN TSLHead_t +{ + struct Value_t + { + TSLNodeBase_t* Next; +#ifdef VALVE_BIG_ENDIAN + int16 Sequence; + int16 Depth; +#else + int16 Depth; + int16 Sequence; +#endif +#ifdef PLATFORM_64BITS + int32 Padding; +#endif + } value; + + struct Value32_t + { + TSLNodeBase_t* Next_do_not_use_me; + int32 DepthAndSequence; + } value32; + +#ifdef PLATFORM_64BITS + int128 value64x128; +#else + int64 value64x128; +#endif +} TSLIST_HEAD_ALIGN_POST; + +#endif + +class CTSListBase +{ +public: + + static void* operator new(size_t size) + { + CTSListBase* pNode = (CTSListBase*)MemAlloc_AllocAlignedFileLine(size, TSLIST_HEAD_ALIGNMENT, __FILE__, __LINE__); + return pNode; + } + + static void* operator new(size_t size, int nBlockUse, const char* pFileName, int nLine) + { + CTSListBase* pNode = (CTSListBase*)MemAlloc_AllocAlignedFileLine(size, TSLIST_HEAD_ALIGNMENT, pFileName, nLine); + return pNode; + } + + static void operator delete(void* p) + { + MemAlloc_FreeAligned(p); + } + + static void operator delete(void* p, int nBlockUse, const char* pFileName, int nLine) + { + MemAlloc_FreeAligned(p); + } + +private: + static void* operator new[](size_t size); + static void operator delete[](void* p); + +public: + + CTSListBase() + { + if (((size_t)&m_Head) % TSLIST_HEAD_ALIGNMENT != 0) + { + Error("CTSListBase: Misaligned list\n"); + DebuggerBreak(); + } + +#ifdef USE_NATIVE_SLIST + InitializeSListHead(&m_Head); +#elif defined(PLATFORM_64BITS) + m_Head.value64x128 = int128_zero(); +#else + m_Head.value64x128 = (int64)0; +#endif + } + + ~CTSListBase() + { + Detach(); + } + + TSLNodeBase_t* Push(TSLNodeBase_t* pNode) + { +#ifdef _DEBUG + if ((size_t)pNode % TSLIST_NODE_ALIGNMENT != 0) + { + Error("CTSListBase: Misaligned node\n"); + DebuggerBreak(); + } +#endif + +#ifdef USE_NATIVE_SLIST +#ifdef _X360 + return (TSLNodeBase_t*)InterlockedPushEntrySListRelease(&m_Head, pNode); +#else + return (TSLNodeBase_t*)InterlockedPushEntrySList(&m_Head, pNode); +#endif +#else + TSLHead_t oldHead; + TSLHead_t newHead; + +#if defined( PLATFORM_PS3 ) || defined( PLATFORM_X360 ) + __lwsync(); +#endif + +#ifdef PLATFORM_64BITS + newHead.value.Padding = 0; +#endif + for (;; ) + { + oldHead.value64x128 = m_Head.value64x128; + pNode->Next = oldHead.value.Next; + newHead.value.Next = pNode; + + newHead.value32.DepthAndSequence = oldHead.value32.DepthAndSequence + 0x10001; + + + if (ThreadInterlockedAssignIf64x128(&m_Head.value64x128, newHead.value64x128, oldHead.value64x128)) + { + break; + } + ThreadPause(); + }; + + return (TSLNodeBase_t*)oldHead.value.Next; +#endif + } + + TSLNodeBase_t* Pop() + { +#ifdef USE_NATIVE_SLIST +#ifdef _X360 + TSLNodeBase_t* pNode = (TSLNodeBase_t*)InterlockedPopEntrySListAcquire(&m_Head); +#else + TSLNodeBase_t* pNode = (TSLNodeBase_t*)InterlockedPopEntrySList(&m_Head); +#endif + return pNode; +#else + TSLHead_t oldHead; + TSLHead_t newHead; + +#ifdef PLATFORM_64BITS + newHead.value.Padding = 0; +#endif + for (;; ) + { + oldHead.value64x128 = m_Head.value64x128; + if (!oldHead.value.Next) + return NULL; + + newHead.value.Next = oldHead.value.Next->Next; + newHead.value32.DepthAndSequence = oldHead.value32.DepthAndSequence - 1; + + + if (ThreadInterlockedAssignIf64x128(&m_Head.value64x128, newHead.value64x128, oldHead.value64x128)) + { +#if defined( PLATFORM_PS3 ) || defined( PLATFORM_X360 ) + __lwsync(); +#endif + break; + } + ThreadPause(); + }; + + return (TSLNodeBase_t*)oldHead.value.Next; +#endif + } + + TSLNodeBase_t* Detach() + { +#ifdef USE_NATIVE_SLIST + TSLNodeBase_t* pBase = (TSLNodeBase_t*)InterlockedFlushSList(&m_Head); +#if defined( _X360 ) || defined( _PS3 ) + __lwsync(); +#endif + return pBase; +#else + TSLHead_t oldHead; + TSLHead_t newHead; + +#ifdef PLATFORM_64BITS + newHead.value.Padding = 0; +#endif + do + { + ThreadPause(); + + oldHead.value64x128 = m_Head.value64x128; + if (!oldHead.value.Next) + return NULL; + + newHead.value.Next = NULL; + newHead.value32.DepthAndSequence = oldHead.value32.DepthAndSequence & 0xffff0000; + + } while (!ThreadInterlockedAssignIf64x128(&m_Head.value64x128, newHead.value64x128, oldHead.value64x128)); + + return (TSLNodeBase_t*)oldHead.value.Next; +#endif + } + + TSLHead_t* AccessUnprotected() + { + return &m_Head; + } + + int Count() const + { +#ifdef USE_NATIVE_SLIST + return QueryDepthSList(const_cast(&m_Head)); +#else + return m_Head.value.Depth; +#endif + } + +private: + TSLHead_t m_Head; +} TSLIST_HEAD_ALIGN_POST; + +template +class TSLIST_HEAD_ALIGN CTSSimpleList : public CTSListBase +{ +public: + void Push(T* pNode) + { + Assert(sizeof(T) >= sizeof(TSLNodeBase_t)); + CTSListBase::Push((TSLNodeBase_t*)pNode); + } + + T* Pop() + { + return (T*)CTSListBase::Pop(); + } +} TSLIST_HEAD_ALIGN_POST; + +template< class T > +class TSLIST_HEAD_ALIGN CTSPool : public CTSListBase +{ + struct TSLIST_NODE_ALIGN simpleTSPoolStruct_t : public TSLNodeBase_t + { + T elem; + } TSLIST_NODE_ALIGN_POST; + +public: + + ~CTSPool() + { + Purge(); + } + + void Purge() + { + simpleTSPoolStruct_t* pNode = NULL; + while (1) + { + pNode = (simpleTSPoolStruct_t*)CTSListBase::Pop(); + if (!pNode) + break; + delete pNode; + } + } + + void PutObject(T* pInfo) + { + char* pElem = (char*)pInfo; + pElem -= offsetof(simpleTSPoolStruct_t, elem); + simpleTSPoolStruct_t* pNode = (simpleTSPoolStruct_t*)pElem; + + CTSListBase::Push(pNode); + } + + T* GetObject() + { + simpleTSPoolStruct_t* pNode = (simpleTSPoolStruct_t*)CTSListBase::Pop(); + if (!pNode) + { + pNode = new simpleTSPoolStruct_t; + } + return &pNode->elem; + } + + FORCEINLINE T* Get() + { + return GetObject(); + } +} TSLIST_HEAD_ALIGN_POST; +template +class TSLIST_HEAD_ALIGN CTSList : public CTSListBase +{ +public: + struct TSLIST_NODE_ALIGN Node_t : public TSLNodeBase_t + { + Node_t() {} + Node_t(const T& init) : elem(init) {} + T elem; + + static void* operator new(size_t size) + { + Node_t* pNode = (Node_t*)MemAlloc_AllocAlignedFileLine(size, TSLIST_NODE_ALIGNMENT, __FILE__, __LINE__); + return pNode; + } + + static void* operator new(size_t size, int nBlockUse, const char* pFileName, int nLine) + { + Node_t* pNode = (Node_t*)MemAlloc_AllocAlignedFileLine(size, TSLIST_NODE_ALIGNMENT, pFileName, nLine); + return pNode; + } + + static void operator delete(void* p) + { + MemAlloc_FreeAligned(p); + } + static void operator delete(void* p, int nBlockUse, const char* pFileName, int nLine) + { + MemAlloc_FreeAligned(p); + } + + } TSLIST_NODE_ALIGN_POST; + + ~CTSList() + { + Purge(); + } + + void Purge() + { + Node_t* pCurrent = Detach(); + Node_t* pNext; + while (pCurrent) + { + pNext = (Node_t*)pCurrent->Next; + delete pCurrent; + pCurrent = pNext; + } + } + + void RemoveAll() + { + Purge(); + } + + Node_t* Push(Node_t* pNode) + { + return (Node_t*)CTSListBase::Push(pNode); + } + + Node_t* Pop() + { + return (Node_t*)CTSListBase::Pop(); + } + + void PushItem(const T& init) + { + Push(new Node_t(init)); + } + + bool PopItem(T* pResult) + { + Node_t* pNode = Pop(); + if (!pNode) + return false; + *pResult = pNode->elem; + delete pNode; + return true; + } + + Node_t* Detach() + { + return (Node_t*)CTSListBase::Detach(); + } + +} TSLIST_HEAD_ALIGN_POST; + +template +class TSLIST_HEAD_ALIGN CTSListWithFreeList : public CTSListBase +{ +public: + struct TSLIST_NODE_ALIGN Node_t : public TSLNodeBase_t + { + Node_t() {} + Node_t(const T& init) : elem(init) {} + + T elem; + } TSLIST_NODE_ALIGN_POST; + + ~CTSListWithFreeList() + { + Purge(); + } + + void Purge() + { + Node_t* pCurrent = Detach(); + Node_t* pNext; + while (pCurrent) + { + pNext = (Node_t*)pCurrent->Next; + delete pCurrent; + pCurrent = pNext; + } + pCurrent = (Node_t*)m_FreeList.Detach(); + while (pCurrent) + { + pNext = (Node_t*)pCurrent->Next; + delete pCurrent; + pCurrent = pNext; + } + } + + void RemoveAll() + { + Node_t* pCurrent = Detach(); + Node_t* pNext; + while (pCurrent) + { + pNext = (Node_t*)pCurrent->Next; + m_FreeList.Push(pCurrent); + pCurrent = pNext; + } + } + + Node_t* Push(Node_t* pNode) + { + return (Node_t*)CTSListBase::Push(pNode); + } + + Node_t* Pop() + { + return (Node_t*)CTSListBase::Pop(); + } + + void PushItem(const T& init) + { + Node_t* pNode = (Node_t*)m_FreeList.Pop(); + if (!pNode) + { + pNode = new Node_t; + } + pNode->elem = init; + Push(pNode); + } + + bool PopItem(T* pResult) + { + Node_t* pNode = Pop(); + if (!pNode) + return false; + *pResult = pNode->elem; + m_FreeList.Push(pNode); + return true; + } + + Node_t* Detach() + { + return (Node_t*)CTSListBase::Detach(); + } + + void FreeNode(Node_t* pNode) + { + m_FreeList.Push(pNode); + } + +private: + CTSListBase m_FreeList; +} TSLIST_HEAD_ALIGN_POST; + +template +class TSLIST_HEAD_ALIGN CTSQueue +{ +public: + + static void* operator new(size_t size) + { + CTSQueue* pNode = (CTSQueue*)MemAlloc_AllocAlignedFileLine(size, TSLIST_HEAD_ALIGNMENT, __FILE__, __LINE__); + return pNode; + } + + static void* operator new(size_t size, int nBlockUse, const char* pFileName, int nLine) + { + CTSQueue* pNode = (CTSQueue*)MemAlloc_AllocAlignedFileLine(size, TSLIST_HEAD_ALIGNMENT, pFileName, nLine); + return pNode; + } + + static void operator delete(void* p) + { + MemAlloc_FreeAligned(p); + } + + static void operator delete(void* p, int nBlockUse, const char* pFileName, int nLine) + { + MemAlloc_FreeAligned(p); + } + +private: + static void* operator new[](size_t size) throw() + { + return NULL; + } + + static void operator delete [](void* p) + { + } + +public: + + struct TSLIST_NODE_ALIGN Node_t + { + static void* operator new(size_t size) + { + Node_t* pNode = (Node_t*)MemAlloc_AllocAlignedFileLine(size, TSLIST_HEAD_ALIGNMENT, __FILE__, __LINE__); + return pNode; + } + + static void* operator new(size_t size, int nBlockUse, const char* pFileName, int nLine) + { + Node_t* pNode = (Node_t*)MemAlloc_AllocAlignedFileLine(size, TSLIST_HEAD_ALIGNMENT, pFileName, nLine); + return pNode; + } + + static void operator delete(void* p) + { + MemAlloc_FreeAligned(p); + } + + static void operator delete(void* p, int nBlockUse, const char* pFileName, int nLine) + { + MemAlloc_FreeAligned(p); + } + + Node_t() {} + Node_t(const T& init) : elem(init) {} + + Node_t* pNext; + T elem; + } TSLIST_NODE_ALIGN_POST; + + union TSLIST_HEAD_ALIGN NodeLink_t + { + static void* operator new(size_t size) + { + NodeLink_t* pNode = (NodeLink_t*)MemAlloc_AllocAlignedFileLine(size, TSLIST_HEAD_ALIGNMENT, __FILE__, __LINE__); + return pNode; + } + + static void operator delete(void* p) + { + MemAlloc_FreeAligned(p); + } + + struct Value_t + { + Node_t* pNode; + intp sequence; + } value; + +#ifdef PLATFORM_64BITS + int128 value64x128; +#else + int64 value64x128; +#endif + } TSLIST_HEAD_ALIGN_POST; + + CTSQueue() + { + COMPILE_TIME_ASSERT(sizeof(Node_t) >= sizeof(TSLNodeBase_t)); + if (((size_t)&m_Head) % TSLIST_HEAD_ALIGNMENT != 0) + { + Error("CTSQueue: Misaligned queue\n"); + DebuggerBreak(); + } + if (((size_t)&m_Tail) % TSLIST_HEAD_ALIGNMENT != 0) + { + Error("CTSQueue: Misaligned queue\n"); + DebuggerBreak(); + } + m_Count = 0; + m_Head.value.sequence = m_Tail.value.sequence = 0; + m_Head.value.pNode = m_Tail.value.pNode = new Node_t; + m_Head.value.pNode->pNext = End(); + } + + ~CTSQueue() + { + Purge(); + Assert(m_Count == 0); + Assert(m_Head.value.pNode == m_Tail.value.pNode); + Assert(m_Head.value.pNode->pNext == End()); + delete m_Head.value.pNode; + } + + void Purge() + { + if (IsDebug()) + { + ValidateQueue(); + } + + Node_t* pNode; + while ((pNode = Pop()) != NULL) + { + delete pNode; + } + + while ((pNode = (Node_t*)m_FreeNodes.Pop()) != NULL) + { + delete pNode; + } + + Assert(m_Count == 0); + Assert(m_Head.value.pNode == m_Tail.value.pNode); + Assert(m_Head.value.pNode->pNext == End()); + + m_Head.value.sequence = m_Tail.value.sequence = 0; + } + + void RemoveAll() + { + if (IsDebug()) + { + ValidateQueue(); + } + + Node_t* pNode; + while ((pNode = Pop()) != NULL) + { + m_FreeNodes.Push((TSLNodeBase_t*)pNode); + } + } + + bool ValidateQueue() + { + if (IsDebug()) + { + bool bResult = true; + int nNodes = 0; + if (m_Tail.value.pNode->pNext != End()) + { + DebuggerBreakIfDebugging(); + bResult = false; + } + + if (m_Count == 0) + { + if (m_Head.value.pNode != m_Tail.value.pNode) + { + DebuggerBreakIfDebugging(); + bResult = false; + } + } + + Node_t* pNode = m_Head.value.pNode; + while (pNode != End()) + { + nNodes++; + pNode = pNode->pNext; + } + + nNodes--; + + if (nNodes != m_Count) + { + DebuggerBreakIfDebugging(); + bResult = false; + } + + if (!bResult) + { + Msg("Corrupt CTSQueueDetected"); + } + + return bResult; + } + else + { + return true; + } + } + + void FinishPush(Node_t* pNode, const NodeLink_t& oldTail) + { + NodeLink_t newTail; + + newTail.value.pNode = pNode; + newTail.value.sequence = oldTail.value.sequence + 1; + + ThreadMemoryBarrier(); + + InterlockedCompareExchangeNodeLink(&m_Tail, newTail, oldTail); + } + + Node_t* Push(Node_t* pNode) + { +#ifdef _DEBUG + if ((size_t)pNode % TSLIST_NODE_ALIGNMENT != 0) + { + Error("CTSListBase: Misaligned node\n"); + DebuggerBreak(); + } +#endif + + NodeLink_t oldTail; + + pNode->pNext = End(); + + for (;; ) + { + oldTail.value.sequence = m_Tail.value.sequence; + oldTail.value.pNode = m_Tail.value.pNode; + if (InterlockedCompareExchangeNode(&(oldTail.value.pNode->pNext), pNode, End()) == End()) + { + break; + } + else + { + FinishPush(oldTail.value.pNode->pNext, oldTail); + } + } + + FinishPush(pNode, oldTail); + + m_Count++; + + return oldTail.value.pNode; + } + + Node_t* Pop() + { +#define TSQUEUE_BAD_NODE_LINK ( (Node_t *)INT_TO_POINTER( 0xdeadbeef ) ) + NodeLink_t* volatile pHead = &m_Head; + NodeLink_t* volatile pTail = &m_Tail; + Node_t* volatile* pHeadNode = &m_Head.value.pNode; + volatile intp* volatile pHeadSequence = &m_Head.value.sequence; + Node_t* volatile* pTailNode = &pTail->value.pNode; + + NodeLink_t head; + NodeLink_t newHead; + Node_t* pNext; + intp tailSequence; + T elem; + + for (;; ) + { + head.value.sequence = *pHeadSequence; + ThreadMemoryBarrier(); + head.value.pNode = *pHeadNode; + tailSequence = pTail->value.sequence; + pNext = head.value.pNode->pNext; + + if (!pNext || head.value.sequence != *pHeadSequence) + continue; + + if (bTestOptimizer) + { + if (pNext == TSQUEUE_BAD_NODE_LINK) + { + Msg("Bad node link detected\n"); + continue; + } + } + + if (head.value.pNode == *pTailNode) + { + if (pNext == End()) + return NULL; + + NodeLink_t& oldTail = head; + oldTail.value.sequence = tailSequence; + FinishPush(pNext, oldTail); + continue; + } + + if (pNext != End()) + { + elem = pNext->elem; + newHead.value.pNode = pNext; + newHead.value.sequence = head.value.sequence + 1; + if (InterlockedCompareExchangeNodeLink(pHead, newHead, head)) + { + ThreadMemoryBarrier(); + if (bTestOptimizer) + { + head.value.pNode->pNext = TSQUEUE_BAD_NODE_LINK; + } + break; + } + } + } + + m_Count--; + head.value.pNode->elem = elem; + return head.value.pNode; + } + + void FreeNode(Node_t* pNode) + { + m_FreeNodes.Push((TSLNodeBase_t*)pNode); + } + + void PushItem(const T& init) + { + Node_t* pNode = (Node_t*)m_FreeNodes.Pop(); + if (pNode) + { + pNode->elem = init; + } + else + { + pNode = new Node_t(init); + } + Push(pNode); + } + + bool PopItem(T* pResult) + { + Node_t* pNode = Pop(); + if (!pNode) + return false; + + *pResult = pNode->elem; + m_FreeNodes.Push((TSLNodeBase_t*)pNode); + return true; + } + + int Count() const + { + return m_Count; + } + +private: + Node_t* End() { return (Node_t*)this; } + + Node_t* InterlockedCompareExchangeNode(Node_t* volatile* ppNode, Node_t* value, Node_t* comperand) + { + return (Node_t*)::ThreadInterlockedCompareExchangePointer((void**)ppNode, value, comperand); + } + + bool InterlockedCompareExchangeNodeLink(NodeLink_t volatile* pLink, const NodeLink_t& value, const NodeLink_t& comperand) + { + return ThreadInterlockedAssignIf64x128(&pLink->value64x128, value.value64x128, comperand.value64x128); + } + + NodeLink_t m_Head; + NodeLink_t m_Tail; + + CInterlockedInt m_Count; + + CTSListBase m_FreeNodes; +} TSLIST_NODE_ALIGN_POST; + +#if defined( _WIN32 ) +#pragma warning( pop ) +#endif + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/uniqueid.h b/SpyCustom/sdk/uniqueid.h new file mode 100644 index 0000000..e71f93e --- /dev/null +++ b/SpyCustom/sdk/uniqueid.h @@ -0,0 +1,37 @@ +#ifndef UNIQUEID_H +#define UNIQUEID_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "utlvector.h" + + +struct UniqueId_t; +class CUtlBuffer; + + +struct UniqueId_t +{ + unsigned char m_Value[16]; +}; + + +void CreateUniqueId(UniqueId_t* pDest); +void InvalidateUniqueId(UniqueId_t* pDest); +bool IsUniqueIdValid(const UniqueId_t& id); +bool IsUniqueIdEqual(const UniqueId_t& id1, const UniqueId_t& id2); +void UniqueIdToString(const UniqueId_t& id, char* pBuf, int nMaxLen); +bool UniqueIdFromString(UniqueId_t* pDest, const char* pBuf, int nMaxLen = 0); +void CopyUniqueId(const UniqueId_t& src, UniqueId_t* pDest); +bool Serialize(CUtlBuffer& buf, const UniqueId_t& src); +bool Unserialize(CUtlBuffer& buf, UniqueId_t& dest); + +inline bool operator ==(const UniqueId_t& lhs, const UniqueId_t& rhs) +{ + return !Q_memcmp((void*)&lhs.m_Value[0], (void*)&rhs.m_Value[0], sizeof(lhs.m_Value)); +} + + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/usercmd.h b/SpyCustom/sdk/usercmd.h new file mode 100644 index 0000000..01e7458 --- /dev/null +++ b/SpyCustom/sdk/usercmd.h @@ -0,0 +1,295 @@ +#if !defined( USERCMD_H ) +#define USERCMD_H +#ifdef _WIN32 +#pragma once +#endif + +#include "vector.h" +#include "utlvector.h" +#include "imovehelper.h" +#include "checksum_crc.h" + + +class bf_read; +class bf_write; + +class CEntityGroundContact +{ +public: + int entindex; + float minheight; + float maxheight; +}; + +#ifdef DOTA_DLL + +class CUnitOrders +{ +public: + + CUnitOrders() + { + m_nOrderSequenceNumber = 0; + } + + void Reset(void) + { + m_nUnits.RemoveAll(); + m_nOrderType = 0; + m_nTargetIndex = 0; + m_vPosition = vec3_origin; + m_nAbilityIndex = 0; + } + + int m_nOrderSequenceNumber; + CUtlVector m_nUnits; + int m_nOrderType; + int m_nTargetIndex; + int m_nAbilityIndex; + Vector m_vPosition; +}; + +#endif + + +class CUserCmd +{ +public: + CUserCmd() + { + Reset(); + } + + virtual ~CUserCmd() { }; + + void Reset() + { + command_number = 0; + tick_count = 0; + viewangles.Init(); + aimdirection.Init(); + forwardmove = 0.0f; + sidemove = 0.0f; + upmove = 0.0f; + buttons = 0; + impulse = 0; + weaponselect = 0; + weaponsubtype = 0; + random_seed = 0; +#ifndef CLIENT_DLL + server_random_seed = 0; +#endif + mousedx = 0; + mousedy = 0; + + hasbeenpredicted = false; +#if defined( HL2_DLL ) || defined( HL2_CLIENT_DLL ) + entitygroundcontact.RemoveAll(); +#endif + +#ifdef DOTA_DLL + dota_unitorders.Reset(); +#endif + +#if defined ( PORTAL2 ) + player_held_entity = 0; + held_entity_was_grabbed_through_portal = 0; + + command_acknowledgements_pending = 0; + predictedPortalTeleportations = 0; +#endif + + headangles.Init(); + headoffset.Init(); + +#if defined( INFESTED_DLL ) || defined( DOTA_DLL ) + crosshairtrace = vec3_origin; +#endif + +#ifdef INFESTED_DLL + crosshair_entity = 0; + forced_action = 0; + sync_kill_ent = 0; + skill_dest.Init(); + skill_dest_ent = 0; + +#endif + +#if defined( KEEP_COMMAND_REPREDICTION_COUNT ) + debug_RepredictionCount = 0; +#endif + } + + CUserCmd& operator =(const CUserCmd& src) + { + if (this == &src) + return *this; + + command_number = src.command_number; + tick_count = src.tick_count; + viewangles = src.viewangles; + aimdirection = src.aimdirection; + forwardmove = src.forwardmove; + sidemove = src.sidemove; + upmove = src.upmove; + buttons = src.buttons; + impulse = src.impulse; + weaponselect = src.weaponselect; + weaponsubtype = src.weaponsubtype; + random_seed = src.random_seed; +#ifndef CLIENT_DLL + server_random_seed = src.server_random_seed; +#endif + mousedx = src.mousedx; + mousedy = src.mousedy; + + hasbeenpredicted = src.hasbeenpredicted; + +#if defined( HL2_DLL ) || defined( HL2_CLIENT_DLL ) + entitygroundcontact = src.entitygroundcontact; +#endif + +#if defined ( PORTAL2 ) + player_held_entity = src.player_held_entity; + held_entity_was_grabbed_through_portal = src.held_entity_was_grabbed_through_portal; + command_acknowledgements_pending = src.command_acknowledgements_pending; + predictedPortalTeleportations = src.predictedPortalTeleportations; +#endif + + headangles = src.headangles; + headoffset = src.headoffset; +#if defined( INFESTED_DLL ) || defined( DOTA_DLL ) + crosshairtrace = src.crosshairtrace; +#endif + +#ifdef INFESTED_DLL + crosshair_entity = src.crosshair_entity; + forced_action = src.forced_action; + sync_kill_ent = src.sync_kill_ent; + skill_dest = src.skill_dest; + skill_dest_ent = src.skill_dest_ent; +#endif + +#ifdef DOTA_DLL + dota_unitorders = src.dota_unitorders; +#endif + +#if defined( KEEP_COMMAND_REPREDICTION_COUNT ) + debug_RepredictionCount = src.debug_RepredictionCount; +#endif + + return *this; + } + + CUserCmd(const CUserCmd& src) + { + *this = src; + } + + CRC32_t GetChecksum(void) const + { + CRC32_t crc; + + CRC32_Init(&crc); + CRC32_ProcessBuffer(&crc, &command_number, sizeof(command_number)); + CRC32_ProcessBuffer(&crc, &tick_count, sizeof(tick_count)); + CRC32_ProcessBuffer(&crc, &viewangles, sizeof(viewangles)); + CRC32_ProcessBuffer(&crc, &aimdirection, sizeof(aimdirection)); + CRC32_ProcessBuffer(&crc, &forwardmove, sizeof(forwardmove)); + CRC32_ProcessBuffer(&crc, &sidemove, sizeof(sidemove)); + CRC32_ProcessBuffer(&crc, &upmove, sizeof(upmove)); + CRC32_ProcessBuffer(&crc, &buttons, sizeof(buttons)); + CRC32_ProcessBuffer(&crc, &impulse, sizeof(impulse)); + CRC32_ProcessBuffer(&crc, &weaponselect, sizeof(weaponselect)); + CRC32_ProcessBuffer(&crc, &weaponsubtype, sizeof(weaponsubtype)); + CRC32_ProcessBuffer(&crc, &random_seed, sizeof(random_seed)); + CRC32_ProcessBuffer(&crc, &mousedx, sizeof(mousedx)); + CRC32_ProcessBuffer(&crc, &mousedy, sizeof(mousedy)); + +#if defined( INFESTED_DLL ) || defined( DOTA_DLL ) + CRC32_ProcessBuffer(&crc, &crosshairtrace, sizeof(crosshairtrace)); +#endif + +#if defined ( PORTAL2 ) + CRC32_ProcessBuffer(&crc, &player_held_entity, sizeof(player_held_entity)); + CRC32_ProcessBuffer(&crc, &held_entity_was_grabbed_through_portal, sizeof(held_entity_was_grabbed_through_portal)); + CRC32_ProcessBuffer(&crc, &command_acknowledgements_pending, sizeof(command_acknowledgements_pending)); + CRC32_ProcessBuffer(&crc, &predictedPortalTeleportations, sizeof(predictedPortalTeleportations)); +#endif + +#ifdef INFESTED_DLL + CRC32_ProcessBuffer(&crc, &crosshair_entity, sizeof(crosshair_entity)); + CRC32_ProcessBuffer(&crc, &forced_action, sizeof(forced_action)); + CRC32_ProcessBuffer(&crc, &sync_kill_ent, sizeof(sync_kill_ent)); + CRC32_ProcessBuffer(&crc, &skill_dest, sizeof(skill_dest)); + CRC32_ProcessBuffer(&crc, &skill_dest_ent, sizeof(skill_dest_ent)); +#endif + CRC32_Final(&crc); + + return crc; + } + + int command_number; + + int tick_count; + + QAngle viewangles; + Vector aimdirection; + float forwardmove; + float sidemove; + float upmove; + int buttons; + byte impulse; + int weaponselect; + int weaponsubtype; + + int random_seed; + +#ifndef CLIENT_DLL + int server_random_seed; +#endif + + short mousedx; + short mousedy; + + bool hasbeenpredicted; + +#if defined( HL2_DLL ) || defined( HL2_CLIENT_DLL ) + CUtlVector< CEntityGroundContact > entitygroundcontact; +#endif + +#if defined ( DOTA_DLL ) + CUnitOrders dota_unitorders; +#endif + +#if defined ( PORTAL2 ) + short player_held_entity; + short held_entity_was_grabbed_through_portal; + + unsigned short command_acknowledgements_pending; + uint8 predictedPortalTeleportations; +#endif + + QAngle headangles; + Vector headoffset; +#if defined( INFESTED_DLL ) || defined( DOTA_DLL ) + Vector crosshairtrace; +#endif + +#ifdef INFESTED_DLL + short crosshair_entity; + byte forced_action; + short sync_kill_ent; + Vector skill_dest; + short skill_dest_ent; +#endif + +#if defined( KEEP_COMMAND_REPREDICTION_COUNT ) + unsigned int debug_RepredictionCount; +#endif +}; + +void ReadUsercmd(bf_read* buf, CUserCmd* move, CUserCmd* from); +void WriteUsercmd(bf_write* buf, const CUserCmd* to, const CUserCmd* from); + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/userid.h b/SpyCustom/sdk/userid.h new file mode 100644 index 0000000..d8c2ef4 --- /dev/null +++ b/SpyCustom/sdk/userid.h @@ -0,0 +1,27 @@ +#ifndef USERID_H +#define USERID_H +#ifdef _WIN32 +#pragma once +#endif + +#if !defined( INCLUDED_STEAM_STEAMUSERIDTYPES_H ) +#include "SteamCommon.h" +#endif + +#define IDTYPE_WON 0 +#define IDTYPE_STEAM 1 +#define IDTYPE_VALVE 2 +#define IDTYPE_HLTV 3 +#define IDTYPE_REPLAY 4 +typedef struct USERID_s +{ + int idtype; + + union + { + TSteamGlobalUserID steamid; + } uid; + +} USERID_t; + +#endif diff --git a/SpyCustom/sdk/utlblockmemory.h b/SpyCustom/sdk/utlblockmemory.h new file mode 100644 index 0000000..7fb4512 --- /dev/null +++ b/SpyCustom/sdk/utlblockmemory.h @@ -0,0 +1,294 @@ +#ifndef UTLBLOCKMEMORY_H +#define UTLBLOCKMEMORY_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "dbg.h" +#include "platform.h" +#include "mathlib.h" + +#include "memalloc.h" +#include "memdbgon.h" + +#pragma warning (disable:4100) +#pragma warning (disable:4514) + +#ifdef UTBLOCKLMEMORY_TRACK +#define UTLBLOCKMEMORY_TRACK_ALLOC() MemAlloc_RegisterAllocation( "Sum of all UtlBlockMemory", 0, NumAllocated() * sizeof(T), NumAllocated() * sizeof(T), 0 ) +#define UTLBLOCKMEMORY_TRACK_FREE() if ( !m_pMemory ) ; else MemAlloc_RegisterDeallocation( "Sum of all UtlBlockMemory", 0, NumAllocated() * sizeof(T), NumAllocated() * sizeof(T), 0 ) +#else +#define UTLBLOCKMEMORY_TRACK_ALLOC() ((void)0) +#define UTLBLOCKMEMORY_TRACK_FREE() ((void)0) +#endif + + +template< class T, class I > +class CUtlBlockMemory +{ +public: + CUtlBlockMemory(int nGrowSize = 0, int nInitSize = 0); + ~CUtlBlockMemory(); + + void Init(int nGrowSize = 0, int nInitSize = 0); + + T* Base() { return NULL; } + const T* Base() const { return NULL; } + + class Iterator_t + { + public: + Iterator_t(I i) : index(i) {} + I index; + + bool operator==(const Iterator_t it) const { return index == it.index; } + bool operator!=(const Iterator_t it) const { return index != it.index; } + }; + Iterator_t First() const { return Iterator_t(IsIdxValid(0) ? 0 : InvalidIndex()); } + Iterator_t Next(const Iterator_t& it) const { return Iterator_t(IsIdxValid(it.index + 1) ? it.index + 1 : InvalidIndex()); } + I GetIndex(const Iterator_t& it) const { return it.index; } + bool IsIdxAfter(I i, const Iterator_t& it) const { return i > it.index; } + bool IsValidIterator(const Iterator_t& it) const { return IsIdxValid(it.index); } + Iterator_t InvalidIterator() const { return Iterator_t(InvalidIndex()); } + + T& operator[](I i); + const T& operator[](I i) const; + T& Element(I i); + const T& Element(I i) const; + + bool IsIdxValid(I i) const; + static I InvalidIndex() { return (I)-1; } + + void Swap(CUtlBlockMemory< T, I >& mem); + + int NumAllocated() const; + int Count() const { return NumAllocated(); } + + void Grow(int num = 1); + + void EnsureCapacity(int num); + + void Purge(); + + void Purge(int numElements); + +protected: + int Index(int major, int minor) const { return (major << m_nIndexShift) | minor; } + int MajorIndex(int i) const { return i >> m_nIndexShift; } + int MinorIndex(int i) const { return i & m_nIndexMask; } + void ChangeSize(int nBlocks); + int NumElementsInBlock() const { return m_nIndexMask + 1; } + + T** m_pMemory; + int m_nBlocks; + int m_nIndexMask : 27; + int m_nIndexShift : 5; +}; + +template< class T, class I > +CUtlBlockMemory::CUtlBlockMemory(int nGrowSize, int nInitAllocationCount) + : m_pMemory(0), m_nBlocks(0), m_nIndexMask(0), m_nIndexShift(0) +{ + Init(nGrowSize, nInitAllocationCount); +} + +template< class T, class I > +CUtlBlockMemory::~CUtlBlockMemory() +{ + Purge(); +} + + +template< class T, class I > +void CUtlBlockMemory::Swap(CUtlBlockMemory< T, I >& mem) +{ + swap(m_pMemory, mem.m_pMemory); + swap(m_nBlocks, mem.m_nBlocks); + swap(m_nIndexMask, mem.m_nIndexMask); + swap(m_nIndexShift, mem.m_nIndexShift); +} + + +template< class T, class I > +void CUtlBlockMemory::Init(int nGrowSize , int nInitSize ) +{ + Purge(); + + if (nGrowSize == 0) + { + nGrowSize = (127 + sizeof(T)) / sizeof(T); + } + nGrowSize = SmallestPowerOfTwoGreaterOrEqual(nGrowSize); + m_nIndexMask = nGrowSize - 1; + + m_nIndexShift = 0; + while (nGrowSize > 1) + { + nGrowSize >>= 1; + ++m_nIndexShift; + } + Assert(m_nIndexMask + 1 == (1 << m_nIndexShift)); + + Grow(nInitSize); +} + + +template< class T, class I > +inline T& CUtlBlockMemory::operator[](I i) +{ + Assert(IsIdxValid(i)); + T* pBlock = m_pMemory[MajorIndex(i)]; + return pBlock[MinorIndex(i)]; +} + +template< class T, class I > +inline const T& CUtlBlockMemory::operator[](I i) const +{ + Assert(IsIdxValid(i)); + const T* pBlock = m_pMemory[MajorIndex(i)]; + return pBlock[MinorIndex(i)]; +} + +template< class T, class I > +inline T& CUtlBlockMemory::Element(I i) +{ + Assert(IsIdxValid(i)); + T* pBlock = m_pMemory[MajorIndex(i)]; + return pBlock[MinorIndex(i)]; +} + +template< class T, class I > +inline const T& CUtlBlockMemory::Element(I i) const +{ + Assert(IsIdxValid(i)); + const T* pBlock = m_pMemory[MajorIndex(i)]; + return pBlock[MinorIndex(i)]; +} + + +template< class T, class I > +inline int CUtlBlockMemory::NumAllocated() const +{ + return m_nBlocks * NumElementsInBlock(); +} + + +template< class T, class I > +inline bool CUtlBlockMemory::IsIdxValid(I i) const +{ + return (i >= 0) && (MajorIndex(i) < m_nBlocks); +} + +template< class T, class I > +void CUtlBlockMemory::Grow(int num) +{ + if (num <= 0) + return; + + int nBlockSize = NumElementsInBlock(); + int nBlocks = (num + nBlockSize - 1) / nBlockSize; + + ChangeSize(m_nBlocks + nBlocks); +} + +template< class T, class I > +void CUtlBlockMemory::ChangeSize(int nBlocks) +{ + UTLBLOCKMEMORY_TRACK_FREE(); + + int nBlocksOld = m_nBlocks; + m_nBlocks = nBlocks; + + UTLBLOCKMEMORY_TRACK_ALLOC(); + + if (m_pMemory) + { + for (int i = m_nBlocks; i < nBlocksOld; ++i) + { + UTLBLOCKMEMORY_TRACK_FREE(); + free((void*)m_pMemory[i]); + } + + MEM_ALLOC_CREDIT_CLASS(); + m_pMemory = (T**)realloc(m_pMemory, m_nBlocks * sizeof(T*)); + Assert(m_pMemory); + } + else + { + MEM_ALLOC_CREDIT_CLASS(); + m_pMemory = (T**)malloc(m_nBlocks * sizeof(T*)); + Assert(m_pMemory); + } + + if (!m_pMemory) + { + Error("CUtlBlockMemory overflow!\n"); + } + + int nBlockSize = NumElementsInBlock(); + for (int i = nBlocksOld; i < m_nBlocks; ++i) + { + MEM_ALLOC_CREDIT_CLASS(); + m_pMemory[i] = (T*)malloc(nBlockSize * sizeof(T)); + Assert(m_pMemory[i]); + } +} + + +template< class T, class I > +inline void CUtlBlockMemory::EnsureCapacity(int num) +{ + Grow(num - NumAllocated()); +} + + +template< class T, class I > +void CUtlBlockMemory::Purge() +{ + if (!m_pMemory) + return; + + for (int i = 0; i < m_nBlocks; ++i) + { + UTLBLOCKMEMORY_TRACK_FREE(); + free((void*)m_pMemory[i]); + } + m_nBlocks = 0; + + UTLBLOCKMEMORY_TRACK_FREE(); + free((void*)m_pMemory); + m_pMemory = 0; +} + +template< class T, class I > +void CUtlBlockMemory::Purge(int numElements) +{ + Assert(numElements >= 0); + + int nAllocated = NumAllocated(); + if (numElements > nAllocated) + { + Assert(numElements <= nAllocated); + return; + } + + if (numElements <= 0) + { + Purge(); + return; + } + + int nBlockSize = NumElementsInBlock(); + int nBlocksOld = m_nBlocks; + int nBlocks = (numElements + nBlockSize - 1) / nBlockSize; + + if (nBlocks == m_nBlocks) + return; + + ChangeSize(nBlocks); +} + +#include "memdbgoff.h" + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/utlbuffer.h b/SpyCustom/sdk/utlbuffer.h new file mode 100644 index 0000000..bd56c8a --- /dev/null +++ b/SpyCustom/sdk/utlbuffer.h @@ -0,0 +1,1157 @@ +#ifndef UTLBUFFER_H +#define UTLBUFFER_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "utlmemory.h" +#include "byteswap.h" +#include + + +struct characterset_t; + + +class CUtlCharConversion +{ +public: + struct ConversionArray_t + { + char m_nActualChar; + char* m_pReplacementString; + }; + + CUtlCharConversion(char nEscapeChar, const char* pDelimiter, int nCount, ConversionArray_t* pArray); + char GetEscapeChar() const; + const char* GetDelimiter() const; + int GetDelimiterLength() const; + + const char* GetConversionString(char c) const; + int GetConversionLength(char c) const; + int MaxConversionLength() const; + + virtual char FindConversion(const char* pString, int* pLength); + +protected: + struct ConversionInfo_t + { + int m_nLength; + char* m_pReplacementString; + }; + + char m_nEscapeChar; + const char* m_pDelimiter; + int m_nDelimiterLength; + int m_nCount; + int m_nMaxConversionLength; + char m_pList[256]; + ConversionInfo_t m_pReplacements[256]; +}; + +#define BEGIN_CHAR_CONVERSION( _name, _delimiter, _escapeChar ) \ + static CUtlCharConversion::ConversionArray_t s_pConversionArray ## _name[] = { + +#define END_CHAR_CONVERSION( _name, _delimiter, _escapeChar ) \ + }; \ + CUtlCharConversion _name( _escapeChar, _delimiter, sizeof( s_pConversionArray ## _name ) / sizeof( CUtlCharConversion::ConversionArray_t ), s_pConversionArray ## _name ); + +#define BEGIN_CUSTOM_CHAR_CONVERSION( _className, _name, _delimiter, _escapeChar ) \ + static CUtlCharConversion::ConversionArray_t s_pConversionArray ## _name[] = { + +#define END_CUSTOM_CHAR_CONVERSION( _className, _name, _delimiter, _escapeChar ) \ + }; \ + _className _name( _escapeChar, _delimiter, sizeof( s_pConversionArray ## _name ) / sizeof( CUtlCharConversion::ConversionArray_t ), s_pConversionArray ## _name ); + +CUtlCharConversion* GetCStringCharConversion(); + +CUtlCharConversion* GetNoEscCharConversion(); + + +#define SetUtlBufferOverflowFuncs( _get, _put ) \ + SetOverflowFuncs( static_cast ( _get ), static_cast ( _put ) ) + + + +typedef unsigned short ushort; + +template < class A > +static const char* GetFmtStr(int nRadix = 10, bool bPrint = true) { Assert(0); return ""; } +#if defined( LINUX ) || defined( __clang__ ) || ( defined( _MSC_VER ) && _MSC_VER >= 1900 ) +template <> const char* GetFmtStr< short >(int nRadix, bool bPrint) { Assert(nRadix == 10); return "%hd"; } +template <> const char* GetFmtStr< ushort >(int nRadix, bool bPrint) { Assert(nRadix == 10); return "%hu"; } +template <> const char* GetFmtStr< int >(int nRadix, bool bPrint) { Assert(nRadix == 10); return "%d"; } +template <> const char* GetFmtStr< uint >(int nRadix, bool bPrint) { Assert(nRadix == 10 || nRadix == 16); return nRadix == 16 ? "%x" : "%u"; } +template <> const char* GetFmtStr< int64 >(int nRadix, bool bPrint) { Assert(nRadix == 10); return "%lld"; } +template <> const char* GetFmtStr< float >(int nRadix, bool bPrint) { Assert(nRadix == 10); return "%f"; } +template <> const char* GetFmtStr< double >(int nRadix, bool bPrint) { Assert(nRadix == 10); return bPrint ? "%.15lf" : "%lf"; } +#else +template <> static const char* GetFmtStr< short >(int nRadix, bool bPrint) { Assert(nRadix == 10); return "%hd"; } +template <> static const char* GetFmtStr< ushort >(int nRadix, bool bPrint) { Assert(nRadix == 10); return "%hu"; } +template <> static const char* GetFmtStr< int >(int nRadix, bool bPrint) { Assert(nRadix == 10); return "%d"; } +template <> static const char* GetFmtStr< uint >(int nRadix, bool bPrint) { Assert(nRadix == 10 || nRadix == 16); return nRadix == 16 ? "%x" : "%u"; } +template <> static const char* GetFmtStr< int64 >(int nRadix, bool bPrint) { Assert(nRadix == 10); return "%lld"; } +template <> static const char* GetFmtStr< float >(int nRadix, bool bPrint) { Assert(nRadix == 10); return "%f"; } +template <> static const char* GetFmtStr< double >(int nRadix, bool bPrint) { Assert(nRadix == 10); return bPrint ? "%.15lf" : "%lf"; } +#endif +class CUtlBuffer +{ +public: + enum SeekType_t + { + SEEK_HEAD = 0, + SEEK_CURRENT, + SEEK_TAIL + }; + + enum BufferFlags_t + { + TEXT_BUFFER = 0x1, + EXTERNAL_GROWABLE = 0x2, + CONTAINS_CRLF = 0x4, + READ_ONLY = 0x8, + AUTO_TABS_DISABLED = 0x10, + }; + + typedef bool (CUtlBuffer::* UtlBufferOverflowFunc_t)(int nSize); + + CUtlBuffer(int growSize = 0, int initSize = 0, int nFlags = 0); + CUtlBuffer(const void* pBuffer, int size, int nFlags = 0); + CUtlBuffer(const void* pBuffer, int size, bool crap) = delete; + + CUtlBuffer(const CUtlBuffer&); + CUtlBuffer& operator= (const CUtlBuffer&); + +#if VALVE_CPP11 + CUtlBuffer(CUtlBuffer&& moveFrom); + CUtlBuffer& operator= (CUtlBuffer&& moveFrom); +#endif + + unsigned char GetFlags() const; + + void SetBufferType(bool bIsText, bool bContainsCRLF); + + void EnsureCapacity(int num); + + void* AccessForDirectRead(int nBytes); + + void SetExternalBuffer(void* pMemory, int nSize, int nInitialPut, int nFlags = 0); + bool IsExternallyAllocated() const; + void AssumeMemory(void* pMemory, int nSize, int nInitialPut, int nFlags = 0); + void* Detach(); + void* DetachMemory(); + + void CopyBuffer(const CUtlBuffer& buffer); + void CopyBuffer(const void* pubData, int cubData); + + void Swap(CUtlBuffer& buf); + void Swap(CUtlMemory& mem); + + + FORCEINLINE void ActivateByteSwappingIfBigEndian(void) + { + if ((IsX360() || IsPS3())) + ActivateByteSwapping(true); + } + + + void ActivateByteSwapping(bool bActivate); + void SetBigEndian(bool bigEndian); + bool IsBigEndian(void); + + void Clear(); + + void Purge(); + + void Spew(); + + char GetChar(); + unsigned char GetUnsignedChar(); + short GetShort(); + unsigned short GetUnsignedShort(); + int GetInt(); + int64 GetInt64(); + unsigned int GetIntHex(); + unsigned int GetUnsignedInt(); + uint64 GetUnsignedInt64(); + float GetFloat(); + double GetDouble(); + void* GetPtr(); + void GetString(char* pString, int nMaxChars); + void Get(void* pMem, int size); + void GetLine(char* pLine, int nMaxChars); + + template void GetObjects(T* dest, int count = 1); + + int GetUpTo(void* pMem, int nSize); + + void GetDelimitedString(CUtlCharConversion* pConv, char* pString, int nMaxChars = 0); + char GetDelimitedChar(CUtlCharConversion* pConv); + + int PeekStringLength(); + + int PeekDelimitedStringLength(CUtlCharConversion* pConv, bool bActualSize = true); + + int Scanf(SCANF_FORMAT_STRING const char* pFmt, ...); + int VaScanf(const char* pFmt, va_list list); + + void EatWhiteSpace(); + + bool EatCPPComment(); + + bool ParseToken(const char* pStartingDelim, const char* pEndingDelim, char* pString, int nMaxLen); + + bool GetToken(const char* pToken); + + int ParseToken(characterset_t* pBreaks, char* pTokenBuf, int nMaxLen, bool bParseComments = true); + + void PutChar(char c); + void PutUnsignedChar(unsigned char uc); + void PutShort(short s); + void PutUnsignedShort(unsigned short us); + void PutInt(int i); + void PutInt64(int64 i); + void PutUnsignedInt(unsigned int u); + void PutUnsignedInt64(uint64 u); + void PutFloat(float f); + void PutDouble(double d); + void PutPtr(void*); + void PutString(const char* pString); + void Put(const void* pMem, int size); + + template void PutObjects(T* src, int count = 1); + + void PutDelimitedString(CUtlCharConversion* pConv, const char* pString); + void PutDelimitedChar(CUtlCharConversion* pConv, char c); + + void Printf(PRINTF_FORMAT_STRING const char* pFmt, ...) FMTFUNCTION(2, 3); + void VaPrintf(const char* pFmt, va_list list); + + void* PeekPut(int offset = 0); + const void* PeekGet(int offset = 0) const; + const void* PeekGet(int nMaxSize, int nOffset); + + int TellPut() const; + int TellGet() const; + + int TellMaxPut() const; + + int GetBytesRemaining() const; + + void SeekPut(SeekType_t type, int offset); + void SeekGet(SeekType_t type, int offset); + + const void* Base() const; + void* Base(); + + int Size() const; + + bool IsText() const; + + bool IsGrowable() const; + + bool IsValid() const; + + bool ContainsCRLF() const; + + bool IsReadOnly() const; + + bool ConvertCRLF(CUtlBuffer& outBuf); + + void PushTab(); + void PopTab(); + + void EnableTabs(bool bEnable); + +#if !defined( _GAMECONSOLE ) + void SwapCopy(CUtlBuffer& other); +#endif + +protected: + enum + { + PUT_OVERFLOW = 0x1, + GET_OVERFLOW = 0x2, + MAX_ERROR_FLAG = GET_OVERFLOW, + }; + + void SetOverflowFuncs(UtlBufferOverflowFunc_t getFunc, UtlBufferOverflowFunc_t putFunc); + + bool OnPutOverflow(int nSize); + bool OnGetOverflow(int nSize); + +protected: + bool CheckPut(int size); + bool CheckGet(int size); + + void AddNullTermination(int nPut); + bool WasLastCharacterCR(); + void PutTabs(); + + char GetDelimitedCharInternal(CUtlCharConversion* pConv); + void PutDelimitedCharInternal(CUtlCharConversion* pConv, char c); + + bool PutOverflow(int nSize); + bool GetOverflow(int nSize); + + bool PeekStringMatch(int nOffset, const char* pString, int nLen); + + int PeekLineLength(); + + int PeekWhiteSpace(int nOffset); + + bool CheckPeekGet(int nOffset, int nSize); + + bool CheckArbitraryPeekGet(int nOffset, int& nIncrement); + + template void GetType(T& dest); + template void GetTypeBin(T& dest); + template bool GetTypeText(T& value, int nRadix = 10); + template void GetObject(T* src); + + template void PutType(T src); + template void PutTypeBin(T src); + template void PutObject(T* src); + + CUtlMemory m_Memory; + int m_Get; + int m_Put; + + unsigned char m_Error; + unsigned char m_Flags; + unsigned char m_Reserved; +#if defined( _GAMECONSOLE ) + unsigned char pad; +#endif + + int m_nTab; + int m_nMaxPut; + int m_nOffset; + + UtlBufferOverflowFunc_t m_GetOverflowFunc; + UtlBufferOverflowFunc_t m_PutOverflowFunc; + + CByteswap m_Byteswap; +}; + + +inline CUtlBuffer& operator<<(CUtlBuffer& b, char v) +{ + b.PutChar(v); + return b; +} + +inline CUtlBuffer& operator<<(CUtlBuffer& b, unsigned char v) +{ + b.PutUnsignedChar(v); + return b; +} + +inline CUtlBuffer& operator<<(CUtlBuffer& b, short v) +{ + b.PutShort(v); + return b; +} + +inline CUtlBuffer& operator<<(CUtlBuffer& b, unsigned short v) +{ + b.PutUnsignedShort(v); + return b; +} + +inline CUtlBuffer& operator<<(CUtlBuffer& b, int v) +{ + b.PutInt(v); + return b; +} + +inline CUtlBuffer& operator<<(CUtlBuffer& b, unsigned int v) +{ + b.PutUnsignedInt(v); + return b; +} + +inline CUtlBuffer& operator<<(CUtlBuffer& b, float v) +{ + b.PutFloat(v); + return b; +} + +inline CUtlBuffer& operator<<(CUtlBuffer& b, double v) +{ + b.PutDouble(v); + return b; +} + +inline CUtlBuffer& operator<<(CUtlBuffer& b, const char* pv) +{ + b.PutString(pv); + return b; +} + +inline CUtlBuffer& operator<<(CUtlBuffer& b, const Vector& v) +{ + b << v.x << " " << v.y << " " << v.z; + return b; +} + +inline CUtlBuffer& operator<<(CUtlBuffer& b, const Vector2D& v) +{ + b << v.x << " " << v.y; + return b; +} + + +class CUtlInplaceBuffer : public CUtlBuffer +{ +public: + CUtlInplaceBuffer(int growSize = 0, int initSize = 0, int nFlags = 0); + +public: + bool InplaceGetLinePtr( char** ppszInBufferPtr, int* pnLineLength); + + char* InplaceGetLinePtr(void); +}; + + +inline int CUtlBuffer::TellGet() const +{ + return m_Get; +} + + +inline int CUtlBuffer::GetBytesRemaining() const +{ + return m_nMaxPut - TellGet(); +} + + +inline const void* CUtlBuffer::PeekGet(int offset) const +{ + return &m_Memory[m_Get + offset - m_nOffset]; +} + + +template +inline void CUtlBuffer::GetObject(T* dest) +{ + if (CheckGet(sizeof(T))) + { + if (!m_Byteswap.IsSwappingBytes() || (sizeof(T) == 1)) + { + *dest = *(T*)PeekGet(); + } + else + { + m_Byteswap.SwapFieldsToTargetEndian(dest, (T*)PeekGet()); + } + m_Get += sizeof(T); + } + else + { + Q_memset(&dest, 0, sizeof(T)); + } +} + + +template +inline void CUtlBuffer::GetObjects(T* dest, int count) +{ + for (int i = 0; i < count; ++i, ++dest) + { + GetObject(dest); + } +} + + +template +inline void CUtlBuffer::GetTypeBin(T& dest) +{ + if (CheckGet(sizeof(T))) + { + if (!m_Byteswap.IsSwappingBytes() || (sizeof(T) == 1)) + { + dest = *(T*)PeekGet(); + } + else + { + m_Byteswap.SwapBufferToTargetEndian(&dest, (T*)PeekGet()); + } + m_Get += sizeof(T); + } + else + { + dest = 0; + } +} + +template <> +inline void CUtlBuffer::GetTypeBin< float >(float& dest) +{ + if (CheckGet(sizeof(float))) + { + uintp pData = (uintp)PeekGet(); + if ((IsX360() || IsPS3()) && (pData & 0x03)) + { + ((unsigned char*)&dest)[0] = ((unsigned char*)pData)[0]; + ((unsigned char*)&dest)[1] = ((unsigned char*)pData)[1]; + ((unsigned char*)&dest)[2] = ((unsigned char*)pData)[2]; + ((unsigned char*)&dest)[3] = ((unsigned char*)pData)[3]; + } + else + { + dest = *(float*)pData; + } + if (m_Byteswap.IsSwappingBytes()) + { + m_Byteswap.SwapBufferToTargetEndian< float >(&dest, &dest); + } + m_Get += sizeof(float); + } + else + { + dest = 0; + } +} + +template <> +inline void CUtlBuffer::GetTypeBin< double >(double& dest) +{ + if (CheckGet(sizeof(double))) + { + uintp pData = (uintp)PeekGet(); + if ((IsX360() || IsPS3()) && (pData & 0x07)) + { + ((unsigned char*)&dest)[0] = ((unsigned char*)pData)[0]; + ((unsigned char*)&dest)[1] = ((unsigned char*)pData)[1]; + ((unsigned char*)&dest)[2] = ((unsigned char*)pData)[2]; + ((unsigned char*)&dest)[3] = ((unsigned char*)pData)[3]; + ((unsigned char*)&dest)[4] = ((unsigned char*)pData)[4]; + ((unsigned char*)&dest)[5] = ((unsigned char*)pData)[5]; + ((unsigned char*)&dest)[6] = ((unsigned char*)pData)[6]; + ((unsigned char*)&dest)[7] = ((unsigned char*)pData)[7]; + } + else + { + dest = *(double*)pData; + } + if (m_Byteswap.IsSwappingBytes()) + { + m_Byteswap.SwapBufferToTargetEndian< double >(&dest, &dest); + } + m_Get += sizeof(double); + } + else + { + dest = 0; + } +} + +template < class T > +inline T StringToNumber(char* pString, char** ppEnd, int nRadix) +{ + Assert(0); + *ppEnd = pString; + return 0; +} + +template <> +inline int8 StringToNumber(char* pString, char** ppEnd, int nRadix) +{ + return (int8)strtol(pString, ppEnd, nRadix); +} + +template <> +inline uint8 StringToNumber(char* pString, char** ppEnd, int nRadix) +{ + return (uint8)strtoul(pString, ppEnd, nRadix); +} + +template <> +inline int16 StringToNumber(char* pString, char** ppEnd, int nRadix) +{ + return (int16)strtol(pString, ppEnd, nRadix); +} + +template <> +inline uint16 StringToNumber(char* pString, char** ppEnd, int nRadix) +{ + return (uint16)strtoul(pString, ppEnd, nRadix); +} + +template <> +inline int32 StringToNumber(char* pString, char** ppEnd, int nRadix) +{ + return (int32)strtol(pString, ppEnd, nRadix); +} + +template <> +inline uint32 StringToNumber(char* pString, char** ppEnd, int nRadix) +{ + return (uint32)strtoul(pString, ppEnd, nRadix); +} + +template <> +inline int64 StringToNumber(char* pString, char** ppEnd, int nRadix) +{ +#if defined(_PS3) || defined(POSIX) + return (int64)strtoll(pString, ppEnd, nRadix); +#else + return (int64)_strtoi64(pString, ppEnd, nRadix); +#endif +} + +template <> +inline float StringToNumber(char* pString, char** ppEnd, int nRadix) +{ + NOTE_UNUSED(nRadix); + return (float)strtod(pString, ppEnd); +} + +template <> +inline double StringToNumber(char* pString, char** ppEnd, int nRadix) +{ + NOTE_UNUSED(nRadix); + return (double)strtod(pString, ppEnd); +} + +template +inline bool CUtlBuffer::GetTypeText(T& value, int nRadix ) +{ + int nLength = 128; + if (!CheckArbitraryPeekGet(0, nLength)) + { + value = 0; + return false; + } + + char* pStart = (char*)PeekGet(); + char* pEnd = pStart; + value = StringToNumber< T >(pStart, &pEnd, nRadix); + + int nBytesRead = (int)(pEnd - pStart); + if (nBytesRead == 0) + return false; + + m_Get += nBytesRead; + return true; +} + +template +inline void CUtlBuffer::GetType(T& dest) +{ + if (!IsText()) + { + GetTypeBin(dest); + } + else + { + GetTypeText(dest); + } +} + +inline char CUtlBuffer::GetChar() +{ + char c; + GetTypeBin(c); + return c; +} + +inline unsigned char CUtlBuffer::GetUnsignedChar() +{ + unsigned char c; + if (!IsText()) + { + GetTypeBin(c); + } + else + { + c = (unsigned char)GetUnsignedShort(); + } + return c; +} + +inline short CUtlBuffer::GetShort() +{ + short s; + GetType(s); + return s; +} + +inline unsigned short CUtlBuffer::GetUnsignedShort() +{ + unsigned short s; + GetType(s); + return s; +} + +inline int CUtlBuffer::GetInt() +{ + int i; + GetType(i); + return i; +} + +inline int64 CUtlBuffer::GetInt64() +{ + int64 i; + GetType(i); + return i; +} + +inline unsigned int CUtlBuffer::GetIntHex() +{ + uint i; + if (!IsText()) + { + GetTypeBin(i); + } + else + { + GetTypeText(i, 16); + } + return i; +} + +inline unsigned int CUtlBuffer::GetUnsignedInt() +{ + unsigned int i; + GetType(i); + return i; +} + +inline uint64 CUtlBuffer::GetUnsignedInt64() +{ + uint64 i; + GetType(i); + return i; +} + + +inline float CUtlBuffer::GetFloat() +{ + float f; + GetType(f); + return f; +} + +inline double CUtlBuffer::GetDouble() +{ + double d; + GetType(d); + return d; +} + +inline void* CUtlBuffer::GetPtr() +{ + void* p; +#if !defined(X64BITS) && !defined(PLATFORM_64BITS) + p = (void*)GetUnsignedInt(); +#else + p = (void*)GetInt64(); +#endif + return p; +} + +inline unsigned char CUtlBuffer::GetFlags() const +{ + return m_Flags; +} + + +inline bool CUtlBuffer::IsExternallyAllocated() const +{ + return m_Memory.IsExternallyAllocated(); +} + + +inline int CUtlBuffer::TellPut() const +{ + return m_Put; +} + + +inline int CUtlBuffer::TellMaxPut() const +{ + return m_nMaxPut; +} + + +inline void* CUtlBuffer::PeekPut(int offset) +{ + return &m_Memory[m_Put + offset - m_nOffset]; +} + + +template +inline void CUtlBuffer::PutObject(T* src) +{ + if (CheckPut(sizeof(T))) + { + if (!m_Byteswap.IsSwappingBytes() || (sizeof(T) == 1)) + { + *(T*)PeekPut() = *src; + } + else + { + m_Byteswap.SwapFieldsToTargetEndian((T*)PeekPut(), src); + } + m_Put += sizeof(T); + AddNullTermination(m_Put); + } +} + + +template +inline void CUtlBuffer::PutObjects(T* src, int count) +{ + for (int i = 0; i < count; ++i, ++src) + { + PutObject(src); + } +} + + +template +inline void CUtlBuffer::PutTypeBin(T src) +{ + if (CheckPut(sizeof(T))) + { + if (!m_Byteswap.IsSwappingBytes() || (sizeof(T) == 1)) + { + *(T*)PeekPut() = src; + } + else + { + m_Byteswap.SwapBufferToTargetEndian((T*)PeekPut(), &src); + } + m_Put += sizeof(T); + AddNullTermination(m_Put); + } +} + +#if defined( _GAMECONSOLE ) +template <> +inline void CUtlBuffer::PutTypeBin< float >(float src) +{ + if (CheckPut(sizeof(src))) + { + if (m_Byteswap.IsSwappingBytes()) + { + m_Byteswap.SwapBufferToTargetEndian(&src, &src); + } + + unsigned pData = (unsigned)PeekPut(); + if (pData & 0x03) + { + byte* dst = (byte*)pData; + byte* srcPtr = (byte*)&src; + dst[0] = srcPtr[0]; + dst[1] = srcPtr[1]; + dst[2] = srcPtr[2]; + dst[3] = srcPtr[3]; + } + else + { + *(float*)pData = src; + } + + m_Put += sizeof(float); + AddNullTermination(m_Put); + } +} + +template <> +inline void CUtlBuffer::PutTypeBin< double >(double src) +{ + if (CheckPut(sizeof(src))) + { + if (m_Byteswap.IsSwappingBytes()) + { + m_Byteswap.SwapBufferToTargetEndian(&src, &src); + } + + unsigned pData = (unsigned)PeekPut(); + if (pData & 0x07) + { + byte* dst = (byte*)pData; + byte* srcPtr = (byte*)&src; + dst[0] = srcPtr[0]; + dst[1] = srcPtr[1]; + dst[2] = srcPtr[2]; + dst[3] = srcPtr[3]; + dst[4] = srcPtr[4]; + dst[5] = srcPtr[5]; + dst[6] = srcPtr[6]; + dst[7] = srcPtr[7]; + } + else + { + *(double*)pData = src; + } + + m_Put += sizeof(double); + AddNullTermination(m_Put); + } +} +#endif + +template +inline void CUtlBuffer::PutType(T src) +{ + if (!IsText()) + { + PutTypeBin(src); + } + else + { + Printf(GetFmtStr< T >(), src); + } +} + +inline bool CUtlBuffer::WasLastCharacterCR() +{ + if (!IsText() || (TellPut() == 0)) + return false; + return (*(const char*)PeekPut(-1) == '\n'); +} + +inline void CUtlBuffer::PutTabs() +{ + int nTabCount = (m_Flags & AUTO_TABS_DISABLED) ? 0 : m_nTab; + for (int i = nTabCount; --i >= 0; ) + { + PutTypeBin('\t'); + } +} + + +inline void CUtlBuffer::PushTab() +{ + ++m_nTab; +} + +inline void CUtlBuffer::PopTab() +{ + if (--m_nTab < 0) + { + m_nTab = 0; + } +} + + +inline void CUtlBuffer::EnableTabs(bool bEnable) +{ + if (bEnable) + { + m_Flags &= ~AUTO_TABS_DISABLED; + } + else + { + m_Flags |= AUTO_TABS_DISABLED; + } +} + +inline void CUtlBuffer::PutChar(char c) +{ + if (WasLastCharacterCR()) + { + PutTabs(); + } + + PutTypeBin(c); +} + +inline void CUtlBuffer::PutUnsignedChar(unsigned char c) +{ + if (!IsText()) + { + PutTypeBin(c); + } + else + { + PutUnsignedShort(c); + } +} + +inline void CUtlBuffer::PutShort(short s) +{ + PutType(s); +} + +inline void CUtlBuffer::PutUnsignedShort(unsigned short s) +{ + PutType(s); +} + +inline void CUtlBuffer::PutInt(int i) +{ + PutType(i); +} + +inline void CUtlBuffer::PutInt64(int64 i) +{ + PutType(i); +} + +inline void CUtlBuffer::PutUnsignedInt(unsigned int u) +{ + PutType(u); +} + +inline void CUtlBuffer::PutUnsignedInt64(uint64 i) +{ + PutType(i); +} + + +inline void CUtlBuffer::PutFloat(float f) +{ + PutType(f); +} + +inline void CUtlBuffer::PutDouble(double d) +{ + PutType(d); +} + +inline void CUtlBuffer::PutPtr(void* p) +{ + if (!IsText()) + { + PutTypeBin(p); + } + else + { + Printf("0x%p", p); + } +} + +inline bool CUtlBuffer::IsText() const +{ + return (m_Flags & TEXT_BUFFER) != 0; +} + + +inline bool CUtlBuffer::IsGrowable() const +{ + return (m_Flags & EXTERNAL_GROWABLE) != 0; +} + + +inline bool CUtlBuffer::IsValid() const +{ + return m_Error == 0; +} + + +inline bool CUtlBuffer::ContainsCRLF() const +{ + return IsText() && ((m_Flags & CONTAINS_CRLF) != 0); +} + + +inline bool CUtlBuffer::IsReadOnly() const +{ + return (m_Flags & READ_ONLY) != 0; +} + + +inline const void* CUtlBuffer::Base() const +{ + return m_Memory.Base(); +} + +inline void* CUtlBuffer::Base() +{ + return m_Memory.Base(); +} + +inline int CUtlBuffer::Size() const +{ + return m_Memory.NumAllocated(); +} + + +inline void CUtlBuffer::Clear() +{ + m_Get = 0; + m_Put = 0; + m_Error = 0; + m_nOffset = 0; + m_nMaxPut = -1; + AddNullTermination(m_Put); +} + +inline void CUtlBuffer::Purge() +{ + m_Get = 0; + m_Put = 0; + m_nOffset = 0; + m_nMaxPut = 0; + m_Error = 0; + m_Memory.Purge(); +} + +inline void* CUtlBuffer::AccessForDirectRead(int nBytes) +{ + Assert(m_Get == 0 && m_Put == 0 && m_nMaxPut == 0); + EnsureCapacity(nBytes); + m_nMaxPut = nBytes; + return Base(); +} + +inline void* CUtlBuffer::Detach() +{ + void* p = m_Memory.Detach(); + Clear(); + return p; +} + +inline void CUtlBuffer::Spew() +{ + SeekGet(CUtlBuffer::SEEK_HEAD, 0); + + char pTmpLine[1024]; + while (IsValid() && GetBytesRemaining()) + { + V_memset(pTmpLine, 0, sizeof(pTmpLine)); + Get(pTmpLine, MIN((size_t)GetBytesRemaining(), sizeof(pTmpLine) - 1)); + Msg(_T("%s"), pTmpLine); + } +} + +#if !defined(_GAMECONSOLE) +inline void CUtlBuffer::SwapCopy(CUtlBuffer& other) +{ + m_Get = other.m_Get; + m_Put = other.m_Put; + m_Error = other.m_Error; + m_Flags = other.m_Flags; + m_Reserved = other.m_Reserved; + m_nTab = other.m_nTab; + m_nMaxPut = other.m_nMaxPut; + m_nOffset = other.m_nOffset; + m_GetOverflowFunc = other.m_GetOverflowFunc; + m_PutOverflowFunc = other.m_PutOverflowFunc; + m_Byteswap = other.m_Byteswap; + + m_Memory.Swap(other.m_Memory); +} +#endif + +inline void CUtlBuffer::CopyBuffer(const CUtlBuffer& buffer) +{ + CopyBuffer(buffer.Base(), buffer.TellPut()); +} + +inline void CUtlBuffer::CopyBuffer(const void* pubData, int cubData) +{ + Clear(); + if (cubData) + { + Put(pubData, cubData); + } +} + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/utldict.h b/SpyCustom/sdk/utldict.h new file mode 100644 index 0000000..ca636d3 --- /dev/null +++ b/SpyCustom/sdk/utldict.h @@ -0,0 +1,278 @@ +#ifndef UTLDICT_H +#define UTLDICT_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "dbg.h" +#include "utlmap.h" + +#include "utlsymbol.h" + +#include "memdbgon.h" + +enum EDictCompareType +{ + k_eDictCompareTypeCaseSensitive = 0, + k_eDictCompareTypeCaseInsensitive = 1, + k_eDictCompareTypeFilenames +}; + +#define FOR_EACH_DICT( dictName, iteratorName ) \ + for( int iteratorName=dictName.First(); iteratorName != dictName.InvalidIndex(); iteratorName = dictName.Next( iteratorName ) ) + +#define FOR_EACH_DICT_FAST( dictName, iteratorName ) \ + for ( int iteratorName = 0; iteratorName < dictName.MaxElement(); ++iteratorName ) if ( !dictName.IsValidIndex( iteratorName ) ) continue; else + +template +class CUtlDict +{ +public: + typedef const char* KeyType_t; + typedef T ElemType_t; + + CUtlDict(int compareType = k_eDictCompareTypeCaseInsensitive, int growSize = 0, int initSize = 0); + ~CUtlDict(); + + void EnsureCapacity(int); + + T& Element(I i); + const T& Element(I i) const; + T& operator[](I i); + const T& operator[](I i) const; + + char const* GetElementName(I i) const; + + void SetElementName(I i, char const* pName); + + unsigned int Count() const; + + I MaxElement() const; + + bool IsValidIndex(I i) const; + + static I InvalidIndex(); + + I Insert(const char* pName, const T& element); + I Insert(const char* pName); + + I Find(const char* pName) const; + bool HasElement(const char* pName) const; + + void RemoveAt(I i); + void Remove(const char* pName); + void RemoveAll(); + + void Purge(); + void PurgeAndDeleteElements(); + + I First() const; + I Next(I i) const; + + typedef I IndexType_t; + +protected: + typedef CUtlMap DictElementMap_t; + DictElementMap_t m_Elements; +}; + + +template +CUtlDict::CUtlDict(int compareType, int growSize, int initSize) : m_Elements(growSize, initSize) +{ + if (compareType == k_eDictCompareTypeFilenames) + { + m_Elements.SetLessFunc(CaselessStringLessThanIgnoreSlashes); + } + else if (compareType == k_eDictCompareTypeCaseInsensitive) + { + m_Elements.SetLessFunc(CaselessStringLessThan); + } + else + { + m_Elements.SetLessFunc(StringLessThan); + } +} + +template +CUtlDict::~CUtlDict() +{ + Purge(); +} + +template +inline void CUtlDict::EnsureCapacity(int num) +{ + return m_Elements.EnsureCapacity(num); +} + +template +inline T& CUtlDict::Element(I i) +{ + return m_Elements[i]; +} + +template +inline const T& CUtlDict::Element(I i) const +{ + return m_Elements[i]; +} + +template +inline char const* CUtlDict::GetElementName(I i) const +{ + return m_Elements.Key(i); +} + +template +inline T& CUtlDict::operator[](I i) +{ + return Element(i); +} + +template +inline const T& CUtlDict::operator[](I i) const +{ + return Element(i); +} + +template +inline void CUtlDict::SetElementName(I i, char const* pName) +{ + MEM_ALLOC_CREDIT_CLASS(); + free(const_cast(m_Elements.Key(i))); + m_Elements.Reinsert(strdup(pName), i); +} + +template +inline unsigned int CUtlDict::Count() const +{ + return m_Elements.Count(); +} + +template +inline I CUtlDict::MaxElement() const +{ + return m_Elements.MaxElement(); +} + +template +inline bool CUtlDict::IsValidIndex(I i) const +{ + return m_Elements.IsValidIndex(i); +} + + +template +inline I CUtlDict::InvalidIndex() +{ + return DictElementMap_t::InvalidIndex(); +} + + +template +void CUtlDict::RemoveAt(I elem) +{ + free(const_cast(m_Elements.Key(elem))); + m_Elements.RemoveAt(elem); +} + + +template void CUtlDict::Remove(const char* search) +{ + I node = Find(search); + if (node != InvalidIndex()) + { + RemoveAt(node); + } +} + + +template +void CUtlDict::RemoveAll() +{ + typename DictElementMap_t::IndexType_t index = m_Elements.FirstInorder(); + while (index != m_Elements.InvalidIndex()) + { + const char* p = m_Elements.Key(index); + free(const_cast(p)); + index = m_Elements.NextInorder(index); + } + + m_Elements.RemoveAll(); +} + +template +void CUtlDict::Purge() +{ + RemoveAll(); +} + + +template +void CUtlDict::PurgeAndDeleteElements() +{ + I index = m_Elements.FirstInorder(); + while (index != m_Elements.InvalidIndex()) + { + const char* p = m_Elements.Key(index); + free(const_cast(p)); + delete m_Elements[index]; + index = m_Elements.NextInorder(index); + } + + m_Elements.RemoveAll(); +} + + +template +I CUtlDict::Insert(const char* pName, const T& element) +{ + MEM_ALLOC_CREDIT_CLASS(); + return m_Elements.Insert(strdup(pName), element); +} + +template +I CUtlDict::Insert(const char* pName) +{ + MEM_ALLOC_CREDIT_CLASS(); + return m_Elements.Insert(strdup(pName)); +} + + +template +I CUtlDict::Find(const char* pName) const +{ + MEM_ALLOC_CREDIT_CLASS(); + if (pName) + return m_Elements.Find(pName); + else + return InvalidIndex(); +} + +template +bool CUtlDict::HasElement(const char* pName) const +{ + if (pName) + return m_Elements.IsValidIndex(m_Elements.Find(pName)); + else + return false; +} + + +template +I CUtlDict::First() const +{ + return m_Elements.FirstInorder(); +} + +template +I CUtlDict::Next(I i) const +{ + return m_Elements.NextInorder(i); +} + +#include "memdbgoff.h" + +#endif diff --git a/SpyCustom/sdk/utlenvelope.h b/SpyCustom/sdk/utlenvelope.h new file mode 100644 index 0000000..a9e08e7 --- /dev/null +++ b/SpyCustom/sdk/utlenvelope.h @@ -0,0 +1,221 @@ +#include "utlstring.h" +#include "basetypes.h" + +#ifndef UTLENVELOPE_H +#define UTLENVELOPE_H + +#if defined( _WIN32 ) +#pragma once +#endif + +class CUtlDataEnvelope +{ +public: + CUtlDataEnvelope(const void* pData, int nBytes); + CUtlDataEnvelope(const CUtlDataEnvelope& from); + ~CUtlDataEnvelope(); + + CUtlDataEnvelope& operator=(const CUtlDataEnvelope& from); + + operator void* (); + operator void* () const; + +private: + void Assign(const void* pData, int nBytes); + void Assign(const CUtlDataEnvelope& from); + void Purge(); + + union + { + byte* m_pData; + byte m_data[4]; + }; + int m_nBytes; +}; + + +template +class CUtlEnvelope : protected CUtlDataEnvelope +{ +public: + CUtlEnvelope(const T* pData, int nElems = 1); + CUtlEnvelope(const CUtlEnvelope& from); + + CUtlEnvelope& operator=(const CUtlEnvelope& from); + + operator T* (); + operator T* () const; + + operator void* (); + operator void* () const; +}; + +template <> +class CUtlEnvelope +{ +public: + CUtlEnvelope(const char* pData) + { + m_string = pData; + } + + CUtlEnvelope(const CUtlEnvelope& from) + { + m_string = from.m_string; + } + + CUtlEnvelope& operator=(const CUtlEnvelope& from) + { + m_string = from.m_string; + return *this; + } + + operator char* () + { + return (char*)m_string.Get(); + } + + operator char* () const + { + return (char*)m_string.Get(); + } + + operator void* () + { + return (void*)m_string.Get(); + } + + operator void* () const + { + return (void*)m_string.Get(); + } + +private: + CUtlString m_string; +}; + +#include "memdbgon.h" + +inline void CUtlDataEnvelope::Assign(const void* pData, int nBytes) +{ + if (pData) + { + m_nBytes = nBytes; + if (m_nBytes > 4) + { + m_pData = new byte[nBytes]; + memcpy(m_pData, pData, nBytes); + } + else + { + memcpy(m_data, pData, nBytes); + } + } + else + { + m_pData = NULL; + m_nBytes = 0; + } +} + +inline void CUtlDataEnvelope::Assign(const CUtlDataEnvelope& from) +{ + Assign(from.operator void* (), from.m_nBytes); +} + +inline void CUtlDataEnvelope::Purge() +{ + if (m_nBytes > 4) + delete[] m_pData; + m_nBytes = 0; +} + +inline CUtlDataEnvelope::CUtlDataEnvelope(const void* pData, int nBytes) +{ + Assign(pData, nBytes); +} + +inline CUtlDataEnvelope::CUtlDataEnvelope(const CUtlDataEnvelope& from) +{ + Assign(from); +} + +inline CUtlDataEnvelope::~CUtlDataEnvelope() +{ + Purge(); +} + +inline CUtlDataEnvelope& CUtlDataEnvelope::operator=(const CUtlDataEnvelope& from) +{ + Purge(); + Assign(from); + return *this; +} + +inline CUtlDataEnvelope::operator void* () +{ + if (!m_nBytes) + { + return NULL; + } + + return (m_nBytes > 4) ? m_pData : m_data; +} + +inline CUtlDataEnvelope::operator void* () const +{ + if (!m_nBytes) + { + return NULL; + } + + return (m_nBytes > 4) ? (void*)m_pData : (void*)m_data; +} + +template +inline CUtlEnvelope::CUtlEnvelope(const T* pData, int nElems) + : CUtlDataEnvelope(pData, sizeof(T)* nElems) +{ +} + +template +inline CUtlEnvelope::CUtlEnvelope(const CUtlEnvelope& from) + : CUtlDataEnvelope(from) +{ + +} + +template +inline CUtlEnvelope& CUtlEnvelope::operator=(const CUtlEnvelope& from) +{ + CUtlDataEnvelope::operator=(from); + return *this; +} + +template +inline CUtlEnvelope::operator T* () +{ + return (T*)CUtlDataEnvelope::operator void* (); +} + +template +inline CUtlEnvelope::operator T* () const +{ + return (T*)((const_cast*>(this))->operator T * ()); +} + +template +inline CUtlEnvelope::operator void* () +{ + return CUtlDataEnvelope::operator void* (); +} + +template +inline CUtlEnvelope::operator void* () const +{ + return ((const_cast*>(this))->operator void* ()); +} + +#include "memdbgoff.h" + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/utlfixedmemory.h b/SpyCustom/sdk/utlfixedmemory.h new file mode 100644 index 0000000..ab71e8a --- /dev/null +++ b/SpyCustom/sdk/utlfixedmemory.h @@ -0,0 +1,302 @@ +#ifndef UTLFIXEDMEMORY_H +#define UTLFIXEDMEMORY_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "dbg.h" +#include "platform.h" + +#include "memalloc.h" +#include "memdbgon.h" + +#pragma warning (disable:4100) +#pragma warning (disable:4514) + +#ifdef UTLFIXEDMEMORY_TRACK +#define UTLFIXEDMEMORY_TRACK_ALLOC() MemAlloc_RegisterAllocation( "Sum of all UtlFixedMemory", 0, NumAllocated() * sizeof(T), NumAllocated() * sizeof(T), 0 ) +#define UTLFIXEDMEMORY_TRACK_FREE() if ( !m_pMemory ) ; else MemAlloc_RegisterDeallocation( "Sum of all UtlFixedMemory", 0, NumAllocated() * sizeof(T), NumAllocated() * sizeof(T), 0 ) +#else +#define UTLFIXEDMEMORY_TRACK_ALLOC() ((void)0) +#define UTLFIXEDMEMORY_TRACK_FREE() ((void)0) +#endif + + +template< class T > +class CUtlFixedMemory +{ +public: + CUtlFixedMemory(int nGrowSize = 0, int nInitSize = 0); + ~CUtlFixedMemory(); + + void Init(int nGrowSize = 0, int nInitSize = 0); + + T* Base() { return NULL; } + const T* Base() const { return NULL; } + +protected: + struct BlockHeader_t; + +public: + class Iterator_t + { + public: + Iterator_t(BlockHeader_t* p, int i) : m_pBlockHeader(p), m_nIndex(i) {} + BlockHeader_t* m_pBlockHeader; + intp m_nIndex; + + bool operator==(const Iterator_t it) const { return m_pBlockHeader == it.m_pBlockHeader && m_nIndex == it.m_nIndex; } + bool operator!=(const Iterator_t it) const { return m_pBlockHeader != it.m_pBlockHeader || m_nIndex != it.m_nIndex; } + }; + Iterator_t First() const { return m_pBlocks ? Iterator_t(m_pBlocks, 0) : InvalidIterator(); } + Iterator_t Next(const Iterator_t& it) const + { + Assert(IsValidIterator(it)); + if (!IsValidIterator(it)) + return InvalidIterator(); + + BlockHeader_t* RESTRICT pHeader = it.m_pBlockHeader; + if (it.m_nIndex + 1 < pHeader->m_nBlockSize) + return Iterator_t(pHeader, it.m_nIndex + 1); + + return pHeader->m_pNext ? Iterator_t(pHeader->m_pNext, 0) : InvalidIterator(); + } + intp GetIndex(const Iterator_t& it) const + { + Assert(IsValidIterator(it)); + if (!IsValidIterator(it)) + return InvalidIndex(); + + return (intp)(HeaderToBlock(it.m_pBlockHeader) + it.m_nIndex); + } + bool IsIdxAfter(intp i, const Iterator_t& it) const + { + Assert(IsValidIterator(it)); + if (!IsValidIterator(it)) + return false; + + if (IsInBlock(i, it.m_pBlockHeader)) + return i > GetIndex(it); + + for (BlockHeader_t* RESTRICT pbh = it.m_pBlockHeader->m_pNext; pbh; pbh = pbh->m_pNext) + { + if (IsInBlock(i, pbh)) + return true; + } + return false; + } + bool IsValidIterator(const Iterator_t& it) const { return it.m_pBlockHeader && it.m_nIndex >= 0 && it.m_nIndex < it.m_pBlockHeader->m_nBlockSize; } + Iterator_t InvalidIterator() const { return Iterator_t(NULL, INVALID_INDEX); } + + T& operator[](intp i); + const T& operator[](intp i) const; + T& Element(intp i); + const T& Element(intp i) const; + + bool IsIdxValid(intp i) const; + + static const intp INVALID_INDEX = 0; + static intp InvalidIndex() { return INVALID_INDEX; } + + int NumAllocated() const; + int Count() const { return NumAllocated(); } + + void Grow(int num = 1); + + void EnsureCapacity(int num); + + void Purge(); + +protected: + void Swap(CUtlFixedMemory< T >& mem); + + bool IsInBlock(intp i, BlockHeader_t* pBlockHeader) const + { + T* p = (T*)i; + const T* p0 = HeaderToBlock(pBlockHeader); + return p >= p0 && p < p0 + pBlockHeader->m_nBlockSize; + } + + struct BlockHeader_t + { + BlockHeader_t* m_pNext; + intp m_nBlockSize; + }; + + const T* HeaderToBlock(const BlockHeader_t* pHeader) const { return (T*)(pHeader + 1); } + const BlockHeader_t* BlockToHeader(const T* pBlock) const { return (BlockHeader_t*)(pBlock)-1; } + + BlockHeader_t* m_pBlocks; + int m_nAllocationCount; + int m_nGrowSize; +}; + +template< class T > +CUtlFixedMemory::CUtlFixedMemory(int nGrowSize, int nInitAllocationCount) + : m_pBlocks(0), m_nAllocationCount(0), m_nGrowSize(0) +{ + Init(nGrowSize, nInitAllocationCount); +} + +template< class T > +CUtlFixedMemory::~CUtlFixedMemory() +{ + Purge(); +} + + +template< class T > +void CUtlFixedMemory::Swap(CUtlFixedMemory< T >& mem) +{ + V_swap(m_pBlocks, mem.m_pBlocks); + V_swap(m_nAllocationCount, mem.m_nAllocationCount); + V_swap(m_nGrowSize, mem.m_nGrowSize); +} + + +template< class T > +void CUtlFixedMemory::Init(int nGrowSize , int nInitSize ) +{ + Purge(); + + m_nGrowSize = nGrowSize; + + Grow(nInitSize); +} + +template< class T > +inline T& CUtlFixedMemory::operator[](intp i) +{ + Assert(IsIdxValid(i)); + return *(T*)i; +} + +template< class T > +inline const T& CUtlFixedMemory::operator[](intp i) const +{ + Assert(IsIdxValid(i)); + return *(T*)i; +} + +template< class T > +inline T& CUtlFixedMemory::Element(intp i) +{ + Assert(IsIdxValid(i)); + return *(T*)i; +} + +template< class T > +inline const T& CUtlFixedMemory::Element(intp i) const +{ + Assert(IsIdxValid(i)); + return *(T*)i; +} + + +template< class T > +inline int CUtlFixedMemory::NumAllocated() const +{ + return m_nAllocationCount; +} + + +template< class T > +inline bool CUtlFixedMemory::IsIdxValid(intp i) const +{ +#ifdef _DEBUG + for (BlockHeader_t* pbh = m_pBlocks; pbh; pbh = pbh->m_pNext) + { + if (IsInBlock(i, pbh)) + return true; + } + return false; +#else + return i != InvalidIndex(); +#endif +} + +template< class T > +void CUtlFixedMemory::Grow(int num) +{ + if (num <= 0) + return; + + int nBlockSize = m_nGrowSize; + if (nBlockSize == 0) + { + if (m_nAllocationCount) + { + nBlockSize = m_nAllocationCount; + } + else + { + nBlockSize = (31 + sizeof(T)) / sizeof(T); + Assert(nBlockSize); + } + } + if (nBlockSize < num) + { + int n = (num + nBlockSize - 1) / nBlockSize; + Assert(n * nBlockSize >= num); + Assert((n - 1) * nBlockSize < num); + nBlockSize *= n; + } + m_nAllocationCount += nBlockSize; + + MEM_ALLOC_CREDIT_CLASS(); + BlockHeader_t* RESTRICT pBlockHeader = (BlockHeader_t*)malloc(sizeof(BlockHeader_t) + nBlockSize * sizeof(T)); + if (!pBlockHeader) + { + Error("CUtlFixedMemory overflow!\n"); + } + pBlockHeader->m_pNext = NULL; + pBlockHeader->m_nBlockSize = nBlockSize; + + if (!m_pBlocks) + { + m_pBlocks = pBlockHeader; + } + else + { +#if 1 + BlockHeader_t* RESTRICT pbh = m_pBlocks; + while (pbh->m_pNext) + { + pbh = pbh->m_pNext; + } + pbh->m_pNext = pBlockHeader; +#else + pBlockHeader = m_pBlocks; + pBlockHeader->m_pNext = m_pBlocks; +#endif + } +} + + +template< class T > +inline void CUtlFixedMemory::EnsureCapacity(int num) +{ + Grow(num - NumAllocated()); +} + + +template< class T > +void CUtlFixedMemory::Purge() +{ + if (!m_pBlocks) + return; + + for (BlockHeader_t* pbh = m_pBlocks; pbh; ) + { + BlockHeader_t* pFree = pbh; + pbh = pbh->m_pNext; + free(pFree); + } + m_pBlocks = NULL; + m_nAllocationCount = 0; +} + +#include "memdbgoff.h" + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/utlflags.h b/SpyCustom/sdk/utlflags.h new file mode 100644 index 0000000..ac37ac9 --- /dev/null +++ b/SpyCustom/sdk/utlflags.h @@ -0,0 +1,92 @@ +#ifndef UTLFLAGS_H +#define UTLFLAGS_H +#ifdef _WIN32 +#pragma once +#endif + +#include "dbg.h" + + +template< class T > +class CUtlFlags +{ +public: + CUtlFlags(int nInitialFlags = 0); + + void SetFlag(int nFlagMask); + void SetFlag(int nFlagMask, bool bEnable); + + void ClearFlag(int nFlagMask); + void ClearAllFlags(); + bool IsFlagSet(int nFlagMask) const; + + bool IsAnyFlagSet() const; + +private: + T m_nFlags; +}; + + +template< class T > +CUtlFlags::CUtlFlags(int nInitialFlags) +{ + Assert(nInitialFlags == (T)nInitialFlags); + + m_nFlags = (T)nInitialFlags; +} + + +template< class T > +void CUtlFlags::SetFlag(int nFlagMask) +{ + Assert(nFlagMask == (T)nFlagMask); + + m_nFlags |= (T)nFlagMask; +} + +template< class T > +void CUtlFlags::SetFlag(int nFlagMask, bool bEnable) +{ + Assert(nFlagMask == (T)nFlagMask); + + if (bEnable) + { + m_nFlags |= (T)nFlagMask; + } + else + { + m_nFlags &= ~((T)nFlagMask); + } +} + + +template< class T > +void CUtlFlags::ClearFlag(int nFlagMask) +{ + Assert(nFlagMask == (T)nFlagMask); + m_nFlags &= ~((T)nFlagMask); +} + +template< class T > +void CUtlFlags::ClearAllFlags() +{ + m_nFlags = 0; +} + + +template< class T > +bool CUtlFlags::IsFlagSet(int nFlagMask) const +{ + Assert(nFlagMask == (T)nFlagMask); + return (m_nFlags & nFlagMask) != 0; +} + + +template< class T > +bool CUtlFlags::IsAnyFlagSet() const +{ + return m_nFlags != 0; +} + + +#endif \ No newline at end of file diff --git a/SpyCustom/sdk/utlhandletable.h b/SpyCustom/sdk/utlhandletable.h new file mode 100644 index 0000000..d3b4836 --- /dev/null +++ b/SpyCustom/sdk/utlhandletable.h @@ -0,0 +1,499 @@ +#ifndef UTLHANDLETABLE_H +#define UTLHANDLETABLE_H + +#ifdef _WIN32 +#pragma once +#endif + + +#include "utlvector.h" +#include "utlqueue.h" + + +typedef unsigned int UtlHandle_t; +#define UTLHANDLE_INVALID ((UtlHandle_t)~0) + + +template< class T, int HandleBits > +class CUtlHandleTable +{ +public: + CUtlHandleTable(); + + UtlHandle_t AddHandle(); + void RemoveHandle(UtlHandle_t h); + + void SetHandle(UtlHandle_t h, T* pData); + T* GetHandle(UtlHandle_t h) const; + T* GetHandle(UtlHandle_t h, bool checkValidity) const; + + bool IsHandleValid(UtlHandle_t h) const; + + unsigned int GetValidHandleCount() const; + unsigned int GetHandleCount() const; + UtlHandle_t GetHandleFromIndex(int i) const; + int GetIndexFromHandle(UtlHandle_t h) const; + + void MarkHandleInvalid(UtlHandle_t h); + void MarkHandleValid(UtlHandle_t h); + +private: + struct HandleType_t + { + HandleType_t(unsigned int i, unsigned int s) : nIndex(i), nSerial(s) + { + Assert(i < (1 << HandleBits)); + Assert(s < (1 << (31 - HandleBits))); + } + unsigned int nIndex : HandleBits; + unsigned int nSerial : 31 - HandleBits; + }; + + struct EntryType_t + { + EntryType_t() : m_nSerial(0), nInvalid(0), m_pData(0) {} + unsigned int m_nSerial : 31; + unsigned int nInvalid : 1; + T* m_pData; + }; + + static unsigned int GetSerialNumber(UtlHandle_t handle); + static unsigned int GetListIndex(UtlHandle_t handle); + static UtlHandle_t CreateHandle(unsigned int nSerial, unsigned int nIndex); + const EntryType_t* GetEntry(UtlHandle_t handle, bool checkValidity) const; + + unsigned int m_nValidHandles; + CUtlVector< EntryType_t > m_list; + CUtlQueue< int > m_unused; +}; + + +template< class T, int HandleBits > +CUtlHandleTable::CUtlHandleTable() : m_nValidHandles(0) +{ +} + + +template< class T, int HandleBits > +UtlHandle_t CUtlHandleTable::AddHandle() +{ + unsigned int nIndex = (m_unused.Count() > 0) ? m_unused.RemoveAtHead() : m_list.AddToTail(); + + EntryType_t& entry = m_list[nIndex]; + entry.nInvalid = 0; + entry.m_pData = NULL; + + ++m_nValidHandles; + + return CreateHandle(entry.m_nSerial, nIndex); +} + +template< class T, int HandleBits > +void CUtlHandleTable::RemoveHandle(UtlHandle_t handle) +{ + unsigned int nIndex = GetListIndex(handle); + Assert(nIndex < (unsigned int)m_list.Count()); + if (nIndex >= (unsigned int)m_list.Count()) + return; + + EntryType_t& entry = m_list[nIndex]; + ++entry.m_nSerial; + if (!entry.nInvalid) + { + entry.nInvalid = 1; + --m_nValidHandles; + } + entry.m_pData = NULL; + + + bool bStopUsing = (entry.m_nSerial >= ((1 << (31 - HandleBits)) - 1)); + if (!bStopUsing) + { + m_unused.Insert(nIndex); + } +} + + +template< class T, int HandleBits > +void CUtlHandleTable::SetHandle(UtlHandle_t handle, T* pData) +{ + EntryType_t* entry = const_cast(GetEntry(handle, false)); + Assert(entry); + if (entry == NULL) + return; + + if (entry->nInvalid) + { + ++m_nValidHandles; + entry->nInvalid = 0; + } + entry->m_pData = pData; +} + +template< class T, int HandleBits > +T* CUtlHandleTable::GetHandle(UtlHandle_t handle) const +{ + const EntryType_t* entry = GetEntry(handle, true); + return entry ? entry->m_pData : NULL; +} + +template< class T, int HandleBits > +T* CUtlHandleTable::GetHandle(UtlHandle_t handle, bool checkValidity) const +{ + const EntryType_t* entry = GetEntry(handle, checkValidity); + return entry ? entry->m_pData : NULL; +} + + +template< class T, int HandleBits > +bool CUtlHandleTable::IsHandleValid(UtlHandle_t handle) const +{ + if (handle == UTLHANDLE_INVALID) + return false; + + unsigned int nIndex = GetListIndex(handle); + AssertOnce(nIndex < (unsigned int)m_list.Count()); + if (nIndex >= (unsigned int)m_list.Count()) + return false; + + const EntryType_t& entry = m_list[nIndex]; + if (entry.m_nSerial != GetSerialNumber(handle)) + return false; + + if (1 == entry.nInvalid) + return false; + + return true; +} + + +template< class T, int HandleBits > +unsigned int CUtlHandleTable::GetValidHandleCount() const +{ + return m_nValidHandles; +} + +template< class T, int HandleBits > +unsigned int CUtlHandleTable::GetHandleCount() const +{ + return m_list.Count(); +} + +template< class T, int HandleBits > +UtlHandle_t CUtlHandleTable::GetHandleFromIndex(int i) const +{ + if (m_list[i].m_pData) + return CreateHandle(m_list[i].m_nSerial, i); + return UTLHANDLE_INVALID; +} + +template< class T, int HandleBits > +int CUtlHandleTable::GetIndexFromHandle(UtlHandle_t h) const +{ + if (h == UTLHANDLE_INVALID) + return -1; + + return GetListIndex(h); +} + + + +template< class T, int HandleBits > +unsigned int CUtlHandleTable::GetSerialNumber(UtlHandle_t handle) +{ + return ((HandleType_t*)&handle)->nSerial; +} + +template< class T, int HandleBits > +unsigned int CUtlHandleTable::GetListIndex(UtlHandle_t handle) +{ + return ((HandleType_t*)&handle)->nIndex; +} + +template< class T, int HandleBits > +UtlHandle_t CUtlHandleTable::CreateHandle(unsigned int nSerial, unsigned int nIndex) +{ + HandleType_t h(nIndex, nSerial); + return *(UtlHandle_t*)&h; +} + + +template< class T, int HandleBits > +const typename CUtlHandleTable::EntryType_t* CUtlHandleTable::GetEntry(UtlHandle_t handle, bool checkValidity) const +{ + if (handle == UTLHANDLE_INVALID) + return NULL; + + unsigned int nIndex = GetListIndex(handle); + Assert(nIndex < (unsigned int)m_list.Count()); + if (nIndex >= (unsigned int)m_list.Count()) + return NULL; + + const EntryType_t& entry = m_list[nIndex]; + if (entry.m_nSerial != GetSerialNumber(handle)) + return NULL; + + if (checkValidity && + (1 == entry.nInvalid)) + return NULL; + + return &entry; +} + +template< class T, int HandleBits > +void CUtlHandleTable::MarkHandleInvalid(UtlHandle_t handle) +{ + if (handle == UTLHANDLE_INVALID) + return; + + unsigned int nIndex = GetListIndex(handle); + Assert(nIndex < (unsigned int)m_list.Count()); + if (nIndex >= (unsigned int)m_list.Count()) + return; + + EntryType_t& entry = m_list[nIndex]; + if (entry.m_nSerial != GetSerialNumber(handle)) + return; + + if (!entry.nInvalid) + { + --m_nValidHandles; + entry.nInvalid = 1; + } +} + +template< class T, int HandleBits > +void CUtlHandleTable::MarkHandleValid(UtlHandle_t handle) +{ + if (handle == UTLHANDLE_INVALID) + return; + + unsigned int nIndex = GetListIndex(handle); + Assert(nIndex < (unsigned int)m_list.Count()); + if (nIndex >= (unsigned int)m_list.Count()) + return; + + EntryType_t& entry = m_list[nIndex]; + if (entry.m_nSerial != GetSerialNumber(handle)) + return; + + if (entry.nInvalid) + { + ++m_nValidHandles; + entry.nInvalid = 0; + } +} + + +template< class T > +class CUtlHandle +{ +public: + CUtlHandle(); + explicit CUtlHandle(T* pObject); + CUtlHandle(UtlHandle_t h); + CUtlHandle(const CUtlHandle& h); + + void Set(T* pObject); + void Set(UtlHandle_t h); + const CUtlHandle& operator=(UtlHandle_t h); + const CUtlHandle& operator=(T* pObject); + + T* Get(); + const T* Get() const; + + bool IsValid() const; + + operator T* (); + operator UtlHandle_t(); + operator bool(); + T* operator->(); + const T* operator->() const; + + bool operator==(CUtlHandle h) const; + bool operator==(T* pObject) const; + bool operator==(UtlHandle_t h) const; + bool operator!=(CUtlHandle h) const; + bool operator!=(T* pObject) const; + bool operator!=(UtlHandle_t h) const; + +private: + UtlHandle_t m_handle; +}; + + +template< class T > +CUtlHandle::CUtlHandle() : m_handle(UTLHANDLE_INVALID) +{ +} + +template< class T > +CUtlHandle::CUtlHandle(T* pObject) +{ + Set(pObject); +} + +template< class T > +CUtlHandle::CUtlHandle(UtlHandle_t h) +{ + m_handle = h; +} + +template< class T > +CUtlHandle::CUtlHandle(const CUtlHandle& h) +{ + m_handle = h.m_handle; +} + + +template< class T > +void CUtlHandle::Set(T* pObject) +{ + m_handle = pObject ? pObject->GetHandle() : UTLHANDLE_INVALID; +} + +template< class T > +void CUtlHandle::Set(UtlHandle_t h) +{ + m_handle = h; +} + +template< class T > +const CUtlHandle& CUtlHandle::operator=(UtlHandle_t h) +{ + Set(h); + return *this; +} + +template< class T > +const CUtlHandle& CUtlHandle::operator=(T* pObject) +{ + Set(pObject); + return *this; +} + + +template< class T > +bool CUtlHandle::IsValid() const +{ + return T::IsHandleValid(m_handle); +} + + +template< class T > +T* CUtlHandle::Get() +{ + return T::GetPtrFromHandle(m_handle); +} + +template< class T > +const T* CUtlHandle::Get() const +{ + return T::GetPtrFromHandle(m_handle); +} + + +template< class T > +CUtlHandle::operator T* () +{ + return Get(); +} + +template< class T > +CUtlHandle::operator UtlHandle_t() +{ + return m_handle; +} + +template< class T > +T* CUtlHandle::operator->() +{ + return Get(); +} + +template< class T > +const T* CUtlHandle::operator->() const +{ + return Get(); +} + +template< class T > +CUtlHandle::operator bool() +{ + return m_handle != UTLHANDLE_INVALID; +} + + +template< class T > +bool CUtlHandle::operator==(CUtlHandle h) const +{ + return m_handle == h.m_handle; +} + +template< class T > +bool CUtlHandle::operator==(T* pObject) const +{ + UtlHandle_t h = pObject ? pObject->GetHandle() : UTLHANDLE_INVALID; + return m_handle == h; +} + +template< class T > +bool CUtlHandle::operator==(UtlHandle_t h) const +{ + return m_handle == h; +} + +template< class T > +bool CUtlHandle::operator!=(CUtlHandle h) const +{ + return m_handle != h.m_handle; +} + +template< class T > +bool CUtlHandle::operator!=(T* pObject) const +{ + UtlHandle_t h = pObject ? pObject->GetHandle() : UTLHANDLE_INVALID; + return m_handle != h; +} + +template< class T > +bool CUtlHandle::operator!=(UtlHandle_t h) const +{ + return m_handle != h; +} + + +#define DECLARE_HANDLES( _className, _handleBitCount ) \ + public: \ + UtlHandle_t GetHandle() \ + { \ + return m_Handle; \ + } \ + static _className* GetPtrFromHandle( UtlHandle_t h ) \ + { \ + return m_HandleTable.GetHandle( h ); \ + } \ + static bool IsHandleValid( UtlHandle_t h ) \ + { \ + return m_HandleTable.IsHandleValid( h ); \ + } \ + private: \ + UtlHandle_t m_Handle; \ + static CUtlHandleTable< _className, _handleBitCount > m_HandleTable + + +#define IMPLEMENT_HANDLES( _className, _handleBitCount ) \ + CUtlHandleTable< _className, _handleBitCount > _className::m_HandleTable; + + +#define CONSTRUCT_HANDLE( ) \ + m_Handle = m_HandleTable.AddHandle(); \ + m_HandleTable.SetHandle( m_Handle, this ) + +#define DESTRUCT_HANDLE() \ + m_HandleTable.RemoveHandle( m_Handle ); \ + m_Handle = UTLHANDLE_INVALID + + + +#endif diff --git a/SpyCustom/sdk/utlhash.h b/SpyCustom/sdk/utlhash.h new file mode 100644 index 0000000..5b20034 --- /dev/null +++ b/SpyCustom/sdk/utlhash.h @@ -0,0 +1,732 @@ +#ifndef UTLHASH_H +#define UTLHASH_H +#pragma once + +#include +#include +#include "utlmemory.h" +#include "utlvector.h" +#include "utllinkedlist.h" +#include "commonmacros.h" +#include "generichash.h" + +typedef unsigned int UtlHashHandle_t; + +template +class CUtlHash +{ +public: + typedef C CompareFunc_t; + typedef K KeyFunc_t; + + CUtlHash(int bucketCount = 0, int growCount = 0, int initCount = 0, + CompareFunc_t compareFunc = 0, KeyFunc_t keyFunc = 0); + ~CUtlHash(); + + static UtlHashHandle_t InvalidHandle(void) { return (UtlHashHandle_t)~0; } + bool IsValidHandle(UtlHashHandle_t handle) const; + + int Count(void) const; + + void Purge(void); + + UtlHashHandle_t Insert(Data const& src); + UtlHashHandle_t Insert(Data const& src, bool* pDidInsert); + UtlHashHandle_t AllocEntryFromKey(Data const& src); + + void Remove(UtlHashHandle_t handle); + void RemoveAll(); + + UtlHashHandle_t Find(Data const& src) const; + + Data& Element(UtlHashHandle_t handle); + Data const& Element(UtlHashHandle_t handle) const; + Data& operator[](UtlHashHandle_t handle); + Data const& operator[](UtlHashHandle_t handle) const; + + UtlHashHandle_t GetFirstHandle() const; + UtlHashHandle_t GetNextHandle(UtlHashHandle_t h) const; + + void Log(const char* filename); + +protected: + + int GetBucketIndex(UtlHashHandle_t handle) const; + int GetKeyDataIndex(UtlHashHandle_t handle) const; + UtlHashHandle_t BuildHandle(int ndxBucket, int ndxKeyData) const; + + bool DoFind(Data const& src, unsigned int* pBucket, int* pIndex) const; + +protected: + + typedef CUtlVector HashBucketList_t; + CUtlVector m_Buckets; + + CompareFunc_t m_CompareFunc; + KeyFunc_t m_KeyFunc; + + bool m_bPowerOfTwo; + unsigned int m_ModMask; +}; + + +template +CUtlHash::CUtlHash(int bucketCount, int growCount, int initCount, + CompareFunc_t compareFunc, KeyFunc_t keyFunc) : + m_CompareFunc(compareFunc), + m_KeyFunc(keyFunc) +{ + m_Buckets.SetSize(bucketCount); + for (int ndxBucket = 0; ndxBucket < bucketCount; ndxBucket++) + { + m_Buckets[ndxBucket].SetSize(initCount); + m_Buckets[ndxBucket].SetGrowSize(growCount); + } + + m_bPowerOfTwo = IsPowerOfTwo(bucketCount); + m_ModMask = m_bPowerOfTwo ? (bucketCount - 1) : 0; +} + + +template +CUtlHash::~CUtlHash() +{ + Purge(); +} + + +template +inline bool CUtlHash::IsValidHandle(UtlHashHandle_t handle) const +{ + int ndxBucket = GetBucketIndex(handle); + int ndxKeyData = GetKeyDataIndex(handle); + + if ( (ndxBucket < m_Buckets.Count())) + { + if ( (ndxKeyData < m_Buckets[ndxBucket].Count())) + return true; + } + + return false; +} + +template +inline int CUtlHash::Count(void) const +{ + int count = 0; + + int bucketCount = m_Buckets.Count(); + for (int ndxBucket = 0; ndxBucket < bucketCount; ndxBucket++) + { + count += m_Buckets[ndxBucket].Count(); + } + + return count; +} + + +template +inline int CUtlHash::GetBucketIndex(UtlHashHandle_t handle) const +{ + return (((handle >> 16) & 0x0000ffff)); +} + + +template +inline int CUtlHash::GetKeyDataIndex(UtlHashHandle_t handle) const +{ + return (handle & 0x0000ffff); +} + + +template +inline UtlHashHandle_t CUtlHash::BuildHandle(int ndxBucket, int ndxKeyData) const +{ + assert((ndxBucket >= 0) && (ndxBucket < 65536)); + assert((ndxKeyData >= 0) && (ndxKeyData < 65536)); + + UtlHashHandle_t handle = ndxKeyData; + handle |= (ndxBucket << 16); + + return handle; +} + + +template +inline void CUtlHash::Purge(void) +{ + int bucketCount = m_Buckets.Count(); + for (int ndxBucket = 0; ndxBucket < bucketCount; ndxBucket++) + { + m_Buckets[ndxBucket].Purge(); + } +} + +template +inline bool CUtlHash::DoFind(Data const& src, unsigned int* pBucket, int* pIndex) const +{ + unsigned int key = m_KeyFunc(src); + + unsigned int ndxBucket; + if (m_bPowerOfTwo) + { + *pBucket = ndxBucket = (key & m_ModMask); + } + else + { + int bucketCount = m_Buckets.Count(); + *pBucket = ndxBucket = key % bucketCount; + } + + int ndxKeyData; + const CUtlVector& bucket = m_Buckets[ndxBucket]; + int keyDataCount = bucket.Count(); + for (ndxKeyData = 0; ndxKeyData < keyDataCount; ndxKeyData++) + { + if (m_CompareFunc(bucket.Element(ndxKeyData), src)) + break; + } + + if (ndxKeyData == keyDataCount) + return false; + + *pIndex = ndxKeyData; + return true; +} + + +template +inline UtlHashHandle_t CUtlHash::Find(Data const& src) const +{ + unsigned int ndxBucket; + int ndxKeyData; + + if (DoFind(src, &ndxBucket, &ndxKeyData)) + { + return (BuildHandle(ndxBucket, ndxKeyData)); + } + return (InvalidHandle()); +} + + +template +inline UtlHashHandle_t CUtlHash::Insert(Data const& src) +{ + unsigned int ndxBucket; + int ndxKeyData; + + if (DoFind(src, &ndxBucket, &ndxKeyData)) + { + return (BuildHandle(ndxBucket, ndxKeyData)); + } + + ndxKeyData = m_Buckets[ndxBucket].AddToTail(src); + + return (BuildHandle(ndxBucket, ndxKeyData)); +} + +template +inline UtlHashHandle_t CUtlHash::Insert(Data const& src, bool* pDidInsert) +{ + unsigned int ndxBucket; + int ndxKeyData; + + if (DoFind(src, &ndxBucket, &ndxKeyData)) + { + *pDidInsert = false; + return (BuildHandle(ndxBucket, ndxKeyData)); + } + + *pDidInsert = true; + ndxKeyData = m_Buckets[ndxBucket].AddToTail(src); + + return (BuildHandle(ndxBucket, ndxKeyData)); +} + + +template +inline UtlHashHandle_t CUtlHash::AllocEntryFromKey(Data const& src) +{ + unsigned int ndxBucket; + int ndxKeyData; + + if (DoFind(src, &ndxBucket, &ndxKeyData)) + { + return (BuildHandle(ndxBucket, ndxKeyData)); + } + + ndxKeyData = m_Buckets[ndxBucket].AddToTail(); + + return (BuildHandle(ndxBucket, ndxKeyData)); +} + + +template +inline void CUtlHash::Remove(UtlHashHandle_t handle) +{ + assert(IsValidHandle(handle)); + + int ndxBucket = GetBucketIndex(handle); + int ndxKeyData = GetKeyDataIndex(handle); + + if (m_Buckets[ndxBucket].IsValidIndex(ndxKeyData)) + { + m_Buckets[ndxBucket].FastRemove(ndxKeyData); + } +} + + +template +inline void CUtlHash::RemoveAll() +{ + int bucketCount = m_Buckets.Count(); + for (int ndxBucket = 0; ndxBucket < bucketCount; ndxBucket++) + { + m_Buckets[ndxBucket].RemoveAll(); + } +} + + +template +inline Data& CUtlHash::Element(UtlHashHandle_t handle) +{ + int ndxBucket = GetBucketIndex(handle); + int ndxKeyData = GetKeyDataIndex(handle); + + return (m_Buckets[ndxBucket].Element(ndxKeyData)); +} + +template +inline Data const& CUtlHash::Element(UtlHashHandle_t handle) const +{ + int ndxBucket = GetBucketIndex(handle); + int ndxKeyData = GetKeyDataIndex(handle); + + return (m_Buckets[ndxBucket].Element(ndxKeyData)); +} + + +template +inline Data& CUtlHash::operator[](UtlHashHandle_t handle) +{ + int ndxBucket = GetBucketIndex(handle); + int ndxKeyData = GetKeyDataIndex(handle); + + return (m_Buckets[ndxBucket].Element(ndxKeyData)); +} + + +template +inline Data const& CUtlHash::operator[](UtlHashHandle_t handle) const +{ + int ndxBucket = GetBucketIndex(handle); + int ndxKeyData = GetKeyDataIndex(handle); + + return (m_Buckets[ndxBucket].Element(ndxKeyData)); +} + +template +inline UtlHashHandle_t CUtlHash::GetFirstHandle() const +{ + return GetNextHandle((UtlHashHandle_t)-1); +} + +template +inline UtlHashHandle_t CUtlHash::GetNextHandle(UtlHashHandle_t handle) const +{ + ++handle; + + int bi = GetBucketIndex(handle); + int ki = GetKeyDataIndex(handle); + + int nBuckets = m_Buckets.Count(); + for (; bi < nBuckets; ++bi) + { + if (ki < m_Buckets[bi].Count()) + return BuildHandle(bi, ki); + + ki = 0; + } + + return InvalidHandle(); +} + +template +inline void CUtlHash::Log(const char* filename) +{ + FILE* pDebugFp; + pDebugFp = fopen(filename, "w"); + if (!pDebugFp) + return; + + int maxBucketSize = 0; + int numBucketsEmpty = 0; + + int bucketCount = m_Buckets.Count(); + fprintf(pDebugFp, "\n%d Buckets\n", bucketCount); + + for (int ndxBucket = 0; ndxBucket < bucketCount; ndxBucket++) + { + int count = m_Buckets[ndxBucket].Count(); + + if (count > maxBucketSize) { maxBucketSize = count; } + if (count == 0) + numBucketsEmpty++; + + fprintf(pDebugFp, "Bucket %d: %d\n", ndxBucket, count); + } + + fprintf(pDebugFp, "\nBucketHeads Used: %d\n", bucketCount - numBucketsEmpty); + fprintf(pDebugFp, "Max Bucket Size: %d\n", maxBucketSize); + + fclose(pDebugFp); +} + +typedef int UtlHashFastHandle_t; + +#define UTLHASH_POOL_SCALAR 2 + +class CUtlHashFastNoHash +{ +public: + static int Hash(int key, int bucketMask) + { + return (key & bucketMask); + } +}; + +class CUtlHashFastGenericHash +{ +public: + static int Hash(int key, int bucketMask) + { + return (HashIntConventional(key) & bucketMask); + } +}; + +template +class CUtlHashFast +{ +public: + + CUtlHashFast(); + ~CUtlHashFast(); + + void Purge(void); + + static UtlHashFastHandle_t InvalidHandle(void) { return (UtlHashFastHandle_t)~0; } + + bool Init(int nBucketCount); + + int Count(void); + + UtlHashFastHandle_t Insert(unsigned int uiKey, const Data& data); + UtlHashFastHandle_t FastInsert(unsigned int uiKey, const Data& data); + + void Remove(UtlHashFastHandle_t hHash); + void RemoveAll(void); + + UtlHashFastHandle_t Find(unsigned int uiKey); + + Data& Element(UtlHashFastHandle_t hHash); + Data const& Element(UtlHashFastHandle_t hHash) const; + Data& operator[](UtlHashFastHandle_t hHash); + Data const& operator[](UtlHashFastHandle_t hHash) const; + + template + struct HashFastData_t_ + { + unsigned int m_uiKey; + HashData m_Data; + }; + + typedef HashFastData_t_ HashFastData_t; + + unsigned int m_uiBucketMask; + CUtlVector m_aBuckets; + CUtlFixedLinkedList m_aDataPool; +}; + +template CUtlHashFast::CUtlHashFast() +{ + Purge(); +} + +template CUtlHashFast::~CUtlHashFast() +{ + Purge(); +} + +template inline void CUtlHashFast::Purge(void) +{ + m_aBuckets.Purge(); + m_aDataPool.Purge(); +} + +template bool CUtlHashFast::Init(int nBucketCount) +{ + if (!IsPowerOfTwo(nBucketCount)) + return false; + + m_aBuckets.SetSize(nBucketCount); + for (int iBucket = 0; iBucket < nBucketCount; ++iBucket) + { + m_aBuckets[iBucket] = m_aDataPool.InvalidIndex(); + } + + m_uiBucketMask = nBucketCount - 1; + + int nGrowSize = UTLHASH_POOL_SCALAR * nBucketCount; + m_aDataPool.SetGrowSize(nGrowSize); + + return true; +} + +template inline int CUtlHashFast::Count(void) +{ + return m_aDataPool.Count(); +} + +template inline UtlHashFastHandle_t CUtlHashFast::Insert(unsigned int uiKey, const Data& data) +{ + UtlHashFastHandle_t hHash = Find(uiKey); + if (hHash != InvalidHandle()) + return hHash; + + return FastInsert(uiKey, data); +} + +template inline UtlHashFastHandle_t CUtlHashFast::FastInsert(unsigned int uiKey, const Data& data) +{ + int iHashData = m_aDataPool.Alloc(true); + HashFastData_t* pHashData = &m_aDataPool[iHashData]; + if (!pHashData) + return InvalidHandle(); + + pHashData->m_uiKey = uiKey; + pHashData->m_Data = data; + + int iBucket = HashFuncs::Hash(uiKey, m_uiBucketMask); + m_aDataPool.LinkBefore(m_aBuckets[iBucket], iHashData); + m_aBuckets[iBucket] = iHashData; + + return iHashData; +} + +template inline void CUtlHashFast::Remove(UtlHashFastHandle_t hHash) +{ + int iBucket = HashFuncs::Hash(m_aDataPool[hHash].m_uiKey, m_uiBucketMask); + if (m_aBuckets[iBucket] == hHash) + { + m_aBuckets[iBucket] = m_aDataPool.Next(hHash); + } + else + { + m_aDataPool.Unlink(hHash); + } + + m_aDataPool.Remove(hHash); +} + +template inline void CUtlHashFast::RemoveAll(void) +{ + m_aBuckets.RemoveAll(); + m_aDataPool.RemoveAll(); +} + +template inline UtlHashFastHandle_t CUtlHashFast::Find(unsigned int uiKey) +{ + int iBucket = HashFuncs::Hash(uiKey, m_uiBucketMask); + + for (int iElement = m_aBuckets[iBucket]; iElement != m_aDataPool.InvalidIndex(); iElement = m_aDataPool.Next(iElement)) + { + if (m_aDataPool[iElement].m_uiKey == uiKey) + return iElement; + } + + return InvalidHandle(); +} + +template inline Data& CUtlHashFast::Element(UtlHashFastHandle_t hHash) +{ + return (m_aDataPool[hHash].m_Data); +} + +template inline Data const& CUtlHashFast::Element(UtlHashFastHandle_t hHash) const +{ + return (m_aDataPool[hHash].m_Data); +} + +template inline Data& CUtlHashFast::operator[](UtlHashFastHandle_t hHash) +{ + return (m_aDataPool[hHash].m_Data); +} + +template inline Data const& CUtlHashFast::operator[](UtlHashFastHandle_t hHash) const +{ + return (m_aDataPool[hHash].m_Data); +} + +typedef int UtlHashFixedHandle_t; + +template +class CUtlHashFixedGenericHash +{ +public: + static int Hash(int key, int bucketMask) + { + int hash = HashIntConventional(key); + if (NUM_BUCKETS <= USHRT_MAX) + { + hash ^= (hash >> 16); + } + if (NUM_BUCKETS <= UCHAR_MAX) + { + hash ^= (hash >> 8); + } + return (hash & bucketMask); + } +}; + +template +class CUtlHashFixed +{ +public: + + CUtlHashFixed(); + ~CUtlHashFixed(); + + void Purge(void); + + static UtlHashFixedHandle_t InvalidHandle(void) { return (UtlHashFixedHandle_t)~0; } + + int Count(void); + + UtlHashFixedHandle_t Insert(unsigned int uiKey, const Data& data); + UtlHashFixedHandle_t FastInsert(unsigned int uiKey, const Data& data); + + void Remove(UtlHashFixedHandle_t hHash); + void RemoveAll(void); + + UtlHashFixedHandle_t Find(unsigned int uiKey); + + Data& Element(UtlHashFixedHandle_t hHash); + Data const& Element(UtlHashFixedHandle_t hHash) const; + Data& operator[](UtlHashFixedHandle_t hHash); + Data const& operator[](UtlHashFixedHandle_t hHash) const; + + template + struct HashFixedData_t_ + { + unsigned int m_uiKey; + Data_t m_Data; + }; + + typedef HashFixedData_t_ HashFixedData_t; + + enum + { + BUCKET_MASK = NUM_BUCKETS - 1 + }; + CUtlPtrLinkedList m_aBuckets[NUM_BUCKETS]; + int m_nElements; +}; + +template CUtlHashFixed::CUtlHashFixed() +{ + Purge(); +} + +template CUtlHashFixed::~CUtlHashFixed() +{ + Purge(); +} + +template inline void CUtlHashFixed::Purge(void) +{ + RemoveAll(); +} + +template inline int CUtlHashFixed::Count(void) +{ + return m_nElements; +} + +template inline UtlHashFixedHandle_t CUtlHashFixed::Insert(unsigned int uiKey, const Data& data) +{ + UtlHashFixedHandle_t hHash = Find(uiKey); + if (hHash != InvalidHandle()) + return hHash; + + return FastInsert(uiKey, data); +} + +template inline UtlHashFixedHandle_t CUtlHashFixed::FastInsert(unsigned int uiKey, const Data& data) +{ + int iBucket = HashFuncs::Hash(uiKey, NUM_BUCKETS - 1); + UtlPtrLinkedListIndex_t iElem = m_aBuckets[iBucket].AddToHead(); + + HashFixedData_t* pHashData = &m_aBuckets[iBucket][iElem]; + + Assert((UtlPtrLinkedListIndex_t)pHashData == iElem); + + pHashData->m_uiKey = uiKey; + pHashData->m_Data = data; + + m_nElements++; + return (UtlHashFixedHandle_t)pHashData; +} + +template inline void CUtlHashFixed::Remove(UtlHashFixedHandle_t hHash) +{ + HashFixedData_t* pHashData = (HashFixedData_t*)hHash; + Assert(Find(pHashData->m_uiKey) != InvalidHandle()); + int iBucket = HashFuncs::Hash(pHashData->m_uiKey, NUM_BUCKETS - 1); + m_aBuckets[iBucket].Remove((UtlPtrLinkedListIndex_t)pHashData); + m_nElements--; +} + +template inline void CUtlHashFixed::RemoveAll(void) +{ + for (int i = 0; i < NUM_BUCKETS; i++) + { + m_aBuckets[i].RemoveAll(); + } + m_nElements = 0; +} + +template inline UtlHashFixedHandle_t CUtlHashFixed::Find(unsigned int uiKey) +{ + int iBucket = HashFuncs::Hash(uiKey, NUM_BUCKETS - 1); + CUtlPtrLinkedList& bucket = m_aBuckets[iBucket]; + + for (UtlPtrLinkedListIndex_t iElement = bucket.Head(); iElement != bucket.InvalidIndex(); iElement = bucket.Next(iElement)) + { + if (bucket[iElement].m_uiKey == uiKey) + return (UtlHashFixedHandle_t)iElement; + } + + return InvalidHandle(); +} + +template inline Data& CUtlHashFixed::Element(UtlHashFixedHandle_t hHash) +{ + return ((HashFixedData_t*)hHash)->m_Data; +} + +template inline Data const& CUtlHashFixed::Element(UtlHashFixedHandle_t hHash) const +{ + return ((HashFixedData_t*)hHash)->m_Data; +} + +template inline Data& CUtlHashFixed::operator[](UtlHashFixedHandle_t hHash) +{ + return ((HashFixedData_t*)hHash)->m_Data; +} + +template inline Data const& CUtlHashFixed::operator[](UtlHashFixedHandle_t hHash) const +{ + return ((HashFixedData_t*)hHash)->m_Data; +} + +#endif \ No newline at end of file